/* * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 * * * Portions Copyright 2007 Sun Microsystems, Inc. */ package org.opends.server.admin; import java.util.Collections; import java.util.LinkedList; import java.util.List; import org.opends.server.admin.std.meta.RootCfgDefn; /** * A path which can be used to determine the location of a managed * object instance. */ public final class ManagedObjectPath { /** * Abstract path element. */ private static abstract class Element { /** * Protected constructor. */ protected Element() { // No implementation required. } /** * Get the relation definition associated with this element. * * @return Returns the relation definition associated with this * element. */ public abstract RelationDefinition getRelation(); /** * 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 { // The instantiable relation. private final InstantiableRelationDefinition r; // The name of the managed object. private final String name; // Private constructor. private InstantiableElement( InstantiableRelationDefinition r, String name) { this.r = r; this.name = name; } /** * {@inheritDoc} */ @Override public RelationDefinition getRelation() { return r; } /** * {@inheritDoc} */ @Override public void serialize(ManagedObjectPathSerializer serializer) { serializer.appendManagedObjectPathElement(r, name); } } /** * A path element representing an optional managed object. */ private static final class OptionalElement extends Element { // The optional relation. private final OptionalRelationDefinition r; // Private constructor. private OptionalElement(OptionalRelationDefinition r) { this.r = r; } /** * {@inheritDoc} */ @Override public RelationDefinition getRelation() { return r; } /** * {@inheritDoc} */ @Override public void serialize(ManagedObjectPathSerializer serializer) { serializer.appendManagedObjectPathElement(r); } } /** * A path element representing a singleton managed object. */ private static final class SingletonElement extends Element { // The singleton relation. private final SingletonRelationDefinition r; // Private constructor. private SingletonElement(SingletonRelationDefinition r) { this.r = r; } /** * {@inheritDoc} */ @Override public RelationDefinition getRelation() { return r; } /** * {@inheritDoc} */ @Override public void serialize(ManagedObjectPathSerializer serializer) { serializer.appendManagedObjectPathElement(r); } } // Single instance of a root path. private static final ManagedObjectPath EMPTY_PATH = new ManagedObjectPath( new LinkedList()); /** * 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) throws IllegalArgumentException { return null; } // The list of path elements in this path. private final List elements; // Private constructor. private ManagedObjectPath(LinkedList elements) { this.elements = Collections.unmodifiableList(elements); } /** * Creates a new child managed object path beneath the provided * parent path. * * @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. */ public ManagedObjectPath child( InstantiableRelationDefinition r, String name) { LinkedList celements = new LinkedList(elements); celements.add(new InstantiableElement(r, name)); return new ManagedObjectPath(celements); } /** * Creates a new child managed object path beneath the provided * parent path. * * @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) { LinkedList celements = new LinkedList(elements); celements.add(new OptionalElement(r)); return new ManagedObjectPath(celements); } /** * Creates a new child managed object path beneath the provided * parent path. * * @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) { LinkedList celements = new LinkedList(elements); celements.add(new SingletonElement(r)); return new ManagedObjectPath(celements); } /** * {@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() { if (elements.isEmpty()) { return RootCfgDefn.getInstance(); } else { Element e = elements.get(elements.size() - 1); return e.getRelation().getChildDefinition(); } } /** * {@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(); } /** * 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) throws IllegalArgumentException { 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; } LinkedList celements = new LinkedList(elements .subList(0, elements.size() - offset)); return new ManagedObjectPath(celements); } /** * 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(); } /** * {@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) { // Use a simple serializer to create the contents. ManagedObjectPathSerializer serializer = new ManagedObjectPathSerializer() { public void appendManagedObjectPathElement( InstantiableRelationDefinition r, String name) { builder.append('/'); builder.append(r.getName()); builder.append('/'); builder.append(name); } public void appendManagedObjectPathElement( OptionalRelationDefinition r) { builder.append('/'); builder.append(r.getName()); } public void appendManagedObjectPathElement( SingletonRelationDefinition r) { builder.append('/'); builder.append(r.getName()); } }; serialize(serializer); } }