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.PolicyConstants; 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: aoqi@0: import java.io.Serializable; aoqi@0: import java.util.HashMap; aoqi@0: import java.util.HashSet; aoqi@0: import java.util.Map; aoqi@0: import java.util.Set; aoqi@0: import javax.xml.namespace.QName; aoqi@0: aoqi@0: /** aoqi@0: * Wrapper class for possible data that each "assertion" and "assertion parameter content" policy source model node may aoqi@0: * have attached. aoqi@0: *

aoqi@0: * This data, when stored in an 'assertion' model node, is intended to be used as input parameter when creating aoqi@0: * {@link com.sun.xml.internal.ws.policy.PolicyAssertion} objects via {@link com.sun.xml.internal.ws.policy.spi.PolicyAssertionCreator} aoqi@0: * implementations. aoqi@0: * aoqi@0: * @author Marek Potociar (marek.potociar@sun.com) aoqi@0: * @author Fabian Ritzmann aoqi@0: */ aoqi@0: public final class AssertionData implements Cloneable, Serializable { aoqi@0: private static final long serialVersionUID = 4416256070795526315L; aoqi@0: private static final PolicyLogger LOGGER = PolicyLogger.getLogger(AssertionData.class); aoqi@0: aoqi@0: private final QName name; aoqi@0: private final String value; aoqi@0: private final Map attributes; aoqi@0: private ModelNode.Type type; aoqi@0: aoqi@0: private boolean optional; aoqi@0: private boolean ignorable; aoqi@0: aoqi@0: /** aoqi@0: * Constructs assertion data wrapper instance for an assertion that does not aoqi@0: * contain any value nor any attributes. aoqi@0: * aoqi@0: * @param name the FQN of the assertion aoqi@0: * aoqi@0: * @throws IllegalArgumentException in case the {@code type} parameter is not aoqi@0: * {@link ModelNode.Type#ASSERTION ASSERTION} or aoqi@0: * {@link ModelNode.Type#ASSERTION_PARAMETER_NODE ASSERTION_PARAMETER_NODE} aoqi@0: */ aoqi@0: public static AssertionData createAssertionData(final QName name) throws IllegalArgumentException { aoqi@0: return new AssertionData(name, null, null, ModelNode.Type.ASSERTION, false, false); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Constructs assertion data wrapper instance for an assertion parameter that aoqi@0: * does not contain any value nor any attributes. aoqi@0: * aoqi@0: * @param name the FQN of the assertion parameter aoqi@0: * aoqi@0: * @throws IllegalArgumentException in case the {@code type} parameter is not aoqi@0: * {@link ModelNode.Type#ASSERTION ASSERTION} or aoqi@0: * {@link ModelNode.Type#ASSERTION_PARAMETER_NODE ASSERTION_PARAMETER_NODE} aoqi@0: */ aoqi@0: public static AssertionData createAssertionParameterData(final QName name) throws IllegalArgumentException { aoqi@0: return new AssertionData(name, null, null, ModelNode.Type.ASSERTION_PARAMETER_NODE, false, false); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Constructs assertion data wrapper instance for an assertion that does aoqi@0: * contain a value or attributes. aoqi@0: * aoqi@0: * @param name the FQN of the assertion aoqi@0: * @param value a {@link String} representation of model node value aoqi@0: * @param attributes map of model node's <attribute name, attribute value> pairs aoqi@0: * @param optional flag indicating whether the assertion is optional or not aoqi@0: * @param ignorable flag indicating whether the assertion is ignorable or not aoqi@0: * aoqi@0: * @throws IllegalArgumentException in case the {@code type} parameter is not aoqi@0: * {@link ModelNode.Type#ASSERTION ASSERTION} or aoqi@0: * {@link ModelNode.Type#ASSERTION_PARAMETER_NODE ASSERTION_PARAMETER_NODE} aoqi@0: */ aoqi@0: public static AssertionData createAssertionData(final QName name, final String value, final Map attributes, boolean optional, boolean ignorable) throws IllegalArgumentException { aoqi@0: return new AssertionData(name, value, attributes, ModelNode.Type.ASSERTION, optional, ignorable); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Constructs assertion data wrapper instance for an assertion parameter that aoqi@0: * contains a value or attributes aoqi@0: * aoqi@0: * @param name the FQN of the assertion parameter aoqi@0: * @param value a {@link String} representation of model node value aoqi@0: * @param attributes map of model node's <attribute name, attribute value> pairs aoqi@0: * aoqi@0: * @throws IllegalArgumentException in case the {@code type} parameter is not aoqi@0: * {@link ModelNode.Type#ASSERTION ASSERTION} or aoqi@0: * {@link ModelNode.Type#ASSERTION_PARAMETER_NODE ASSERTION_PARAMETER_NODE} aoqi@0: */ aoqi@0: public static AssertionData createAssertionParameterData(final QName name, final String value, final Map attributes) throws IllegalArgumentException { aoqi@0: return new AssertionData(name, value, attributes, ModelNode.Type.ASSERTION_PARAMETER_NODE, false, false); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Constructs assertion data wrapper instance for an assertion or assertion parameter that contains a value or aoqi@0: * some attributes. Whether the data wrapper is constructed for assertion or assertion parameter node is distinguished by aoqi@0: * the supplied {@code type} parameter. aoqi@0: * aoqi@0: * @param name the FQN of the assertion or assertion parameter aoqi@0: * @param value a {@link String} representation of model node value aoqi@0: * @param attributes map of model node's <attribute name, attribute value> pairs aoqi@0: * @param type specifies whether the data will belong to the assertion or assertion parameter node. This is aoqi@0: * a workaround solution that allows us to transfer this information about the owner node to aoqi@0: * a policy assertion instance factory without actualy having to touch the {@link PolicyAssertionCreator} aoqi@0: * interface and protected {@link PolicyAssertion} constructors. aoqi@0: * aoqi@0: * @throws IllegalArgumentException in case the {@code type} parameter is not aoqi@0: * {@link ModelNode.Type#ASSERTION ASSERTION} or aoqi@0: * {@link ModelNode.Type#ASSERTION_PARAMETER_NODE ASSERTION_PARAMETER_NODE} aoqi@0: */ aoqi@0: AssertionData(QName name, String value, Map attributes, ModelNode.Type type, boolean optional, boolean ignorable) throws IllegalArgumentException { aoqi@0: this.name = name; aoqi@0: this.value = value; aoqi@0: this.optional = optional; aoqi@0: this.ignorable = ignorable; aoqi@0: aoqi@0: this.attributes = new HashMap(); aoqi@0: if (attributes != null && !attributes.isEmpty()) { aoqi@0: this.attributes.putAll(attributes); aoqi@0: } aoqi@0: setModelNodeType(type); aoqi@0: } aoqi@0: aoqi@0: private void setModelNodeType(final ModelNode.Type type) throws IllegalArgumentException { aoqi@0: if (type == ModelNode.Type.ASSERTION || type == ModelNode.Type.ASSERTION_PARAMETER_NODE) { aoqi@0: this.type = type; aoqi@0: } else { aoqi@0: throw LOGGER.logSevereException(new IllegalArgumentException( aoqi@0: LocalizationMessages.WSP_0074_CANNOT_CREATE_ASSERTION_BAD_TYPE(type, ModelNode.Type.ASSERTION, ModelNode.Type.ASSERTION_PARAMETER_NODE))); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Copy constructor. aoqi@0: * aoqi@0: * @param data The instance that is to be copied. aoqi@0: */ aoqi@0: AssertionData(final AssertionData data) { aoqi@0: this.name = data.name; aoqi@0: this.value = data.value; aoqi@0: this.attributes = new HashMap(); aoqi@0: if (!data.attributes.isEmpty()) { aoqi@0: this.attributes.putAll(data.attributes); aoqi@0: } aoqi@0: this.type = data.type; aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: protected AssertionData clone() throws CloneNotSupportedException { aoqi@0: return (AssertionData) super.clone(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Returns true if the given attribute exists, false otherwise. aoqi@0: * aoqi@0: * @param name The name of the attribute. Must not be null. aoqi@0: * @return True if the given attribute exists, false otherwise. aoqi@0: */ aoqi@0: public boolean containsAttribute(final QName name) { aoqi@0: synchronized (attributes) { aoqi@0: return attributes.containsKey(name); aoqi@0: } aoqi@0: } aoqi@0: 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 AssertionData)) { aoqi@0: return false; aoqi@0: } aoqi@0: aoqi@0: boolean result = true; aoqi@0: final AssertionData that = (AssertionData) obj; aoqi@0: aoqi@0: result = result && this.name.equals(that.name); aoqi@0: result = result && ((this.value == null) ? that.value == null : this.value.equals(that.value)); aoqi@0: synchronized (attributes) { aoqi@0: result = result && this.attributes.equals(that.attributes); aoqi@0: } aoqi@0: aoqi@0: return result; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Returns the value of the given attribute. Returns null if the attribute aoqi@0: * does not exist. aoqi@0: * aoqi@0: * @param name The name of the attribute. Must not be null. aoqi@0: * @return The value of the given attribute. Returns null if the attribute aoqi@0: * does not exist. aoqi@0: */ aoqi@0: public String getAttributeValue(final QName name) { aoqi@0: synchronized (attributes) { aoqi@0: return attributes.get(name); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Returns the disconnected map of attributes attached to the assertion. aoqi@0: *

aoqi@0: * 'Disconnected' means, that the result of this method will not be synchronized with any consequent assertion's attribute modification. It is aoqi@0: * also important to notice that a manipulation with returned set of attributes will not have any effect on the actual assertion's aoqi@0: * attributes. aoqi@0: * aoqi@0: * @return disconnected map of attributes attached to the assertion. aoqi@0: */ aoqi@0: public Map getAttributes() { aoqi@0: synchronized (attributes) { aoqi@0: return new HashMap(attributes); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Returns the disconnected set of attributes attached to the assertion. Each attribute is represented as a single aoqi@0: * {@code Map.Entry} element. aoqi@0: *

aoqi@0: * 'Disconnected' means, that the result of this method will not be synchronized with any consequent assertion's attribute modification. It is aoqi@0: * also important to notice that a manipulation with returned set of attributes will not have any effect on the actual assertion's aoqi@0: * attributes. aoqi@0: * aoqi@0: * @return disconnected set of attributes attached to the assertion. aoqi@0: */ aoqi@0: public Set> getAttributesSet() { aoqi@0: synchronized (attributes) { aoqi@0: return new HashSet>(attributes.entrySet()); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Returns the name of the assertion. aoqi@0: * aoqi@0: * @return assertion's name aoqi@0: */ aoqi@0: public QName getName() { aoqi@0: return name; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Returns the value of the assertion. aoqi@0: * aoqi@0: * @return assertion's value aoqi@0: */ aoqi@0: public String getValue() { aoqi@0: return value; aoqi@0: } 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.name.hashCode(); aoqi@0: result = 37 * result + ((this.value == null) ? 0 : this.value.hashCode()); aoqi@0: synchronized (attributes) { aoqi@0: result = 37 * result + this.attributes.hashCode(); aoqi@0: } aoqi@0: return result; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Method specifies whether the assertion data contain proprietary visibility element set to "private" value. aoqi@0: * aoqi@0: * @return {@code 'true'} if the attribute is present and set properly (i.e. the node containing this assertion data instance should aoqi@0: * not be marshaled into generated WSDL documents). Returns {@code false} otherwise. aoqi@0: */ aoqi@0: public boolean isPrivateAttributeSet() { aoqi@0: return PolicyConstants.VISIBILITY_VALUE_PRIVATE.equals(getAttributeValue(PolicyConstants.VISIBILITY_ATTRIBUTE)); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Removes the given attribute from the assertion data. aoqi@0: * aoqi@0: * @param name The name of the attribute. Must not be null aoqi@0: * @return The value of the removed attribute. aoqi@0: */ aoqi@0: public String removeAttribute(final QName name) { aoqi@0: synchronized (attributes) { aoqi@0: return attributes.remove(name); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Adds or overwrites an attribute. aoqi@0: * aoqi@0: * @param name The name of the attribute. aoqi@0: * @param value The value of the attribute. aoqi@0: */ aoqi@0: public void setAttribute(final QName name, final String value) { aoqi@0: synchronized (attributes) { aoqi@0: attributes.put(name, value); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Sets the optional attribute. aoqi@0: * aoqi@0: * @param value The value of the optional attribute. aoqi@0: */ aoqi@0: public void setOptionalAttribute(final boolean value) { aoqi@0: optional = value; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Tests if the optional attribute is set. aoqi@0: * aoqi@0: * @return True if optional is set and is true. False otherwise. aoqi@0: */ aoqi@0: public boolean isOptionalAttributeSet() { aoqi@0: return optional; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Sets the ignorable attribute. aoqi@0: * aoqi@0: * @param value The value of the ignorable attribute. aoqi@0: */ aoqi@0: public void setIgnorableAttribute(final boolean value) { aoqi@0: ignorable = value; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Tests if the ignorable attribute is set. aoqi@0: * aoqi@0: * @return True if ignorable is set and is true. False otherwise. aoqi@0: */ aoqi@0: public boolean isIgnorableAttributeSet() { aoqi@0: return ignorable; aoqi@0: } 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: final String innerDoubleIndent = PolicyUtils.Text.createIndent(indentLevel + 2); aoqi@0: aoqi@0: buffer.append(indent); aoqi@0: if (type == ModelNode.Type.ASSERTION) { aoqi@0: buffer.append("assertion data {"); aoqi@0: } else { aoqi@0: buffer.append("assertion parameter data {"); aoqi@0: } aoqi@0: buffer.append(PolicyUtils.Text.NEW_LINE); aoqi@0: aoqi@0: buffer.append(innerIndent).append("namespace = '").append(name.getNamespaceURI()).append('\'').append(PolicyUtils.Text.NEW_LINE); aoqi@0: buffer.append(innerIndent).append("prefix = '").append(name.getPrefix()).append('\'').append(PolicyUtils.Text.NEW_LINE); aoqi@0: buffer.append(innerIndent).append("local name = '").append(name.getLocalPart()).append('\'').append(PolicyUtils.Text.NEW_LINE); aoqi@0: buffer.append(innerIndent).append("value = '").append(value).append('\'').append(PolicyUtils.Text.NEW_LINE); aoqi@0: buffer.append(innerIndent).append("optional = '").append(optional).append('\'').append(PolicyUtils.Text.NEW_LINE); aoqi@0: buffer.append(innerIndent).append("ignorable = '").append(ignorable).append('\'').append(PolicyUtils.Text.NEW_LINE); aoqi@0: synchronized (attributes) { aoqi@0: if (attributes.isEmpty()) { aoqi@0: buffer.append(innerIndent).append("no attributes"); aoqi@0: } else { aoqi@0: aoqi@0: buffer.append(innerIndent).append("attributes {").append(PolicyUtils.Text.NEW_LINE); aoqi@0: for(Map.Entry entry : attributes.entrySet()) { aoqi@0: final QName aName = entry.getKey(); aoqi@0: buffer.append(innerDoubleIndent).append("name = '").append(aName.getNamespaceURI()).append(':').append(aName.getLocalPart()); aoqi@0: buffer.append("', value = '").append(entry.getValue()).append('\'').append(PolicyUtils.Text.NEW_LINE); aoqi@0: } aoqi@0: buffer.append(innerIndent).append('}'); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: buffer.append(PolicyUtils.Text.NEW_LINE).append(indent).append('}'); aoqi@0: aoqi@0: return buffer; aoqi@0: } aoqi@0: aoqi@0: public ModelNode.Type getNodeType() { aoqi@0: return type; aoqi@0: } aoqi@0: aoqi@0: }