aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.xml.internal.ws.policy.sourcemodel; aoqi@0: aoqi@0: import com.sun.xml.internal.ws.policy.privateutil.LocalizationMessages; aoqi@0: import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger; aoqi@0: import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils; aoqi@0: import com.sun.xml.internal.ws.policy.sourcemodel.wspolicy.XmlToken; aoqi@0: aoqi@0: import java.util.Collection; aoqi@0: import java.util.Collections; aoqi@0: import java.util.Iterator; aoqi@0: import java.util.LinkedList; aoqi@0: aoqi@0: /** aoqi@0: * The general representation of a single node within a {@link com.sun.xml.internal.ws.policy.sourcemodel.PolicySourceModel} instance. aoqi@0: * The model node is created via factory methods of the {@link com.sun.xml.internal.ws.policy.sourcemodel.PolicySourceModel} instance. aoqi@0: * It may also hold {@link com.sun.xml.internal.ws.policy.sourcemodel.AssertionData} instance in case its type is {@code ModelNode.Type.ASSERTION}. aoqi@0: * aoqi@0: * @author Marek Potociar aoqi@0: */ aoqi@0: public final class ModelNode implements Iterable, Cloneable { aoqi@0: private static final PolicyLogger LOGGER = PolicyLogger.getLogger(ModelNode.class); aoqi@0: aoqi@0: /** aoqi@0: * Policy source model node type enumeration aoqi@0: */ aoqi@0: public static enum Type { aoqi@0: POLICY(XmlToken.Policy), aoqi@0: ALL(XmlToken.All), aoqi@0: EXACTLY_ONE(XmlToken.ExactlyOne), aoqi@0: POLICY_REFERENCE(XmlToken.PolicyReference), aoqi@0: ASSERTION(XmlToken.UNKNOWN), aoqi@0: ASSERTION_PARAMETER_NODE(XmlToken.UNKNOWN); aoqi@0: aoqi@0: private XmlToken token; aoqi@0: aoqi@0: Type(XmlToken token) { aoqi@0: this.token = token; aoqi@0: } aoqi@0: aoqi@0: public XmlToken getXmlToken() { aoqi@0: return token; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Method checks the PSM state machine if the creation of new child of given type is plausible for a node element aoqi@0: * with type set to this type instance. aoqi@0: * aoqi@0: * @param childType The type. aoqi@0: * @return True if the type is supported, false otherwise aoqi@0: */ aoqi@0: private boolean isChildTypeSupported(final Type childType) { aoqi@0: switch (this) { aoqi@0: case POLICY: aoqi@0: case ALL: aoqi@0: case EXACTLY_ONE: aoqi@0: switch (childType) { aoqi@0: case ASSERTION_PARAMETER_NODE: aoqi@0: return false; aoqi@0: default: aoqi@0: return true; aoqi@0: } aoqi@0: case POLICY_REFERENCE: aoqi@0: return false; aoqi@0: case ASSERTION: aoqi@0: switch (childType) { aoqi@0: case POLICY: aoqi@0: case POLICY_REFERENCE: aoqi@0: case ASSERTION_PARAMETER_NODE: aoqi@0: return true; aoqi@0: default: aoqi@0: return false; aoqi@0: } aoqi@0: case ASSERTION_PARAMETER_NODE: aoqi@0: switch (childType) { aoqi@0: case ASSERTION_PARAMETER_NODE: aoqi@0: return true; aoqi@0: default: aoqi@0: return false; aoqi@0: } aoqi@0: default: aoqi@0: throw LOGGER.logSevereException(new IllegalStateException( aoqi@0: LocalizationMessages.WSP_0060_POLICY_ELEMENT_TYPE_UNKNOWN(this))); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: // comon model node attributes aoqi@0: private LinkedList children; aoqi@0: private Collection unmodifiableViewOnContent; aoqi@0: private final ModelNode.Type type; aoqi@0: private ModelNode parentNode; aoqi@0: private PolicySourceModel parentModel; aoqi@0: aoqi@0: // attributes used only in 'POLICY_REFERENCE' model node aoqi@0: private PolicyReferenceData referenceData; aoqi@0: private PolicySourceModel referencedModel; aoqi@0: aoqi@0: // attibutes used only in 'ASSERTION' or 'ASSERTION_PARAMETER_NODE' model node aoqi@0: private AssertionData nodeData; aoqi@0: aoqi@0: /** aoqi@0: * The factory method creates and initializes the POLICY model node and sets it's parent model reference to point to aoqi@0: * the model supplied as an input parameter. This method is intended to be used ONLY from {@link PolicySourceModel} during aoqi@0: * the initialization of its own internal structures. aoqi@0: * aoqi@0: * @param model policy source model to be used as a parent model of the newly created {@link ModelNode}. Must not be {@code null} aoqi@0: * @return POLICY model node with the parent model reference initialized to the model supplied as an input parameter aoqi@0: * @throws IllegalArgumentException if the {@code model} input parameter is {@code null} aoqi@0: */ aoqi@0: static ModelNode createRootPolicyNode(final PolicySourceModel model) throws IllegalArgumentException { aoqi@0: if (model == null) { aoqi@0: throw LOGGER.logSevereException(new IllegalArgumentException(LocalizationMessages.WSP_0039_POLICY_SRC_MODEL_INPUT_PARAMETER_MUST_NOT_BE_NULL())); aoqi@0: } aoqi@0: return new ModelNode(ModelNode.Type.POLICY, model); aoqi@0: } aoqi@0: aoqi@0: private ModelNode(Type type, PolicySourceModel parentModel) { aoqi@0: this.type = type; aoqi@0: this.parentModel = parentModel; aoqi@0: this.children = new LinkedList(); aoqi@0: this.unmodifiableViewOnContent = Collections.unmodifiableCollection(this.children); aoqi@0: } aoqi@0: aoqi@0: private ModelNode(Type type, PolicySourceModel parentModel, AssertionData data) { aoqi@0: this(type, parentModel); aoqi@0: aoqi@0: this.nodeData = data; aoqi@0: } aoqi@0: aoqi@0: private ModelNode(PolicySourceModel parentModel, PolicyReferenceData data) { aoqi@0: this(Type.POLICY_REFERENCE, parentModel); aoqi@0: aoqi@0: this.referenceData = data; aoqi@0: } aoqi@0: aoqi@0: private void checkCreateChildOperationSupportForType(final Type type) throws UnsupportedOperationException { aoqi@0: if (!this.type.isChildTypeSupported(type)) { aoqi@0: throw LOGGER.logSevereException(new UnsupportedOperationException(LocalizationMessages.WSP_0073_CREATE_CHILD_NODE_OPERATION_NOT_SUPPORTED(type, this.type))); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Factory method that creates new policy source model node as specified by a factory method name and input parameters. aoqi@0: * Each node is created with respect to its enclosing policy source model. aoqi@0: * aoqi@0: * @return A new Policy node. aoqi@0: */ aoqi@0: public ModelNode createChildPolicyNode() { aoqi@0: checkCreateChildOperationSupportForType(Type.POLICY); aoqi@0: aoqi@0: final ModelNode node = new ModelNode(ModelNode.Type.POLICY, parentModel); aoqi@0: this.addChild(node); aoqi@0: aoqi@0: return node; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Factory method that creates new policy source model node as specified by a factory method name and input parameters. aoqi@0: * Each node is created with respect to its enclosing policy source model. aoqi@0: * aoqi@0: * @return A new All node. aoqi@0: */ aoqi@0: public ModelNode createChildAllNode() { aoqi@0: checkCreateChildOperationSupportForType(Type.ALL); aoqi@0: aoqi@0: final ModelNode node = new ModelNode(ModelNode.Type.ALL, parentModel); aoqi@0: this.addChild(node); aoqi@0: aoqi@0: return node; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Factory method that creates new policy source model node as specified by a factory method name and input parameters. aoqi@0: * Each node is created with respect to its enclosing policy source model. aoqi@0: * aoqi@0: * @return A new ExactlyOne node. aoqi@0: */ aoqi@0: public ModelNode createChildExactlyOneNode() { aoqi@0: checkCreateChildOperationSupportForType(Type.EXACTLY_ONE); aoqi@0: aoqi@0: final ModelNode node = new ModelNode(ModelNode.Type.EXACTLY_ONE, parentModel); aoqi@0: this.addChild(node); aoqi@0: aoqi@0: return node; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Factory method that creates new policy source model node as specified by a factory method name and input parameters. aoqi@0: * Each node is created with respect to its enclosing policy source model. aoqi@0: * aoqi@0: * @return A new policy assertion node. aoqi@0: */ aoqi@0: public ModelNode createChildAssertionNode() { aoqi@0: checkCreateChildOperationSupportForType(Type.ASSERTION); aoqi@0: aoqi@0: final ModelNode node = new ModelNode(ModelNode.Type.ASSERTION, parentModel); aoqi@0: this.addChild(node); aoqi@0: aoqi@0: return node; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Factory method that creates new policy source model node as specified by a factory method name and input parameters. aoqi@0: * Each node is created with respect to its enclosing policy source model. aoqi@0: * aoqi@0: * @param nodeData The policy assertion data. aoqi@0: * @return A new policy assertion node. aoqi@0: */ aoqi@0: public ModelNode createChildAssertionNode(final AssertionData nodeData) { aoqi@0: checkCreateChildOperationSupportForType(Type.ASSERTION); aoqi@0: aoqi@0: final ModelNode node = new ModelNode(Type.ASSERTION, parentModel, nodeData); aoqi@0: this.addChild(node); aoqi@0: aoqi@0: return node; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Factory method that creates new policy source model node as specified by a factory method name and input parameters. aoqi@0: * Each node is created with respect to its enclosing policy source model. aoqi@0: * aoqi@0: * @return A new assertion parameter node. aoqi@0: */ aoqi@0: public ModelNode createChildAssertionParameterNode() { aoqi@0: checkCreateChildOperationSupportForType(Type.ASSERTION_PARAMETER_NODE); aoqi@0: aoqi@0: final ModelNode node = new ModelNode(ModelNode.Type.ASSERTION_PARAMETER_NODE, parentModel); aoqi@0: this.addChild(node); aoqi@0: aoqi@0: return node; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Factory method that creates new policy source model node as specified by a factory method name and input parameters. aoqi@0: * Each node is created with respect to its enclosing policy source model. aoqi@0: * aoqi@0: * @param nodeData The assertion parameter data. aoqi@0: * @return A new assertion parameter node. aoqi@0: */ aoqi@0: ModelNode createChildAssertionParameterNode(final AssertionData nodeData) { aoqi@0: checkCreateChildOperationSupportForType(Type.ASSERTION_PARAMETER_NODE); aoqi@0: aoqi@0: final ModelNode node = new ModelNode(Type.ASSERTION_PARAMETER_NODE, parentModel, nodeData); aoqi@0: this.addChild(node); aoqi@0: aoqi@0: return node; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Factory method that creates new policy source model node as specified by a factory method name and input parameters. aoqi@0: * Each node is created with respect to its enclosing policy source model. aoqi@0: * aoqi@0: * @param referenceData The PolicyReference data. aoqi@0: * @return A new PolicyReference node. aoqi@0: */ aoqi@0: ModelNode createChildPolicyReferenceNode(final PolicyReferenceData referenceData) { aoqi@0: checkCreateChildOperationSupportForType(Type.POLICY_REFERENCE); aoqi@0: aoqi@0: final ModelNode node = new ModelNode(parentModel, referenceData); aoqi@0: this.parentModel.addNewPolicyReference(node); aoqi@0: this.addChild(node); aoqi@0: aoqi@0: return node; aoqi@0: } aoqi@0: aoqi@0: Collection getChildren() { aoqi@0: return unmodifiableViewOnContent; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Sets the parent model reference on the node and its children. The method may be invoked only on the root node aoqi@0: * of the policy source model (or - in general - on a model node that dose not reference a parent node). Otherwise an aoqi@0: * exception is thrown. aoqi@0: * aoqi@0: * @param model new parent policy source model to be set. aoqi@0: * @throws IllegalAccessException in case this node references a parent node (i.e. is not a root node of the model). aoqi@0: */ aoqi@0: void setParentModel(final PolicySourceModel model) throws IllegalAccessException { aoqi@0: if (parentNode != null) { aoqi@0: throw LOGGER.logSevereException(new IllegalAccessException(LocalizationMessages.WSP_0049_PARENT_MODEL_CAN_NOT_BE_CHANGED())); aoqi@0: } aoqi@0: aoqi@0: this.updateParentModelReference(model); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * The method updates the parentModel reference on current model node instance and all of it's children aoqi@0: * aoqi@0: * @param model new policy source model reference. aoqi@0: */ aoqi@0: private void updateParentModelReference(final PolicySourceModel model) { aoqi@0: this.parentModel = model; aoqi@0: aoqi@0: for (ModelNode child : children) { aoqi@0: child.updateParentModelReference(model); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Returns the parent policy source model that contains this model node. aoqi@0: * aoqi@0: * @return the parent policy source model aoqi@0: */ aoqi@0: public PolicySourceModel getParentModel() { aoqi@0: return parentModel; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Returns the type of this policy source model node. aoqi@0: * aoqi@0: * @return actual type of this policy source model node aoqi@0: */ aoqi@0: public ModelNode.Type getType() { aoqi@0: return type; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Returns the parent referenced by this policy source model node. aoqi@0: * aoqi@0: * @return current parent of this policy source model node or {@code null} if the node does not have a parent currently. aoqi@0: */ aoqi@0: public ModelNode getParentNode() { aoqi@0: return parentNode; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Returns the data for this policy source model node (if any). The model node data are expected to be not {@code null} only in aoqi@0: * case the type of this node is ASSERTION or ASSERTION_PARAMETER_NODE. aoqi@0: * aoqi@0: * @return the data of this policy source model node or {@code null} if the node does not have any data associated to it aoqi@0: * attached. aoqi@0: */ aoqi@0: public AssertionData getNodeData() { aoqi@0: return nodeData; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Returns the policy reference data for this policy source model node. The policy reference data are expected to be not {@code null} only in aoqi@0: * case the type of this node is POLICY_REFERENCE. aoqi@0: * aoqi@0: * @return the policy reference data for this policy source model node or {@code null} if the node does not have any policy reference data aoqi@0: * attached. aoqi@0: */ aoqi@0: PolicyReferenceData getPolicyReferenceData() { aoqi@0: return referenceData; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * The method may be used to set or replace assertion data set for this node. If there are assertion data set already, aoqi@0: * those are replaced by a new reference and eventualy returned from the method. aoqi@0: *

aoqi@0: * This method is supported only in case this model node instance's type is {@code ASSERTION} or {@code ASSERTION_PARAMETER_NODE}. aoqi@0: * If used from other node types, an exception is thrown. aoqi@0: * aoqi@0: * @param newData new assertion data to be set. aoqi@0: * @return old and replaced assertion data if any or {@code null} otherwise. aoqi@0: * aoqi@0: * @throws UnsupportedOperationException in case this method is called on nodes of type other than {@code ASSERTION} aoqi@0: * or {@code ASSERTION_PARAMETER_NODE} aoqi@0: */ aoqi@0: public AssertionData setOrReplaceNodeData(final AssertionData newData) { aoqi@0: if (!isDomainSpecific()) { aoqi@0: throw LOGGER.logSevereException(new UnsupportedOperationException(LocalizationMessages.WSP_0051_OPERATION_NOT_SUPPORTED_FOR_THIS_BUT_ASSERTION_RELATED_NODE_TYPE(type))); aoqi@0: } aoqi@0: aoqi@0: final AssertionData oldData = this.nodeData; aoqi@0: this.nodeData = newData; aoqi@0: aoqi@0: return oldData; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * The method specifies whether the model node instance represents assertion related node, it means whether its type aoqi@0: * is 'ASSERTION' or 'ASSERTION_PARAMETER_NODE'. This is, for example, the way to determine whether the node supports aoqi@0: * setting a {@link AssertionData} object via {@link #setOrReplaceNodeData(AssertionData)} method or not. aoqi@0: * aoqi@0: * @return {@code true} or {@code false} according to whether the node instance represents assertion related node or not. aoqi@0: */ aoqi@0: boolean isDomainSpecific() { aoqi@0: return type == Type.ASSERTION || type == Type.ASSERTION_PARAMETER_NODE; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Appends the specified child node to the end of the children list of this node and sets it's parent to reference aoqi@0: * this node. aoqi@0: * aoqi@0: * @param child node to be appended to the children list of this node. aoqi@0: * @return {@code true} (as per the general contract of the {@code Collection.add} method). aoqi@0: * aoqi@0: * @throws NullPointerException if the specified node is {@code null}. aoqi@0: * @throws IllegalArgumentException if child has a parent node set already to point to some node aoqi@0: */ aoqi@0: private boolean addChild(final ModelNode child) { aoqi@0: children.add(child); aoqi@0: child.parentNode = this; aoqi@0: aoqi@0: return true; aoqi@0: } aoqi@0: aoqi@0: void setReferencedModel(final PolicySourceModel model) { aoqi@0: if (this.type != Type.POLICY_REFERENCE) { aoqi@0: throw LOGGER.logSevereException(new UnsupportedOperationException(LocalizationMessages.WSP_0050_OPERATION_NOT_SUPPORTED_FOR_THIS_BUT_POLICY_REFERENCE_NODE_TYPE(type))); aoqi@0: } aoqi@0: aoqi@0: referencedModel = model; aoqi@0: } aoqi@0: aoqi@0: PolicySourceModel getReferencedModel() { aoqi@0: return referencedModel; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Returns the number of child policy source model nodes. If this model node contains aoqi@0: * more than {@code Integer.MAX_VALUE} children, returns {@code Integer.MAX_VALUE}. aoqi@0: * aoqi@0: * @return the number of children of this node. aoqi@0: */ aoqi@0: public int childrenSize() { aoqi@0: return children.size(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Returns true if the node has at least one child node. aoqi@0: * aoqi@0: * @return true if the node has at least one child node, false otherwise. aoqi@0: */ aoqi@0: public boolean hasChildren() { aoqi@0: return !children.isEmpty(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Iterates through all child nodes. aoqi@0: * aoqi@0: * @return An iterator for the child nodes aoqi@0: */ aoqi@0: public Iterator iterator() { aoqi@0: return children.iterator(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * An {@code Object.equals(Object obj)} method override. Method ignores the parent source model. It means that two aoqi@0: * model nodes may be the same even if they belong to different models. aoqi@0: *

aoqi@0: * If parent model comparison is desired, it must be accomplished separately. To perform that, the reference equality aoqi@0: * test is sufficient ({@code nodeA.getParentModel() == nodeB.getParentModel()}), since all model nodes are created aoqi@0: * for specific model instances. aoqi@0: */ aoqi@0: @Override aoqi@0: public boolean equals(final Object obj) { aoqi@0: if (this == obj) { aoqi@0: return true; aoqi@0: } aoqi@0: aoqi@0: if (!(obj instanceof ModelNode)) { aoqi@0: return false; aoqi@0: } aoqi@0: aoqi@0: boolean result = true; aoqi@0: final ModelNode that = (ModelNode) obj; aoqi@0: aoqi@0: result = result && this.type.equals(that.type); aoqi@0: // result = result && ((this.parentNode == null) ? that.parentNode == null : this.parentNode.equals(that.parentNode)); aoqi@0: result = result && ((this.nodeData == null) ? that.nodeData == null : this.nodeData.equals(that.nodeData)); aoqi@0: result = result && ((this.children == null) ? that.children == null : this.children.equals(that.children)); aoqi@0: aoqi@0: return result; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * An {@code Object.hashCode()} method override. aoqi@0: */ aoqi@0: @Override aoqi@0: public int hashCode() { aoqi@0: int result = 17; aoqi@0: aoqi@0: result = 37 * result + this.type.hashCode(); aoqi@0: result = 37 * result + ((this.parentNode == null) ? 0 : this.parentNode.hashCode()); aoqi@0: result = 37 * result + ((this.nodeData == null) ? 0 : this.nodeData.hashCode()); aoqi@0: result = 37 * result + this.children.hashCode(); aoqi@0: aoqi@0: return result; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Returns a string representation of the object. In general, the toString method aoqi@0: * returns a string that "textually represents" this object. aoqi@0: * aoqi@0: * @return a string representation of the object. aoqi@0: */ aoqi@0: @Override aoqi@0: public String toString() { aoqi@0: return toString(0, new StringBuffer()).toString(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * A helper method that appends indented string representation of this instance to the input string buffer. aoqi@0: * aoqi@0: * @param indentLevel indentation level to be used. aoqi@0: * @param buffer buffer to be used for appending string representation of this instance aoqi@0: * @return modified buffer containing new string representation of the instance aoqi@0: */ aoqi@0: public StringBuffer toString(final int indentLevel, final StringBuffer buffer) { aoqi@0: final String indent = PolicyUtils.Text.createIndent(indentLevel); aoqi@0: final String innerIndent = PolicyUtils.Text.createIndent(indentLevel + 1); aoqi@0: aoqi@0: buffer.append(indent).append(type).append(" {").append(PolicyUtils.Text.NEW_LINE); aoqi@0: if (type == Type.ASSERTION) { aoqi@0: if (nodeData == null) { aoqi@0: buffer.append(innerIndent).append("no assertion data set"); aoqi@0: } else { aoqi@0: nodeData.toString(indentLevel + 1, buffer); aoqi@0: } aoqi@0: buffer.append(PolicyUtils.Text.NEW_LINE); aoqi@0: } else if (type == Type.POLICY_REFERENCE) { aoqi@0: if (referenceData == null) { aoqi@0: buffer.append(innerIndent).append("no policy reference data set"); aoqi@0: } else { aoqi@0: referenceData.toString(indentLevel + 1, buffer); aoqi@0: } aoqi@0: buffer.append(PolicyUtils.Text.NEW_LINE); aoqi@0: } else if (type == Type.ASSERTION_PARAMETER_NODE) { aoqi@0: if (nodeData == null) { aoqi@0: buffer.append(innerIndent).append("no parameter data set"); aoqi@0: } aoqi@0: else { aoqi@0: nodeData.toString(indentLevel + 1, buffer); aoqi@0: } aoqi@0: buffer.append(PolicyUtils.Text.NEW_LINE); aoqi@0: } aoqi@0: aoqi@0: if (children.size() > 0) { aoqi@0: for (ModelNode child : children) { aoqi@0: child.toString(indentLevel + 1, buffer).append(PolicyUtils.Text.NEW_LINE); aoqi@0: } aoqi@0: } else { aoqi@0: buffer.append(innerIndent).append("no child nodes").append(PolicyUtils.Text.NEW_LINE); aoqi@0: } aoqi@0: aoqi@0: buffer.append(indent).append('}'); aoqi@0: return buffer; aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: protected ModelNode clone() throws CloneNotSupportedException { aoqi@0: final ModelNode clone = (ModelNode) super.clone(); aoqi@0: aoqi@0: if (this.nodeData != null) { aoqi@0: clone.nodeData = this.nodeData.clone(); aoqi@0: } aoqi@0: aoqi@0: // no need to clone PolicyReferenceData, since those are immutable aoqi@0: aoqi@0: if (this.referencedModel != null) { aoqi@0: clone.referencedModel = this.referencedModel.clone(); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: clone.children = new LinkedList(); aoqi@0: clone.unmodifiableViewOnContent = Collections.unmodifiableCollection(clone.children); aoqi@0: aoqi@0: for (ModelNode thisChild : this.children) { aoqi@0: clone.addChild(thisChild.clone()); aoqi@0: } aoqi@0: aoqi@0: return clone; aoqi@0: } aoqi@0: aoqi@0: PolicyReferenceData getReferenceData() { aoqi@0: return referenceData; aoqi@0: } aoqi@0: }