/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at legal-notices/CDDLv1_0.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2008-2009 Sun Microsystems, Inc. * Portions Copyright 2011 ForgeRock AS */ package org.forgerock.opendj.config; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.forgerock.opendj.server.config.client.RootCfgClient; import org.forgerock.opendj.server.config.meta.RootCfgDefn; import org.forgerock.opendj.server.config.server.RootCfg; import org.forgerock.opendj.ldap.DN; import org.forgerock.opendj.ldap.RDN; import org.forgerock.opendj.ldap.schema.AttributeType; import org.forgerock.opendj.ldap.schema.Schema; /** * A path which can be used to determine the location of a managed object * instance. *

* A path is made up of zero or more elements each of which represents a managed * object. Managed objects are arranged hierarchically with the root * configuration being the top-most managed object. Elements are ordered such * that the root configuration managed object is the first element and * subsequent elements representing managed objects further down the hierarchy. *

* A path can be encoded into a string representation using the * {@link #toString()} and {@link #toString(StringBuilder)} methods. Conversely, * this string representation can be parsed using the {@link #valueOf(String)} * method. *

* The string representation of a managed object path is similar in principle to * a UNIX file-system path and is defined as follows: *

* The following path string representation identifies a connection handler * instance (note that the type is not specified indicating that * the path identifies a connection handler called my handler which can * be any type of connection handler): * *
 *  /relation=connection-handler+name=my handler
 * 
* * If the identified connection handler must be an LDAP connection handler then * the above path should include the type: * *
 *  /relation=connection-handler+type=ldap-connection-handler+name=my handler
 * 
* * The final example identifies the global configuration: * *
 *  /relation=global-configuration
 * 
* * @param * The type of client managed object configuration that this path * references. * @param * The type of server managed object configuration that this path * references. */ public final class ManagedObjectPath { /** * A serialize which is used to generate the toDN representation. */ private static final class DNSerializer implements ManagedObjectPathSerializer { // The current DN. private DN dn; // The LDAP profile. private final LDAPProfile profile; // Create a new DN builder. private DNSerializer() { this.dn = DN.rootDN(); this.profile = LDAPProfile.getInstance(); } /** * {@inheritDoc} */ public void appendManagedObjectPathElement( InstantiableRelationDefinition r, AbstractManagedObjectDefinition d, String name) { // Add the RDN sequence representing the relation. appendManagedObjectPathElement(r); // Now add the single RDN representing the named instance. String type = profile.getRelationChildRDNType(r); AttributeType attrType = Schema.getDefaultSchema().getAttributeType(type); dn = dn.child(new RDN(attrType, name)); } /** * {@inheritDoc} */ public void appendManagedObjectPathElement( SetRelationDefinition r, AbstractManagedObjectDefinition d) { // Add the RDN sequence representing the relation. appendManagedObjectPathElement(r); // Now add the single RDN representing the instance. String type = profile.getRelationChildRDNType(r); AttributeType attrType = Schema.getDefaultSchema().getAttributeType(type); dn = dn.child(new RDN(attrType, d.getName())); } /** * {@inheritDoc} */ public void appendManagedObjectPathElement( OptionalRelationDefinition r, AbstractManagedObjectDefinition d) { // Add the RDN sequence representing the relation. appendManagedObjectPathElement(r); } /** * {@inheritDoc} */ public void appendManagedObjectPathElement( SingletonRelationDefinition r, AbstractManagedObjectDefinition d) { // Add the RDN sequence representing the relation. appendManagedObjectPathElement(r); } // Appends the RDN sequence representing the provided relation. private void appendManagedObjectPathElement(RelationDefinition r) { DN localName = DN.valueOf(profile.getRelationRDNSequence(r)); dn = dn.child(localName); } // Gets the serialized DN value. private DN toDN() { return dn; } } /** * Abstract path element. */ private static abstract class Element { // The type of managed object referenced by this element. private final AbstractManagedObjectDefinition definition; /** * Protected constructor. * * @param definition * The type of managed object referenced by this element. */ protected Element(AbstractManagedObjectDefinition definition) { this.definition = definition; } /** * Get the managed object definition associated with this element. * * @return Returns the managed object definition associated with this * element. */ public final AbstractManagedObjectDefinition getManagedObjectDefinition() { return definition; } /** * Get the name associated with this element if applicable. * * @return Returns the name associated with this element if applicable. */ public String getName() { return null; } /** * Get the relation definition associated with this element. * * @return Returns the relation definition associated with this element. */ public abstract RelationDefinition getRelationDefinition(); /** * Serialize this path element using the provided serialization * strategy. * * @param serializer * The managed object path serialization strategy. */ public abstract void serialize(ManagedObjectPathSerializer serializer); } /** * A path element representing an instantiable managed object. */ private static final class InstantiableElement extends Element { // Factory method. private static final InstantiableElement create( InstantiableRelationDefinition r, AbstractManagedObjectDefinition d, String name) { return new InstantiableElement(r, d, name); } // The name of the managed object. private final String name; // The instantiable relation. private final InstantiableRelationDefinition r; // Private constructor. private InstantiableElement(InstantiableRelationDefinition r, AbstractManagedObjectDefinition d, String name) { super(d); this.r = r; this.name = name; } /** * {@inheritDoc} */ @Override public String getName() { return name; } /** * {@inheritDoc} */ @Override public InstantiableRelationDefinition getRelationDefinition() { return r; } /** * {@inheritDoc} */ @Override public void serialize(ManagedObjectPathSerializer serializer) { serializer.appendManagedObjectPathElement(r, getManagedObjectDefinition(), name); } } /** * A path element representing an optional managed object. */ private static final class OptionalElement extends Element { // Factory method. private static final OptionalElement create( OptionalRelationDefinition r, AbstractManagedObjectDefinition d) { return new OptionalElement(r, d); } // The optional relation. private final OptionalRelationDefinition r; // Private constructor. private OptionalElement(OptionalRelationDefinition r, AbstractManagedObjectDefinition d) { super(d); this.r = r; } /** * {@inheritDoc} */ @Override public OptionalRelationDefinition getRelationDefinition() { return r; } /** * {@inheritDoc} */ @Override public void serialize(ManagedObjectPathSerializer serializer) { serializer.appendManagedObjectPathElement(r, getManagedObjectDefinition()); } } /** * A path element representing an set managed object. */ private static final class SetElement extends Element { // Factory method. private static final SetElement create( SetRelationDefinition r, AbstractManagedObjectDefinition d) { return new SetElement(r, d); } // The set relation. private final SetRelationDefinition r; // Private constructor. private SetElement(SetRelationDefinition r, AbstractManagedObjectDefinition d) { super(d); this.r = r; } /** * {@inheritDoc} */ @Override public SetRelationDefinition getRelationDefinition() { return r; } /** * {@inheritDoc} */ @Override public void serialize(ManagedObjectPathSerializer serializer) { serializer.appendManagedObjectPathElement(r, getManagedObjectDefinition()); } } /** * A path element representing a singleton managed object. */ private static final class SingletonElement extends Element { // Factory method. private static final SingletonElement create( SingletonRelationDefinition r, AbstractManagedObjectDefinition d) { return new SingletonElement(r, d); } // The singleton relation. private final SingletonRelationDefinition r; // Private constructor. private SingletonElement(SingletonRelationDefinition r, AbstractManagedObjectDefinition d) { super(d); this.r = r; } /** * {@inheritDoc} */ @Override public SingletonRelationDefinition getRelationDefinition() { return r; } /** * {@inheritDoc} */ @Override public void serialize(ManagedObjectPathSerializer serializer) { serializer.appendManagedObjectPathElement(r, getManagedObjectDefinition()); } } /** * A serialize which is used to generate the toString representation. */ private static final class StringSerializer implements ManagedObjectPathSerializer { // Serialize to this string builder. private final StringBuilder builder; // Private constructor. private StringSerializer(StringBuilder builder) { this.builder = builder; } /** * {@inheritDoc} */ public void appendManagedObjectPathElement( InstantiableRelationDefinition r, AbstractManagedObjectDefinition d, String name) { serializeElement(r, d); // Be careful to escape any forward slashes in the name. builder.append("+name="); builder.append(name.replace("/", "//")); } /** * {@inheritDoc} */ public void appendManagedObjectPathElement( OptionalRelationDefinition r, AbstractManagedObjectDefinition d) { serializeElement(r, d); } /** * {@inheritDoc} */ public void appendManagedObjectPathElement( SingletonRelationDefinition r, AbstractManagedObjectDefinition d) { serializeElement(r, d); } /** * {@inheritDoc} */ public void appendManagedObjectPathElement( SetRelationDefinition r, AbstractManagedObjectDefinition d) { serializeElement(r, d); } // Common element serialization. private void serializeElement(RelationDefinition r, AbstractManagedObjectDefinition d) { // Always specify the relation name. builder.append("/relation="); builder.append(r.getName()); // Only specify the type if it is a sub-type of the relation's // type. if (r.getChildDefinition() != d) { builder.append("+type="); builder.append(d.getName()); } } } // Single instance of a root path. private static final ManagedObjectPath EMPTY_PATH = new ManagedObjectPath(new LinkedList>(), null, RootCfgDefn.getInstance()); // A regular expression used to parse path elements. private static final Pattern PE_REGEXP = Pattern.compile("^\\s*relation=\\s*([^+]+)\\s*" + "(\\+\\s*type=\\s*([^+]+)\\s*)?" + "(\\+\\s*name=\\s*([^+]+)\\s*)?$"); /** * Creates a new managed object path representing the configuration root. * * @return Returns a new managed object path representing the configuration * root. */ public static ManagedObjectPath emptyPath() { return EMPTY_PATH; } /** * Returns a managed object path holding the value of the specified string. * * @param s * The string to be parsed. * @return Returns a managed object path holding the value of the specified * string. * @throws IllegalArgumentException * If the string could not be parsed. */ public static ManagedObjectPath valueOf(String s) { String ns = s.trim(); // Check for root special case. if (ns.equals("/")) { return EMPTY_PATH; } // Parse the elements. LinkedList> elements = new LinkedList>(); Element lastElement = null; AbstractManagedObjectDefinition definition = RootCfgDefn.getInstance(); if (!ns.startsWith("/")) { throw new IllegalArgumentException("Invalid path \"" + ns + "\": must begin with a \"/\""); } int start = 1; while (true) { // Get the next path element. int end; for (end = start; end < ns.length(); end++) { char c = ns.charAt(end); if (c == '/') { if (end == (ns.length() - 1)) { throw new IllegalArgumentException("Invalid path \"" + ns + "\": must not end with a trailing \"/\""); } if (ns.charAt(end + 1) == '/') { // Found an escaped forward slash. end++; } else { // Found the end of this path element. break; } } } // Get the next element. String es = ns.substring(start, end); Matcher m = PE_REGEXP.matcher(es); if (!m.matches()) { throw new IllegalArgumentException("Invalid path element \"" + es + "\" in path \"" + ns + "\""); } // Mandatory. String relation = m.group(1); // Optional. String type = m.group(3); // Mandatory if relation is instantiable. String name = m.group(5); // Get the relation definition. RelationDefinition r; try { r = definition.getRelationDefinition(relation); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Invalid path element \"" + es + "\" in path \"" + ns + "\": unknown relation \"" + relation + "\""); } // Append the next element. lastElement = createElement(r, ns, es, type, name); elements.add(lastElement); definition = lastElement.getManagedObjectDefinition(); // Update start to point to the beginning of the next element. if (end < ns.length()) { // Skip to the beginning of the next element start = end + 1; } else { // We reached the end of the string. break; } } // Construct the new path. return create(elements, lastElement); } // Factory method required in order to allow generic wild-card // construction of new paths. private static ManagedObjectPath create( LinkedList> elements, Element lastElement) { return new ManagedObjectPath(elements, lastElement.getRelationDefinition(), lastElement.getManagedObjectDefinition()); } // Decode an element. // @Checkstyle:ignore private static Element createElement( RelationDefinition r, String path, String element, String type, String name) { // First determine the managed object definition. AbstractManagedObjectDefinition d = null; if (type != null) { for (AbstractManagedObjectDefinition child : r.getChildDefinition() .getAllChildren()) { if (child.getName().equals(type)) { d = child; break; } } if (d == null) { throw new IllegalArgumentException("Invalid path element \"" + element + "\" in path \"" + path + "\": unknown sub-type \"" + type + "\""); } } else { d = r.getChildDefinition(); } if (r instanceof InstantiableRelationDefinition) { InstantiableRelationDefinition ir = (InstantiableRelationDefinition) r; if (name == null) { throw new IllegalArgumentException("Invalid path element \"" + element + "\" in path \"" + path + "\": no instance name for instantiable relation"); } return InstantiableElement.create(ir, d, name); } else if (r instanceof SetRelationDefinition) { SetRelationDefinition ir = (SetRelationDefinition) r; if (name != null) { throw new IllegalArgumentException("Invalid path element \"" + element + "\" in path \"" + path + "\": instance name specified for set relation"); } return SetElement.create(ir, d); } else if (r instanceof OptionalRelationDefinition) { OptionalRelationDefinition or = (OptionalRelationDefinition) r; if (name != null) { throw new IllegalArgumentException("Invalid path element \"" + element + "\" in path \"" + path + "\": instance name specified for optional relation"); } return OptionalElement.create(or, d); } else if (r instanceof SingletonRelationDefinition) { SingletonRelationDefinition sr = (SingletonRelationDefinition) r; if (name != null) { throw new IllegalArgumentException("Invalid path element \"" + element + "\" in path \"" + path + "\": instance name specified for singleton relation"); } return SingletonElement.create(sr, d); } else { throw new IllegalArgumentException("Invalid path element \"" + element + "\" in path \"" + path + "\": unsupported relation type"); } } // The managed object definition in this path. private final AbstractManagedObjectDefinition d; // The list of path elements in this path. private final List> elements; // The last relation definition in this path. private final RelationDefinition r; // Private constructor. private ManagedObjectPath(LinkedList> elements, RelationDefinition r, AbstractManagedObjectDefinition d) { this.elements = Collections.unmodifiableList(elements); this.r = r; this.d = d; } /** * Creates a new managed object path which has the same structure as this * path except that the final path element is associated with the specified * managed object definition. * * @param * The type of client managed object configuration that this path * will reference. * @param * The type of server managed object configuration that this path * will reference. * @param nd * The new managed object definition. * @return Returns a new managed object path which has the same structure as * this path except that the final path element is associated with * the specified managed object definition. */ // @Checkstyle:ignore public ManagedObjectPath asSubType(AbstractManagedObjectDefinition nd) { if (r instanceof InstantiableRelationDefinition) { InstantiableRelationDefinition ir = (InstantiableRelationDefinition) r; if (elements.size() == 0) { return parent().child(ir, nd, "null"); } else { return parent().child(ir, nd, elements.get(elements.size() - 1).getName()); } } else if (r instanceof SetRelationDefinition) { SetRelationDefinition sr = (SetRelationDefinition) r; return parent().child(sr, nd); } else if (r instanceof OptionalRelationDefinition) { OptionalRelationDefinition or = (OptionalRelationDefinition) r; return parent().child(or, nd); } else { SingletonRelationDefinition sr = (SingletonRelationDefinition) r; return parent().child(sr, nd); } } /** * Creates a new child managed object path beneath the provided parent path * having the specified managed object definition. * * @param * The type of client managed object configuration that the child * path references. * @param * The type of server managed object configuration that the child * path references. * @param r * The instantiable relation referencing the child. * @param d * The managed object definition associated with the child (must * be a sub-type of the relation). * @param name * The relative name of the child managed object. * @return Returns a new child managed object path beneath the provided * parent path. * @throws IllegalArgumentException * If the provided name is empty or blank. */ public ManagedObjectPath child( InstantiableRelationDefinition r, AbstractManagedObjectDefinition d, String name) { if (name.trim().length() == 0) { throw new IllegalArgumentException("Empty or blank managed object names are not allowed"); } LinkedList> celements = new LinkedList>(elements); celements.add(new InstantiableElement(r, d, name)); return new ManagedObjectPath(celements, r, d); } /** * Creates a new child managed object path beneath the provided parent path * using the relation's child managed object definition. * * @param * The type of client managed object configuration that the child * path references. * @param * The type of server managed object configuration that the child * path references. * @param r * The instantiable relation referencing the child. * @param name * The relative name of the child managed object. * @return Returns a new child managed object path beneath the provided * parent path. * @throws IllegalArgumentException * If the provided name is empty or blank. */ public ManagedObjectPath child( InstantiableRelationDefinition r, String name) { return child(r, r.getChildDefinition(), name); } /** * Creates a new child managed object path beneath the provided parent path * having the specified managed object definition. * * @param * The type of client managed object configuration that the child * path references. * @param * The type of server managed object configuration that the child * path references. * @param r * The optional relation referencing the child. * @param d * The managed object definition associated with the child (must * be a sub-type of the relation). * @return Returns a new child managed object path beneath the provided * parent path. */ public ManagedObjectPath child( OptionalRelationDefinition r, AbstractManagedObjectDefinition d) { LinkedList> celements = new LinkedList>(elements); celements.add(new OptionalElement(r, d)); return new ManagedObjectPath(celements, r, d); } /** * Creates a new child managed object path beneath the provided parent path * using the relation's child managed object definition. * * @param * The type of client managed object configuration that the child * path references. * @param * The type of server managed object configuration that the child * path references. * @param r * The optional relation referencing the child. * @return Returns a new child managed object path beneath the provided * parent path. */ public ManagedObjectPath child( OptionalRelationDefinition r) { return child(r, r.getChildDefinition()); } /** * Creates a new child managed object path beneath the provided parent path * having the specified managed object definition. * * @param * The type of client managed object configuration that the child * path references. * @param * The type of server managed object configuration that the child * path references. * @param r * The singleton relation referencing the child. * @param d * The managed object definition associated with the child (must * be a sub-type of the relation). * @return Returns a new child managed object path beneath the provided * parent path. */ public ManagedObjectPath child( SingletonRelationDefinition r, AbstractManagedObjectDefinition d) { LinkedList> celements = new LinkedList>(elements); celements.add(new SingletonElement(r, d)); return new ManagedObjectPath(celements, r, d); } /** * Creates a new child managed object path beneath the provided parent path * using the relation's child managed object definition. * * @param * The type of client managed object configuration that the child * path references. * @param * The type of server managed object configuration that the child * path references. * @param r * The singleton relation referencing the child. * @return Returns a new child managed object path beneath the provided * parent path. */ public ManagedObjectPath child( SingletonRelationDefinition r) { return child(r, r.getChildDefinition()); } /** * Creates a new child managed object path beneath the provided parent path * having the specified managed object definition. * * @param * The type of client managed object configuration that the child * path references. * @param * The type of server managed object configuration that the child * path references. * @param r * The set relation referencing the child. * @param d * The managed object definition associated with the child (must * be a sub-type of the relation). * @return Returns a new child managed object path beneath the provided * parent path. * @throws IllegalArgumentException * If the provided name is empty or blank. */ public ManagedObjectPath child( SetRelationDefinition r, AbstractManagedObjectDefinition d) { LinkedList> celements = new LinkedList>(elements); celements.add(new SetElement(r, d)); return new ManagedObjectPath(celements, r, d); } /** * Creates a new child managed object path beneath the provided parent path * having the managed object definition indicated by name. * * @param * The type of client managed object configuration that the path * references. * @param * The type of server managed object configuration that the path * references. * @param r * The set relation referencing the child. * @param name * The name of the managed object definition associated with the * child (must be a sub-type of the relation). * @return Returns a new child managed object path beneath the provided * parent path. * @throws IllegalArgumentException * If the provided name is empty or blank or specifies a managed * object definition which is not a sub-type of the relation's * child definition. */ public ManagedObjectPath child( SetRelationDefinition r, String name) { AbstractManagedObjectDefinition d = r.getChildDefinition(); return child(r, d.getChild(name)); } /** * Creates a new child managed object path beneath the provided parent path * using the relation's child managed object definition. * * @param * The type of client managed object configuration that the child * path references. * @param * The type of server managed object configuration that the child * path references. * @param r * The set relation referencing the child. * @return Returns a new child managed object path beneath the provided * parent path. * @throws IllegalArgumentException * If the provided name is empty or blank. */ public ManagedObjectPath child( SetRelationDefinition r) { return child(r, r.getChildDefinition()); } /** * {@inheritDoc} */ @Override public boolean equals(Object obj) { if (obj == this) { return true; } else if (obj instanceof ManagedObjectPath) { ManagedObjectPath other = (ManagedObjectPath) obj; return toString().equals(other.toString()); } else { return false; } } /** * Get the definition of the managed object referred to by this path. *

* When the path is empty, the {@link RootCfgDefn} is returned. * * @return Returns the definition of the managed object referred to by this * path, or the {@link RootCfgDefn} if the path is empty. */ public AbstractManagedObjectDefinition getManagedObjectDefinition() { return d; } /** * Get the name of the managed object referred to by this path if * applicable. *

* If there path does not refer to an instantiable managed object * null is returned. * * @return Returns the name of the managed object referred to by this path, * or null if the managed object does not have a name. */ public String getName() { if (elements.isEmpty()) { return null; } else { return elements.get(elements.size() - 1).getName(); } } /** * Get the relation definition of the managed object referred to by this * path. *

* When the path is empty, the null is returned. * * @return Returns the relation definition of the managed object referred to * by this path, or the null if the path is empty. */ public RelationDefinition getRelationDefinition() { return r; } /** * {@inheritDoc} */ @Override public int hashCode() { return toString().hashCode(); } /** * Determine whether or not this path contains any path elements. * * @return Returns true if this path does not contain any path * elements. */ public boolean isEmpty() { return elements.isEmpty(); } /** * Determines whether this managed object path references the same location * as the provided managed object path. *

* This method differs from equals in that it ignores sub-type * definitions. * * @param other * The managed object path to be compared. * @return Returns true if this managed object path references * the same location as the provided managed object path. */ public boolean matches(ManagedObjectPath other) { DN thisDN = toDN(); DN otherDN = other.toDN(); return thisDN.equals(otherDN); } /** * Creates a new parent managed object path representing the immediate * parent of this path. This method is a short-hand for * parent(1). * * @return Returns a new parent managed object path representing the * immediate parent of this path. * @throws IllegalArgumentException * If this path does not have a parent (i.e. it is the empty * path). */ public ManagedObjectPath parent() { return parent(1); } /** * Creates a new parent managed object path the specified number of path * elements above this path. * * @param offset * The number of path elements (0 - means no offset, 1 means the * parent, and 2 means the grand-parent). * @return Returns a new parent managed object path the specified number of * path elements above this path. * @throws IllegalArgumentException * If the offset is less than 0, or greater than the number of * path elements in this path. */ public ManagedObjectPath parent(int offset) { if (offset < 0) { throw new IllegalArgumentException("Negative offset"); } if (offset > elements.size()) { throw new IllegalArgumentException("Offset is greater than the number of path elements"); } // An offset of 0 leaves the path unchanged. if (offset == 0) { return this; } // Return the empty path if the parent has zero elements. if (elements.size() == offset) { return emptyPath(); } LinkedList> celements = new LinkedList>(elements.subList(0, elements.size() - offset)); return create(celements, celements.getLast()); } /** * Creates a new managed object path which has the same structure as this * path except that the final path element is renamed. The final path * element must comprise of an instantiable relation. * * @param newName * The new name of the final path element. * @return Returns a new managed object path which has the same structure as * this path except that the final path element is renamed. * @throws IllegalStateException * If this managed object path is empty or if its final path * element does not comprise of an instantiable relation. */ public ManagedObjectPath rename(String newName) { if (elements.size() == 0) { throw new IllegalStateException("Cannot rename an empty path"); } if (r instanceof InstantiableRelationDefinition) { InstantiableRelationDefinition ir = (InstantiableRelationDefinition) r; return parent().child(ir, d, newName); } else { throw new IllegalStateException("Not an instantiable relation"); } } /** * Serialize this managed object path using the provided serialization * strategy. *

* The path elements will be passed to the serializer in big-endian order: * starting from the root element and proceeding down to the leaf. * * @param serializer * The managed object path serialization strategy. */ public void serialize(ManagedObjectPathSerializer serializer) { for (Element element : elements) { element.serialize(serializer); } } /** * Get the number of path elements in this managed object path. * * @return Returns the number of path elements (0 - means no offset, 1 means * the parent, and 2 means the grand-parent). */ public int size() { return elements.size(); } /** * Creates a DN representation of this managed object path. * * @return Returns a DN representation of this managed object path. */ public DN toDN() { // Use a simple serializer to create the contents. DNSerializer serializer = new DNSerializer(); serialize(serializer); return serializer.toDN(); } /** * {@inheritDoc} */ @Override public String toString() { StringBuilder builder = new StringBuilder(); toString(builder); return builder.toString(); } /** * Appends a string representation of this managed object path to the * provided string builder. * * @param builder * Append the string representation to this builder. * @see #toString() */ public void toString(final StringBuilder builder) { if (isEmpty()) { // Special treatment of root configuration paths. builder.append('/'); } else { // Use a simple serializer to create the contents. ManagedObjectPathSerializer serializer = new StringSerializer(builder); serialize(serializer); } } }