Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Piskarev2015-08-20 07:28:37 +0000
committerVladimir Piskarev2015-08-20 09:16:35 +0000
commit829d8e9255fb247a1e8bedadd25f89e945d2a6ed (patch)
tree3be7e59320da9de17719b4bcfd3c4ccbd0823324
parentb3121644da65fa1480a99f13814f9fbba80bb2fb (diff)
downloadorg.eclipse.handly-829d8e9255fb247a1e8bedadd25f89e945d2a6ed.tar.gz
org.eclipse.handly-829d8e9255fb247a1e8bedadd25f89e945d2a6ed.tar.xz
org.eclipse.handly-829d8e9255fb247a1e8bedadd25f89e945d2a6ed.zip
Bug 475446 - Overhaul handle's toString facility
-rw-r--r--org.eclipse.handly.examples.adapter/src/org/eclipse/handly/internal/examples/adapter/JavaHandle.java6
-rw-r--r--org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/examples/javamodel/ICompilationUnit.java2
-rw-r--r--org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/Field.java7
-rw-r--r--org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/ImportContainer.java7
-rw-r--r--org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/JavaModelManager.java2
-rw-r--r--org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/Method.java7
-rw-r--r--org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/PackageFragment.java16
-rw-r--r--org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/Type.java7
-rw-r--r--org.eclipse.handly/src/org/eclipse/handly/model/IHandle.java77
-rw-r--r--org.eclipse.handly/src/org/eclipse/handly/model/impl/Handle.java66
-rw-r--r--org.eclipse.handly/src/org/eclipse/handly/model/impl/HandleDelta.java40
-rw-r--r--org.eclipse.handly/src/org/eclipse/handly/util/TextIndent.java118
12 files changed, 280 insertions, 75 deletions
diff --git a/org.eclipse.handly.examples.adapter/src/org/eclipse/handly/internal/examples/adapter/JavaHandle.java b/org.eclipse.handly.examples.adapter/src/org/eclipse/handly/internal/examples/adapter/JavaHandle.java
index bdab1103..cb0e3319 100644
--- a/org.eclipse.handly.examples.adapter/src/org/eclipse/handly/internal/examples/adapter/JavaHandle.java
+++ b/org.eclipse.handly.examples.adapter/src/org/eclipse/handly/internal/examples/adapter/JavaHandle.java
@@ -150,6 +150,12 @@ public class JavaHandle
}
@Override
+ public String toString(ToStringStyle style)
+ {
+ return toString();
+ }
+
+ @Override
public IHandle[] getChildren() throws CoreException
{
if (!(javaElement instanceof IParent))
diff --git a/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/examples/javamodel/ICompilationUnit.java b/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/examples/javamodel/ICompilationUnit.java
index 75b45892..8780e15b 100644
--- a/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/examples/javamodel/ICompilationUnit.java
+++ b/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/examples/javamodel/ICompilationUnit.java
@@ -45,7 +45,7 @@ public interface ICompilationUnit
* <p>
* This is a handle-only method. The import container may or may not exist.
* </p>
-
+ *
* @return the import container for this compilation unit
* (never <code>null</code>)
*/
diff --git a/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/Field.java b/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/Field.java
index 1590bed0..137bc33e 100644
--- a/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/Field.java
+++ b/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/Field.java
@@ -14,6 +14,7 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.handly.examples.javamodel.IField;
import org.eclipse.handly.model.impl.Body;
import org.eclipse.handly.model.impl.SourceElementBody;
+import org.eclipse.handly.util.TextIndent;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.Signature;
@@ -57,10 +58,10 @@ public class Field
}
@Override
- protected void toStringBody(int tab, StringBuilder builder, Body body,
- boolean showResolvedInfo)
+ protected void toStringBody(TextIndent indent, StringBuilder builder,
+ Body body, boolean showResolvedInfo)
{
- builder.append(tabString(tab));
+ indent.appendTo(builder);
if (body != null && body != NO_BODY)
{
SourceElementBody fieldBody = (SourceElementBody)body;
diff --git a/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/ImportContainer.java b/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/ImportContainer.java
index 88eb0cc8..1c7b9d63 100644
--- a/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/ImportContainer.java
+++ b/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/ImportContainer.java
@@ -19,6 +19,7 @@ import org.eclipse.handly.model.impl.Body;
import org.eclipse.handly.model.impl.Handle;
import org.eclipse.handly.model.impl.HandleManager;
import org.eclipse.handly.model.impl.SourceConstruct;
+import org.eclipse.handly.util.TextIndent;
/**
* Implementation of {@link IImportContainer}.
@@ -78,7 +79,7 @@ public class ImportContainer
}
@Override
- protected void toString(int tab, StringBuilder builder)
+ protected void toString(TextIndent indent, StringBuilder builder)
{
Body body = peekAtBody();
if (body == null)
@@ -87,8 +88,8 @@ public class ImportContainer
for (int i = 0; i < children.length; i++)
{
if (i > 0)
- builder.append('\n');
- ((Handle)children[i]).toStringBody(tab, builder);
+ indent.appendLineSeparatorTo(builder);
+ ((Handle)children[i]).toStringBody(indent, builder);
}
}
}
diff --git a/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/JavaModelManager.java b/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/JavaModelManager.java
index 78b911af..46480f30 100644
--- a/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/JavaModelManager.java
+++ b/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/JavaModelManager.java
@@ -194,7 +194,7 @@ public class JavaModelManager
/**
* Returns the per-project info for the given project. If the info
* doesn't exist, check for the project existence and create the info.
-
+ *
* @param project the given project
* @return the per-project info for the given project (never <code>null</code>)
* @throws CoreException if the Java project doesn't exist
diff --git a/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/Method.java b/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/Method.java
index 1a417617..3c3e65ca 100644
--- a/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/Method.java
+++ b/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/Method.java
@@ -16,6 +16,7 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.handly.examples.javamodel.IMethod;
import org.eclipse.handly.model.impl.Body;
import org.eclipse.handly.model.impl.SourceElementBody;
+import org.eclipse.handly.util.TextIndent;
import org.eclipse.jdt.core.Signature;
/**
@@ -152,10 +153,10 @@ public class Method
}
@Override
- protected void toStringBody(int tab, StringBuilder builder, Body body,
- boolean showResolvedInfo)
+ protected void toStringBody(TextIndent indent, StringBuilder builder,
+ Body body, boolean showResolvedInfo)
{
- builder.append(tabString(tab));
+ indent.appendTo(builder);
if (body != null && body != NO_BODY)
{
SourceElementBody methodBody = (SourceElementBody)body;
diff --git a/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/PackageFragment.java b/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/PackageFragment.java
index 172dbe81..cba9e561 100644
--- a/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/PackageFragment.java
+++ b/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/PackageFragment.java
@@ -28,6 +28,7 @@ import org.eclipse.handly.model.IHandle;
import org.eclipse.handly.model.impl.Body;
import org.eclipse.handly.model.impl.Handle;
import org.eclipse.handly.model.impl.HandleManager;
+import org.eclipse.handly.util.TextIndent;
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.Signature;
@@ -209,18 +210,19 @@ public class PackageFragment
}
@Override
- protected void toStringBody(int tab, StringBuilder builder, Body body,
- boolean showResolvedInfo)
+ protected void toStringBody(TextIndent indent, StringBuilder builder,
+ Body body, boolean showResolvedInfo)
{
- super.toStringBody(tab, builder, body, showResolvedInfo);
- if (body != null && tab > 0)
+ super.toStringBody(indent, builder, body, showResolvedInfo);
+ if (body != null && indent.getLevel() > 0)
builder.append(" (...)"); //$NON-NLS-1$
}
@Override
- protected void toStringChildren(int tab, StringBuilder builder, Body body)
+ protected void toStringChildren(TextIndent indent, StringBuilder builder,
+ Body body)
{
- if (tab == 0)
- super.toStringChildren(tab, builder, body);
+ if (indent.getLevel() == 0)
+ super.toStringChildren(indent, builder, body);
}
}
diff --git a/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/Type.java b/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/Type.java
index 7b76002f..9d28a545 100644
--- a/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/Type.java
+++ b/org.eclipse.handly.examples.javamodel/src/org/eclipse/handly/internal/examples/javamodel/Type.java
@@ -20,6 +20,7 @@ import org.eclipse.handly.model.impl.Body;
import org.eclipse.handly.model.impl.Handle;
import org.eclipse.handly.model.impl.SourceElementBody;
import org.eclipse.handly.snapshot.ISnapshot;
+import org.eclipse.handly.util.TextIndent;
import org.eclipse.handly.util.TextRange;
import org.eclipse.jdt.core.Flags;
@@ -179,10 +180,10 @@ public class Type
}
@Override
- protected void toStringBody(int tab, StringBuilder builder, Body body,
- boolean showResolvedInfo)
+ protected void toStringBody(TextIndent indent, StringBuilder builder,
+ Body body, boolean showResolvedInfo)
{
- builder.append(tabString(tab));
+ indent.appendTo(builder);
if (body != null && body != NO_BODY)
{
SourceElementBody typeBody = (SourceElementBody)body;
diff --git a/org.eclipse.handly/src/org/eclipse/handly/model/IHandle.java b/org.eclipse.handly/src/org/eclipse/handly/model/IHandle.java
index 10f6bc00..e034f8ed 100644
--- a/org.eclipse.handly/src/org/eclipse/handly/model/IHandle.java
+++ b/org.eclipse.handly/src/org/eclipse/handly/model/IHandle.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014 1C LLC.
+ * Copyright (c) 2014, 2015 1C-Soft LLC and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -11,10 +11,15 @@
*******************************************************************************/
package org.eclipse.handly.model;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
+
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.handly.util.TextIndent;
/**
* Represents an element of a handle-based model.
@@ -141,4 +146,74 @@ public interface IHandle
*/
<T extends IHandle> T[] getChildren(Class<T> childType)
throws CoreException;
+
+ /**
+ * Returns a string representation of this element. Note that the specified
+ * style serves as a hint that implementations may or may not fully support.
+ *
+ * @param style style hint (not <code>null</code>)
+ * @return a string representation of this element (never <code>null</code>)
+ */
+ String toString(ToStringStyle style);
+
+ /**
+ * Style hint for <code>IHandle.toString</code>.
+ * @see IHandle#toString(ToStringStyle)
+ */
+ final class ToStringStyle
+ {
+ private final TextIndent indent;
+ private final EnumSet<Option> options;
+
+ /**
+ * Creates a new style with the given indent and options.
+ *
+ * @param indent indentation info (not <code>null</code>)
+ * @param options style options (not <code>null</code>)
+ */
+ public ToStringStyle(TextIndent indent, EnumSet<Option> options)
+ {
+ if (indent == null)
+ throw new IllegalArgumentException();
+ if (options == null)
+ throw new IllegalArgumentException();
+ this.indent = indent;
+ this.options = options;
+ }
+
+ /**
+ * Returns the indentation info.
+ *
+ * @return the indentation info (never <code>null</code>)
+ */
+ public TextIndent getIndent()
+ {
+ return indent;
+ }
+
+ /**
+ * Returns the style options.
+ *
+ * @return the style options (never <code>null</code>)
+ */
+ public Set<Option> getOptions()
+ {
+ return Collections.unmodifiableSet(options);
+ }
+
+ /**
+ * Style options.
+ */
+ public enum Option
+ {
+ /**
+ * Include ancestors info.
+ */
+ ANCESTORS,
+ /**
+ * Include children info.
+ */
+ CHILDREN
+ }
+ }
}
diff --git a/org.eclipse.handly/src/org/eclipse/handly/model/impl/Handle.java b/org.eclipse.handly/src/org/eclipse/handly/model/impl/Handle.java
index 94a3e012..f5bc698f 100644
--- a/org.eclipse.handly/src/org/eclipse/handly/model/impl/Handle.java
+++ b/org.eclipse.handly/src/org/eclipse/handly/model/impl/Handle.java
@@ -13,6 +13,7 @@ package org.eclipse.handly.model.impl;
import java.lang.reflect.Array;
import java.util.ArrayList;
+import java.util.EnumSet;
import java.util.List;
import java.util.Map;
@@ -23,6 +24,7 @@ import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.handly.internal.Activator;
import org.eclipse.handly.model.IHandle;
+import org.eclipse.handly.util.TextIndent;
/**
* The root of the handle class hierarchy.
@@ -221,7 +223,25 @@ public abstract class Handle
public String toString()
{
StringBuilder builder = new StringBuilder();
- toString(0, builder);
+ toString(TextIndent.with(" "), builder); //$NON-NLS-1$
+ return builder.toString();
+ }
+
+ @Override
+ public String toString(ToStringStyle style)
+ {
+ StringBuilder builder = new StringBuilder();
+ if (style.getOptions().contains(ToStringStyle.Option.CHILDREN))
+ {
+ toString(style.getIndent(), builder);
+ }
+ else
+ {
+ toStringBody(style.getIndent(), builder, NO_BODY,
+ true/*show resolved info*/);
+ if (style.getOptions().contains(ToStringStyle.Option.ANCESTORS))
+ toStringAncestors(builder);
+ }
return builder.toString();
}
@@ -231,7 +251,8 @@ public abstract class Handle
public String toDebugString()
{
StringBuilder builder = new StringBuilder();
- toStringBody(0, builder, NO_BODY, true/*show resolved info*/);
+ toStringBody(TextIndent.NONE, builder, NO_BODY,
+ true/*show resolved info*/);
return builder.toString();
}
@@ -249,7 +270,7 @@ public abstract class Handle
public String toStringWithAncestors(boolean showResolvedInfo)
{
StringBuilder builder = new StringBuilder();
- toStringBody(0, builder, NO_BODY, showResolvedInfo);
+ toStringBody(TextIndent.NONE, builder, NO_BODY, showResolvedInfo);
toStringAncestors(builder);
return builder.toString();
}
@@ -257,10 +278,10 @@ public abstract class Handle
/**
* Debugging purposes
*/
- public Body toStringBody(int tab, StringBuilder builder)
+ public Body toStringBody(TextIndent indent, StringBuilder builder)
{
Body body = peekAtBody();
- toStringBody(tab, builder, body, true/*show resolved info*/);
+ toStringBody(indent, builder, body, true/*show resolved info*/);
return body;
}
@@ -272,7 +293,7 @@ public abstract class Handle
if (parent != null && parent.getParent() != null)
{
builder.append(" [in "); //$NON-NLS-1$
- parent.toStringBody(0, builder, NO_BODY,
+ parent.toStringBody(TextIndent.NONE, builder, NO_BODY,
false/*don't show resolved info*/);
parent.toStringAncestors(builder);
builder.append(']');
@@ -282,37 +303,42 @@ public abstract class Handle
/**
* Debugging purposes
*/
- protected void toString(int tab, StringBuilder builder)
+ protected void toString(TextIndent indent, StringBuilder builder)
{
- Body body = toStringBody(tab, builder);
- if (tab == 0)
+ Body body = toStringBody(indent, builder);
+ if (indent.getLevel() == 0)
{
toStringAncestors(builder);
}
- toStringChildren(tab, builder, body);
+ toStringChildren(indent, builder, body);
}
/**
* Debugging purposes
*/
- protected void toStringChildren(int tab, StringBuilder builder, Body body)
+ protected void toStringChildren(TextIndent indent, StringBuilder builder,
+ Body body)
{
if (body == null)
return;
+ ToStringStyle childStyle = null;
for (IHandle child : body.getChildren())
{
- builder.append('\n');
- ((Handle)child).toString(tab + 1, builder);
+ indent.appendLineSeparatorTo(builder);
+ if (childStyle == null)
+ childStyle = new ToStringStyle(indent.getIncreasedIndent(),
+ EnumSet.of(ToStringStyle.Option.CHILDREN));
+ builder.append(child.toString(childStyle));
}
}
/**
* Debugging purposes
*/
- protected void toStringBody(int tab, StringBuilder builder, Body body,
- boolean showResolvedInfo)
+ protected void toStringBody(TextIndent indent, StringBuilder builder,
+ Body body, boolean showResolvedInfo)
{
- builder.append(tabString(tab));
+ indent.appendTo(builder);
toStringName(builder);
if (body == null)
{
@@ -328,14 +354,6 @@ public abstract class Handle
builder.append(getName());
}
- protected String tabString(int tab)
- {
- StringBuilder builder = new StringBuilder();
- for (int i = tab; i > 0; i--)
- builder.append(" "); //$NON-NLS-1$
- return builder.toString();
- }
-
/**
* Returns an opaque object representing the <i>type</i> of this element.
* Equal elements must have equal types.
diff --git a/org.eclipse.handly/src/org/eclipse/handly/model/impl/HandleDelta.java b/org.eclipse.handly/src/org/eclipse/handly/model/impl/HandleDelta.java
index 5dd93b3b..842440f6 100644
--- a/org.eclipse.handly/src/org/eclipse/handly/model/impl/HandleDelta.java
+++ b/org.eclipse.handly/src/org/eclipse/handly/model/impl/HandleDelta.java
@@ -12,6 +12,7 @@
package org.eclipse.handly.model.impl;
import java.util.ArrayList;
+import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -21,6 +22,7 @@ import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.handly.model.IHandle;
import org.eclipse.handly.model.IHandleDelta;
import org.eclipse.handly.model.ISourceFile;
+import org.eclipse.handly.util.TextIndent;
/**
* To create a delta tree, use the <code>insertXXX</code> methods on a root delta.
@@ -575,7 +577,9 @@ public class HandleDelta
{
builder.append('\t');
}
- toDebugString(element, builder);
+ builder.append(element.toString(new IHandle.ToStringStyle(
+ TextIndent.NONE, EnumSet.noneOf(
+ IHandle.ToStringStyle.Option.class))));
toDebugString(builder);
for (HandleDelta child : affectedChildren)
{
@@ -663,7 +667,9 @@ public class HandleDelta
if (prev)
builder.append(" | "); //$NON-NLS-1$
builder.append("MOVED_FROM("); //$NON-NLS-1$
- toStringWithAncestors(getMovedFromElement(), builder);
+ builder.append(getMovedFromElement().toString(
+ new IHandle.ToStringStyle(TextIndent.NONE, EnumSet.of(
+ IHandle.ToStringStyle.Option.ANCESTORS))));
builder.append(')');
prev = true;
}
@@ -672,7 +678,9 @@ public class HandleDelta
if (prev)
builder.append(" | "); //$NON-NLS-1$
builder.append("MOVED_TO("); //$NON-NLS-1$
- toStringWithAncestors(getMovedToElement(), builder);
+ builder.append(getMovedToElement().toString(
+ new IHandle.ToStringStyle(TextIndent.NONE, EnumSet.of(
+ IHandle.ToStringStyle.Option.ANCESTORS))));
builder.append(')');
prev = true;
}
@@ -736,32 +744,6 @@ public class HandleDelta
}
/**
- * Debugging purposes
- */
- protected void toDebugString(IHandle element, StringBuilder builder)
- {
- if (element instanceof Handle)
- builder.append(((Handle)element).toDebugString());
- else
- builder.append(element.getName());
- }
-
- /**
- * Debugging purposes
- */
- protected void toStringWithAncestors(IHandle element, StringBuilder builder)
- {
- toDebugString(element, builder);
- IHandle parent = element.getParent();
- if (parent != null && parent.getParent() != null)
- {
- builder.append(" [in "); //$NON-NLS-1$
- toStringWithAncestors(parent, builder);
- builder.append(']');
- }
- }
-
- /**
* Returns a new, initially empty delta for the given element.
*
* @param element the element that this delta describes a change to
diff --git a/org.eclipse.handly/src/org/eclipse/handly/util/TextIndent.java b/org.eclipse.handly/src/org/eclipse/handly/util/TextIndent.java
new file mode 100644
index 00000000..9bc4fc87
--- /dev/null
+++ b/org.eclipse.handly/src/org/eclipse/handly/util/TextIndent.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2015 1C-Soft LLC.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Vladimir Piskarev (1C) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.handly.util;
+
+/**
+ * A text indent has a level and is based on an indentation string.
+ */
+public final class TextIndent
+{
+ /**
+ * An empty indent of level 0.
+ */
+ public static final TextIndent NONE = new TextIndent(0, ""); //$NON-NLS-1$
+
+ private final int level;
+ private final String space;
+
+ /**
+ * Returns a text indent of level 0 with the given indentation string.
+ *
+ * @param space an indentation string (not <code>null</code>)
+ * @return a text indent of level 0 with the given indentation string
+ */
+ public static TextIndent with(String space)
+ {
+ if (space == null)
+ throw new IllegalArgumentException();
+ return new TextIndent(0, space);
+ }
+
+ /**
+ * Returns the level of this text indent.
+ *
+ * @return the indentation level (0-based)
+ */
+ public int getLevel()
+ {
+ return level;
+ }
+
+ /**
+ * Returns whether this text indent is empty, i.e. is based on an empty
+ * indentation string.
+ *
+ * @return <code>true</code> if this text indent is empty,
+ * <code>false</code> otherwise
+ */
+ public boolean isEmpty()
+ {
+ return space.isEmpty();
+ }
+
+ /**
+ * Returns a text indent increased by one level. Does not modify this object.
+ *
+ * @return a text indent increased by one level (never <code>null</code>)
+ */
+ public TextIndent getIncreasedIndent()
+ {
+ return new TextIndent(level + 1, space);
+ }
+
+ /**
+ * Returns a text indent decreased by one level. Does not modify this object.
+ *
+ * @return a text indent decreased by one level (never <code>null</code>)
+ * @throws IllegalStateException if this indent's level is zero
+ */
+ public TextIndent getDecreasedIndent()
+ {
+ if (level == 0)
+ throw new IllegalStateException();
+ return new TextIndent(level - 1, space);
+ }
+
+ /**
+ * Appends a line separator to the given string builder.
+ *
+ * @param builder a string builder (not <code>null</code>)
+ */
+ public void appendLineSeparatorTo(StringBuilder builder)
+ {
+ builder.append('\n');
+ }
+
+ /**
+ * Appends this text indent to the given string builder.
+ *
+ * @param builder a string builder (not <code>null</code>)
+ */
+ public void appendTo(StringBuilder builder)
+ {
+ for (int i = 0; i < level; i++)
+ builder.append(space);
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder builder = new StringBuilder();
+ appendTo(builder);
+ return builder.toString();
+ }
+
+ private TextIndent(int level, String space)
+ {
+ this.level = level;
+ this.space = space;
+ }
+}

Back to the top