summaryrefslogtreecommitdiff
path: root/src/com/sun/apoc/spi/cfgtree/property/ReadWritePropertyImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/sun/apoc/spi/cfgtree/property/ReadWritePropertyImpl.java')
-rw-r--r--src/com/sun/apoc/spi/cfgtree/property/ReadWritePropertyImpl.java967
1 files changed, 967 insertions, 0 deletions
diff --git a/src/com/sun/apoc/spi/cfgtree/property/ReadWritePropertyImpl.java b/src/com/sun/apoc/spi/cfgtree/property/ReadWritePropertyImpl.java
new file mode 100644
index 0000000..bd0167c
--- /dev/null
+++ b/src/com/sun/apoc/spi/cfgtree/property/ReadWritePropertyImpl.java
@@ -0,0 +1,967 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either
+ * the GNU General Public License Version 2 only ("GPL") or
+ * the Common Development and Distribution License("CDDL")
+ * (collectively, the "License"). You may not use this file
+ * except in compliance with the License. You can obtain a copy
+ * of the License at www.sun.com/CDDL or at COPYRIGHT. See the
+ * License for the specific language governing permissions and
+ * limitations under the License. When distributing the software,
+ * include this License Header Notice in each file and include
+ * the License file at /legal/license.txt. If applicable, add the
+ * following below the License Header, with the fields enclosed
+ * by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by
+ * only the CDDL or only the GPL Version 2, indicate your
+ * decision by adding "[Contributor] elects to include this
+ * software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice
+ * of license, a recipient has the option to distribute your
+ * version of this file under either the CDDL, the GPL Version
+ * 2 or to extend the choice of license to its licensees as
+ * provided above. However, if you add GPL Version 2 code and
+ * therefore, elected the GPL Version 2 license, then the
+ * option applies only if the new code is made subject to such
+ * option by the copyright holder.
+ */
+
+package com.sun.apoc.spi.cfgtree.property;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+import com.sun.apoc.spi.SPIException;
+import com.sun.apoc.spi.cfgtree.ConfigElementImpl;
+import com.sun.apoc.spi.cfgtree.DataType;
+import com.sun.apoc.spi.cfgtree.InvalidDataTypeException;
+import com.sun.apoc.spi.cfgtree.MandatoryElementException;
+import com.sun.apoc.spi.cfgtree.NodeKey;
+import com.sun.apoc.spi.cfgtree.NodeValueImpl;
+import com.sun.apoc.spi.cfgtree.OperationType;
+import com.sun.apoc.spi.cfgtree.PolicyTree;
+import com.sun.apoc.spi.cfgtree.policynode.PolicyNodeImpl;
+import com.sun.apoc.spi.cfgtree.policynode.ReadWritePolicyNodeImpl;
+import com.sun.apoc.spi.policies.Policy;
+
+/**
+ * Class for a property.
+ *
+ */
+public class ReadWritePropertyImpl extends PropertyImpl {
+ /** Default property */
+ private ReadWritePropertyImpl mDefaultProperty ;
+ private boolean mHasBeenModified = false;
+
+ /**
+ * Creates and adds a default <code>NodeValueImpl</code>.
+ *
+ * @param aOrigin originating layer
+ */
+ public void addDefaultNodeValueImpl(Policy aOrigin) {
+ if (mValues == null) { mValues = new Hashtable(); }
+ NodeValueImpl defaultValue = createDefaultNodeValueImpl();
+ defaultValue.setOrigin(aOrigin);
+ mValues.put(mRequiredLocale, defaultValue);
+ }
+
+ /**
+ * Clears the settings added at this layer.
+ *
+ * @throws <code>SPIException</code> if
+ * error occurs
+ */
+ public void clear() throws SPIException {
+ /* cannot apply reset operation if property
+ is readonly */
+ checkIfReadOnly();
+ ReadWritePropertyImpl defaultProperty = mDefaultProperty;
+ PolicyNodeImpl parent = (PolicyNodeImpl)getParent();
+ if (defaultProperty != null) {
+ setDefaultProperty(defaultProperty);
+ defaultProperty.setOperationType(OperationType.OP_RESET);
+ /* replace the property in the policy tree with
+ the default property. */
+ if (parent.isProtected()) {
+ defaultProperty.setFinalized(true,
+ getNameOfElementWhereProtectionSet(),
+ getOriginOfProtection());
+ parent.addProperty(defaultProperty);
+ }
+ } else {
+ /* we are dealing with a property added at this layer */
+ checkIfMandatory();
+ setOperationType(OperationType.OP_REMOVE);
+ }
+ mHasBeenModified = true;
+ }
+
+ /**
+ * Utility function for copying updated <code>NodeValueImpls</code>
+ * into an existing table of <code>NodeValueImpls</code>.
+ *
+ * @param aUpdateTable the table to be copied
+ * @param aPropertyImpl the property containing the table
+ * to be updated
+ * @param aLayer layer where values originated
+ * @param aIsParentUpdateLayer indicates if this is a parent update
+ * layer (needed for handling
+ * finalized attribute): <code>true</code>
+ * if final layer, otherwise <code>false</code>
+ * @throws <code>SPIException</code> if
+ * error occurs
+ */
+ public void copyUpdateNodeValueImpls(Hashtable aUpdateTable,
+ PropertyImpl aPropertyImpl, Policy aLayer,
+ boolean aIsParentUpdateLayer) throws SPIException {
+ Enumeration keys = aUpdateTable.keys();
+ if (keys != null) {
+ while (keys.hasMoreElements()) {
+ String key = (String)keys.nextElement();
+ NodeValueImpl updatedNodeValueImpl =
+ (NodeValueImpl)aUpdateTable.get(key);
+ if (updatedNodeValueImpl != null) {
+ /* if the property node is not nillable, then
+ ensure that don't copy a nil NodeValueImpl */
+ if (!aPropertyImpl.isNillable() &&
+ updatedNodeValueImpl.hasNilAttribute()) {
+ /* skip this value */
+ } else {
+ NodeValueImpl newNodeValueImpl =
+ updatedNodeValueImpl.copyNodeValueImpl();
+ newNodeValueImpl.setOrigin(aLayer);
+ aPropertyImpl.setNodeValue(newNodeValueImpl, key);
+ newNodeValueImpl.setPropertyImpl(aPropertyImpl);
+ if (!aIsParentUpdateLayer) {
+ newNodeValueImpl.setModifiedAtTopLayer();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Deletes this property if it is dynamic.
+ *
+ * @throws <code>SPIException</code>
+ * if error occurs
+ */
+ public void delete () throws SPIException {
+ /* if this property is marked readonly then it cannot
+ be removed */
+ checkIfReadOnly();
+ /* only properties that have been added in the current
+ layer may be removed */
+ if (! ((PropertyImpl)this).isAddedAtTopLayer()) {
+ throw new MandatoryElementException(
+ "Property", getName(),
+ MandatoryElementException.REMOVE_MANDATORY_KEY);
+ }
+ /* set the operation attribute to "remove" */
+ setOperationType(OperationType.OP_REMOVE);
+ mHasBeenModified = true;
+ }
+
+ /**
+ * Returns the default property, that is the property as it
+ * was in the default layer.
+ *
+ * @return the default property
+ * @throws <code>SPIException</code> if error occurs
+ */
+ public ReadWritePropertyImpl getDefaultProperty()
+ throws SPIException {
+ return ( (mDefaultProperty != null) ?
+ (ReadWritePropertyImpl)mDefaultProperty.shallowCopy() : null);
+ }
+
+ /**
+ * Returns a boolean indicating if the property has
+ * been modified.
+ *
+ * @return <code>true</code> if the property has been
+ * modified, otherwise <code>false</code>
+ */
+ public boolean hasBeenModified() {
+ return mHasBeenModified;
+ }
+
+
+ /**
+ * Determines from this update operation which operation is to
+ * be carried out during the read merge, and then invokes
+ * the corresponding operation method.
+ *
+ * @param aOutputProperty the equivalent property for the new
+ * update layer
+ * @param aLayer layer to update
+ * @param aUpdateNodePath the path to this update node (used
+ * for exception messages
+ * @return <code>true</code> if this node is
+ * required for the new update layer,
+ * otherwise <code>false</code>
+ * @throws <code>SPIException</code>
+ * if error occurs
+ */
+ public boolean processUpdateOperation(PropertyImpl aOutputProperty,
+ Policy aLayer,
+ String aUpdateNodePath)
+ throws SPIException {
+ boolean update = false;
+ switch (mOperationType) {
+ case OperationType.OP_REPLACE:
+ update = updateReplaceProperty(aOutputProperty, aLayer,
+ aUpdateNodePath);
+ break;
+ case OperationType.OP_REMOVE:
+ update = updateRemoveProperty(aOutputProperty, aLayer,
+ aUpdateNodePath);
+ break;
+ case OperationType.OP_RESET:
+ update = updateResetProperty(aOutputProperty, aLayer,
+ aUpdateNodePath);
+ break;
+ case OperationType.OP_UNKNOWN: //defaults to OP_MODIFY
+ case OperationType.OP_MODIFY:
+ update = updateModifyProperty(aOutputProperty, aLayer,
+ aUpdateNodePath);
+ break;
+ };
+ return update;
+ }
+
+ private String[] getArrayFromListValue(String aValue) {
+ StringTokenizer st = new StringTokenizer(aValue, mSeparator);
+ String [] retCode = new String[st.countTokens()];
+ int i = 0;
+ while (st.hasMoreTokens()) {
+ retCode [i++] = st.nextToken();
+ }
+ return retCode;
+ }
+
+ private String getStringFromArray(String[] aValues) {
+ StringBuffer sBuf = new StringBuffer(PolicyTree.BUFFER_SIZE);
+ for (int i = 0; i < aValues.length - 1; ++i) {
+ sBuf.append(aValues[i]);
+ sBuf.append(mSeparator);
+ }
+ sBuf.append(aValues[aValues.length - 1]);
+ return sBuf.toString();
+ }
+
+ /**
+ * Sets the value.
+ *
+ * @param aValue the value
+ * @param aDataType the type of the data
+ * @throws SPIException if error occurs
+ * @throws InvalidDataTypeException if invalid data type
+ * @throws InvalidPropertyException if invalid value
+ */
+ public void put(String aValue, DataType aDataType) throws SPIException {
+ if (aValue == null) {
+ throw new InvalidPropertyException(
+ InvalidPropertyException.INVALID_VALUE_KEY);
+ }
+ if (mDataType == DataType.UNKNOWN) {
+ mDataType = aDataType;
+ } else if (mDataType != aDataType) {
+ throw new InvalidDataTypeException(
+ mDataType.getStringValue());
+ }
+ getNodeValue().setNewContents(aValue);
+ mHasBeenModified = true;
+ }
+
+ /**
+ * Sets the string value.
+ *
+ * @param aValue the string value
+ * @throws SPIException if error occurs
+ * @throws InvalidDataTypeException if invalid data type
+ */
+ public void putString(String aValue) throws SPIException{
+ put(aValue, DataType.STRING);
+ }
+
+ /**
+ * Sets the hexbinary value as a string.
+ *
+ * @param aValue the hexbinary value
+ * @throws SPIException if error occurs
+ * @throws InvalidDataTypeException if invalid data type
+ */
+ public void putHexBinary(String aValue) throws SPIException{
+ put(aValue, DataType.HEXBIN);
+ }
+
+ /**
+ * Sets the int value.
+ *
+ * @param aValue the int value
+ * @throws SPIException if error occurs
+ * @throws InvalidDataTypeException if invalid data type
+ */
+ public void putInt(int aValue) throws SPIException{
+ put(Integer.toString(aValue), DataType.INT);
+ }
+
+ /**
+ * Sets the double value.
+ *
+ * @param aValue the double value
+ * @throws SPIException if error occurs
+ * @throws InvalidDataTypeException if invalid data type
+ */
+ public void putDouble(double aValue) throws SPIException{
+ put(Double.toString(aValue), DataType.DOUBLE);
+ }
+
+ /**
+ * Sets the short value.
+ *
+ * @param aValue the short value
+ * @throws SPIException if error occurs
+ * @throws InvalidDataTypeException if invalid data type
+ */
+ public void putShort(short aValue) throws SPIException{
+ put(Short.toString(aValue), DataType.SHORT);
+ }
+
+
+ /**
+ * Sets the long value.
+ *
+ * @param aValue the long value
+ * @throws SPIException if error occurs
+ * @throws InvalidDataTypeException if invalid data type
+ */
+ public void putLong(long aValue) throws SPIException{
+ put(Long.toString(aValue), DataType.LONG);
+ }
+
+ /**
+ * Sets the boolean value.
+ *
+ * @param aValue the boolean value
+ * @throws SPIException if error occurs
+ * @throws InvalidDataTypeException if invalid data type
+ */
+ public void putBoolean(boolean aValue) throws SPIException{
+ put(Boolean.toString(aValue), DataType.BOOLEAN);
+ }
+
+ /**
+ * Sets the string list values.
+ *
+ * @param aValues the list of string values
+ * @throws SPIException if error occurs
+ * @throws InvalidDataTypeException if invalid data type
+ * @throws InvalidPropertyException if invalid value
+ */
+ public void putStringList(String[] aValues) throws SPIException{
+ if (aValues == null || aValues.length == 0) {
+ throw new InvalidPropertyException(
+ InvalidPropertyException.INVALID_VALUE_KEY);
+ }
+ put(getStringFromArray(aValues), DataType.STRING_LIST);
+ }
+
+ /**
+ * Sets the hexbinary list values.
+ *
+ * @param aValues the list of hexbinary values
+ * @throws SPIException if error occurs
+ * @throws InvalidDataTypeException if invalid data type
+ */
+ public void putHexBinaryList(String[] aValues) throws SPIException{
+ if (aValues == null || aValues.length == 0) {
+ throw new InvalidPropertyException(
+ InvalidPropertyException.INVALID_VALUE_KEY);
+ }
+ put(getStringFromArray(aValues), DataType.HEXBIN_LIST);
+ }
+
+ /**
+ * Sets the list of int value.
+ *
+ * @param aValues the list of int values
+ * @throws SPIException if error occurs
+ * @throws InvalidDataTypeException if invalid data type
+ * @throws InvalidPropertyException if invalid value
+ */
+ public void putIntList(int[] aValues) throws SPIException{
+ if (aValues == null || aValues.length == 0) {
+ throw new InvalidPropertyException(
+ InvalidPropertyException.INVALID_VALUE_KEY);
+ }
+ StringBuffer sBuf = new StringBuffer(PolicyTree.BUFFER_SIZE);
+ for (int i = 0; i < aValues.length - 1; ++i) {
+ sBuf.append(aValues[i]);
+ sBuf.append(mSeparator);
+ }
+ sBuf.append(aValues[aValues.length - 1]);
+ put(sBuf.toString(), DataType.INT_LIST);
+ }
+
+ /**
+ * Sets the list of double values.
+ *
+ * @param aValue the list of double values
+ * @throws SPIException if error occurs
+ * @throws InvalidDataTypeException if invalid data type
+ * @throws InvalidPropertyException if invalid value
+ */
+ public void putDoubleList(double[] aValues) throws SPIException{
+ if (aValues == null || aValues.length == 0) {
+ throw new InvalidPropertyException(
+ InvalidPropertyException.INVALID_VALUE_KEY);
+ }
+ StringBuffer sBuf = new StringBuffer(PolicyTree.BUFFER_SIZE);
+ for (int i = 0; i < aValues.length - 1; ++i) {
+ sBuf.append(aValues[i]);
+ sBuf.append(mSeparator);
+ }
+ sBuf.append(aValues[aValues.length - 1]);
+ put(sBuf.toString(), DataType.DOUBLE_LIST);
+ }
+
+ /**
+ * Sets the list of short values.
+ *
+ * @param aValue the list of short values
+ * @throws SPIException if error occurs
+ * @throws InvalidDataTypeException if invalid data type
+ * @throws InvalidPropertyException if invalid value
+ */
+ public void putShortList(short[] aValues) throws SPIException {
+ if (aValues == null || aValues.length == 0) {
+ throw new InvalidPropertyException(
+ InvalidPropertyException.INVALID_VALUE_KEY);
+ }
+ StringBuffer sBuf = new StringBuffer(PolicyTree.BUFFER_SIZE);
+ for (int i = 0; i < aValues.length - 1; ++i) {
+ sBuf.append(aValues[i]);
+ sBuf.append(mSeparator);
+ }
+ sBuf.append(aValues[aValues.length - 1]);
+ put(sBuf.toString(), DataType.SHORT_LIST);
+ }
+
+ /**
+ * Sets the list of long values.
+ *
+ * @param aValue the list of long values
+ * @throws SPIException if error occurs
+ * @throws InvalidDataTypeException if invalid data type
+ * @throws InvalidPropertyException if invalid value
+ */
+ public void putLongList(long []aValues) throws SPIException{
+ if (aValues == null || aValues.length == 0) {
+ throw new InvalidPropertyException(
+ InvalidPropertyException.INVALID_VALUE_KEY);
+ }
+ StringBuffer sBuf = new StringBuffer(PolicyTree.BUFFER_SIZE);
+ for (int i = 0; i < aValues.length - 1; ++i) {
+ sBuf.append(aValues[i]);
+ sBuf.append(mSeparator);
+ }
+ sBuf.append(aValues[aValues.length - 1]);
+ put(sBuf.toString(), DataType.LONG_LIST);
+ }
+
+ /**
+ * Sets the list of boolean values.
+ *
+ * @param aValue the list of boolean values
+ * @throws SPIException if error occurs
+ * @throws InvalidDataTypeException if invalid data type
+ * @throws InvalidPropertyException if invalid value
+ */
+ public void putBooleanList(String[] aValues) throws SPIException{
+ if (aValues == null || aValues.length == 0) {
+ throw new InvalidPropertyException(
+ InvalidPropertyException.INVALID_VALUE_KEY);
+ }
+ put(getStringFromArray(aValues), DataType.BOOLEAN_LIST);
+ }
+
+ /**
+ * Sets the list of boolean values.
+ *
+ * @param aValue the list of boolean values
+ * @throws SPIException if error occurs
+ * @throws InvalidDataTypeException if invalid data type
+ * @throws InvalidPropertyException if invalid value
+ */
+ public void putBooleanList(boolean[] aValues) throws SPIException{
+ if (aValues == null || aValues.length == 0) {
+ throw new InvalidPropertyException(
+ InvalidPropertyException.INVALID_VALUE_KEY);
+ }
+ StringBuffer sBuf = new StringBuffer(PolicyTree.BUFFER_SIZE);
+ for (int i = 0; i < aValues.length - 1; ++i) {
+ sBuf.append(aValues[i]);
+ sBuf.append(mSeparator);
+ }
+ sBuf.append(aValues[aValues.length - 1]);
+ put(sBuf.toString(), DataType.BOOLEAN_LIST);
+ }
+
+ /**
+ * Carries out the read modification operation specified in
+ * this update node.
+ *
+ * @param aResultNode node that will be the result of
+ * the merge process
+ * @param aUpdateNodeKey information on update node
+ * @param aUpdateNodePath the path to this update node (used
+ * for exception messages)
+ * @param aIsParentUpdateLayer indicates if this is a parent update
+ * layer (needed for handling
+ * finalized attribute): <code>true</code>
+ * if final layer, otherwise <code>false</code>
+ * @throws <code>SPIException</code> if error occurs
+ */
+ public void readModifyProperty(PolicyNodeImpl aResultNode,
+ NodeKey aUpdateNodeKey, String aUpdateNodePath,
+ boolean aIsParentUpdateLayer) throws SPIException {
+ /* If the property exists in the source layer and is marked
+ readonly then this operation is ignored */
+ PropertyImpl resultNode =
+ (PropertyImpl)aResultNode.getProperty(getName());
+ if (resultNode != null && resultNode.isReadOnly()) { return; }
+
+ PropertyImpl newProperty;
+ if (resultNode == null) {
+ newProperty = this;
+ if (!aIsParentUpdateLayer) {
+ newProperty.setAddedAtTopLayer();
+ }
+ } else {
+ newProperty = (PropertyImpl)resultNode.shallowCopy();
+ /* If the update node has empty tags then the new PropertyImpl
+ will keep the values of the source layer. Otherwise, the
+ new Node copies the updated values of the update layer */
+ if (mValues != null && !mValues.isEmpty()) {
+ copyUpdateNodeValueImpls(mValues, newProperty,
+ aUpdateNodeKey.mLayer, aIsParentUpdateLayer);
+ }
+ }
+ newProperty.setPath(PolicyNodeImpl.appendToPath(aResultNode.getAbsolutePath(), getName()));
+ /* Check if this update property is finalized. If it is, and this
+ is a parent update layer being processed, then set the
+ readonly attribute to true for this node. If it is
+ finalized and this is the source layer or this is not a
+ parent layer, then set the finalized attribute to true */
+ if (isProtected()) {
+ newProperty.setFinalized(true, newProperty.getAbsolutePath(),
+ getOriginOfProtection());
+ if (aIsParentUpdateLayer) {
+ newProperty.setReadOnly();
+ }
+ }
+ /* set the operation property to reflect that this node
+ was modified */
+ newProperty.setOperationType(OperationType.OP_MODIFY);
+ /* add the node to aResultNode */
+ aResultNode.addProperty(newProperty);
+ }
+
+ /**
+ * Carries out the replacement operation specified in
+ * this update node.
+ *
+ * @param aResultNode node that will be the result of
+ * the merge process
+ * @param aUpdateNodePath the path to this update property (used
+ * for exception messages)
+ * @param aUpdateNodeKey information on update property
+ * @param aIsParentUpdateLayer indicates if this is a parent update
+ * layer (needed for handling
+ * finalized attribute): <code>true</code>
+ * if final layer, otherwise <code>false</code>
+ * @throws <code>SPIException</code> if
+ * error occurs
+ */
+ public void readReplaceProperty(PolicyNodeImpl aResultNode,
+ NodeKey aUpdateNodeKey, String aUpdateNodePath,
+ boolean aIsParentUpdateLayer)
+ throws SPIException {
+ /* if property element exists in source layer then
+ it cannot be replaced, so the operation is ignored */
+ if (aResultNode.getChild(getName()) != null) {
+ return;
+ } else {
+ /* Check if the update node is finalized. If it is, and it is
+ a parent update layer being processed, then set the readonly
+ attribute to true. If it is a default layer, or not a parent
+ layer, then set the finalized attribute to true */
+ if (isProtected()) {
+ String name = PolicyNodeImpl.appendToPath(
+ aResultNode.getAbsolutePath(),
+ getName());
+ setFinalized(true, name, getOriginOfProtection());
+ if (aIsParentUpdateLayer) {
+ setReadOnly();
+ }
+ }
+ /* if the update node is empty, then add a default NodeValueImpl */
+ if (mValues == null || mValues.isEmpty()) {
+ addDefaultNodeValueImpl(getOrigin());
+ }
+ if (aIsParentUpdateLayer) {
+ /* a node inserted at a parent layer is
+ mandatory to subsequent layers */
+ setMandatoryFlag();
+ setOriginOfMandatory(getOrigin());
+ }
+ /* if this is the entity layer being read, then
+ set the dynamic flag to indicate that the property
+ was added on the current layer */
+ if (!aIsParentUpdateLayer) {
+ setAddedAtTopLayer();
+ }
+ setPath(PolicyNodeImpl.appendToPath(aResultNode.getAbsolutePath(), getName()));
+ aResultNode.addProperty(this);
+ }
+ }
+
+ /**
+ * Sets the default property, that is the property as it was in the
+ * default layer.
+ *
+ * @param aDefaultProperty the default property
+ * @throws <code>SPIException</code> if error
+ * occurs
+ */
+ public void setDefaultProperty(
+ ReadWritePropertyImpl aDefaultProperty) throws SPIException {
+ mDefaultProperty = aDefaultProperty;
+ }
+
+ /**
+ * Sets the property value to Nil.
+ *
+ * @throws <code>SPIException</code>
+ */
+ public void setNil() throws SPIException {
+ getNodeValue().setValueToNil();
+ mHasBeenModified = true;
+ }
+
+ /**
+ * Sets the value of the finalized property of the property.
+ *
+ * @param aIsProtected <code>true</code> if the property
+ * is finalized, <code>false</code>
+ * otherwise
+ * if aIsProtected is <code>false</code>
+ */
+ public void setProtected(boolean aIsProtected)
+ throws SPIException {
+ setProtected(aIsProtected, getAbsolutePath(),
+ mPolicyTree.getPolicy());
+ }
+
+ /**
+ * Sets the value of the finalized property of the node,
+ * and its children.
+ *
+ * @param aIsProtected <code>true</code> if the node
+ * is finalized, <code>false</code>
+ * otherwise
+ * @param aNameOfNodeWhereProtectionSet name of the node where
+ * the flag was set
+ * (null if aIsProtected is
+ * <code>false</code>
+ * @param aOriginOfProtection layer where the flag was set
+ * (null if aIsProtected is
+ * <code>false</code>
+ */
+ public void setProtected(boolean aIsProtected,
+ String aNameOfNodeWhereProtectionSet,
+ Policy aOriginOfProtection)
+ throws SPIException {
+ checkIfReadOnly();
+ mIsProtected = aIsProtected ;
+ mNameOfElementWhereProtectionSet = aNameOfNodeWhereProtectionSet;
+ mOriginOfProtection = aOriginOfProtection;
+ mHasBeenModified = true;
+ }
+
+
+
+ /**
+ * Sets the property to its default.
+ *
+ * @param aDefaultProperty the default for the property on which
+ * the setDefault() method was called
+ * @throws <code>SPIException</code> if
+ * error occurs
+ */
+ private void setPropertyToDefault(
+ ReadWritePropertyImpl aDefaultProperty)
+ throws SPIException {
+ aDefaultProperty.setDefaultProperty(
+ (ReadWritePropertyImpl)aDefaultProperty.shallowCopy());
+ }
+
+
+ /**
+ * Sets the separator used by the property's values.
+ *
+ * @param aSeparator separator
+ */
+ public void setSeparator(String aSeparator) {
+ if (mSeparator != null) {
+ mSeparator = aSeparator;
+ }
+ mHasBeenModified = true;
+ }
+
+
+ /**
+ * Returns a shallow copy of the property.
+ *
+ * @return copy of the property
+ * @throws <code>SPIException</code> if cannot
+ * create copy
+ */
+ public ConfigElementImpl shallowCopy() throws SPIException {
+ ConfigElementImpl retCode = super.shallowCopy();
+ ((ReadWritePropertyImpl)retCode).mDefaultProperty = mDefaultProperty;
+ return retCode;
+ }
+
+ /**
+ * Carries out the update merge modification operation specified in
+ * this result property.
+ *
+ * @param aOutputProperty the equivalent node for the new
+ * update layer
+ * @param aLayer layer to be updated
+ * @param aUpdateNodePath the path to this result node (used
+ * for exception messages
+ * @return <code>true</code> if this node is
+ * required for the new update layer,
+ * otherwise <code>false</code>
+ * @throws <code>SPIException</code>
+ * if error occurs
+ */
+ public boolean updateModifyProperty(PropertyImpl aOutputProperty,
+ Policy aLayer,
+ String aUpdateNodePath)
+ throws SPIException{
+ boolean update = false;
+ if (isProtected()) {
+ if (getParent() == null || !getParent().isProtected()) {
+ /* should be included if the protect or setMandatory
+ function was applied directly to this node. */
+ update = true;
+ }
+ } else if (isMandatory() &&
+ (getOriginOfMandatory()).equals(aLayer)) {
+ update = true;
+ } else if (mValues != null) {
+ /* if the property was added at this layer
+ then all the values should be written */
+ if (isAddedAtTopLayer()) {
+ update = true;
+ } else {
+ /* go through each NodeValueImpl and see if it was
+ modified at this layer */
+ Enumeration keys = mValues.keys();
+ if (keys != null) {
+ Hashtable updateValues = null;
+ while (keys.hasMoreElements()) {
+ String key = (String)keys.nextElement();
+ NodeValueImpl value = (NodeValueImpl)getNodeValue(key);
+ if (value != null) {
+ if (value.isModifiedAtTopLayer()) {
+ update = true;
+ if (updateValues == null) {
+ updateValues = new Hashtable();
+ aOutputProperty.mValues =
+ updateValues;
+ }
+ updateValues.put(key, value);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (!update) {
+ ((ReadWritePolicyNodeImpl)aOutputProperty.getParent()).removeProperty(
+ getName());
+ }
+ return update;
+ }
+
+
+
+ /**
+ * Carries out the update merge remove operation specified in
+ * this result node.
+ *
+ * @param aOutputProperty the equivalent node for the new
+ * update layer
+ * @param aLayer layer to be updated
+ * @param aUpdateNodePath the path to this result node (used
+ * for exception messages
+ * @return <code>true</code> if this node is
+ * required for the new update layer,
+ * otherwise <code>false</code>
+ * @throws <code>SPIException</code> if
+ * error occurs
+ */
+ public boolean updateRemoveProperty(PropertyImpl aOutputProperty,
+ Policy aLayer,
+ String aUpdateNodePath)
+ throws SPIException {
+ ReadWritePolicyNodeImpl parentNode =
+ (ReadWritePolicyNodeImpl)getParent();
+ // delete the node
+ parentNode.removeProperty(getName());
+ return false;
+ }
+
+ /**
+ * Carries out the update merge replacement operation specified in
+ * this result property.
+ *
+ * @param aOutputProperty the equivalent property for the new
+ * update layer
+ * @param aLayer layer to be updated
+ * @param aUpdateNodePat the path to this result node (used
+ * for exception messages
+ * @return <code>true</code> if this node is
+ * required for the new update layer,
+ * otherwise <code>false</code>
+ * @throws <code>SPIException</code> if
+ * error occurs
+ */
+ public boolean updateReplaceProperty(PropertyImpl aOutputProperty,
+ Policy aLayer,
+ String aUpdateNodePath)
+ throws SPIException {
+ boolean update = false;
+ if (isProtected()) {
+ if (getParent() == null || !getParent().isProtected()) {
+ /* should be included if the protect or setMandatory
+ function was applied directly to this node. */
+ update = true;
+ }
+ } else if (isMandatory() &&
+ (getOriginOfMandatory()).equals(aLayer)) {
+ update = true;
+ } else if (mValues != null) {
+ /* if the property was added at this layer
+ then all the values should be written */
+ if (isAddedAtTopLayer()) {
+ update = true;
+ } else {
+ /* go through each NodeValueImpl and see if it was
+ modified at this layer */
+ Enumeration keys = mValues.keys();
+ if (keys != null) {
+ Hashtable updateValues = null;
+ while (keys.hasMoreElements()) {
+ String key = (String)keys.nextElement();
+ NodeValueImpl value = (NodeValueImpl)getNodeValue(key);
+ if (value != null) {
+ if (value.isModifiedAtTopLayer()) {
+ update = true;
+ if (updateValues == null) {
+ updateValues = new Hashtable();
+ ((PropertyImpl)aOutputProperty).mValues =
+ updateValues;
+ }
+ updateValues.put(key, value);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (update) {
+ /* set the operation attribute to "modify" */
+ setOperationType(OperationType.OP_MODIFY);
+ aOutputProperty.setOperationType(OperationType.OP_MODIFY);
+ } else {
+ ((ReadWritePolicyNodeImpl)aOutputProperty.getParent()).removeProperty(
+ getName());
+ }
+ return update;
+ }
+
+ /**
+ * Carries out the update merge reset operation specified in
+ * this result node.
+ *
+ * @param aOutputNode the equivalent property for the new
+ * update layer
+ * @param aLayer layer to be updated
+ * @param aUpdateNodePath the path to this result node (used
+ * for exception messages
+ * @return <code>true</code> if this node is
+ * required for the new update layer,
+ * otherwise <code>false</code>
+ * @throws <code>SPIException</code> if
+ * error occurs
+ */
+ public boolean updateResetProperty(PropertyImpl aOutputNode,
+ Policy aLayer,
+ String aUpdateNodePath)
+ throws SPIException {
+ boolean update = false;
+ if (isProtected()) {
+ if (getParent() == null || !getParent().isProtected()) {
+ /* it should be included if the protect function was
+ applied directly to this node. */
+ update = true;
+ }
+ } else if (isMandatory() && getOriginOfMandatory() != null &&
+ aLayer.equals(getOriginOfMandatory())) {
+ update = true;
+ } else if (mValues != null) {
+ /* go through each NodeValueImpl and see if it was
+ modified at this layer */
+ Enumeration keys = mValues.keys();
+ if (keys != null) {
+ Hashtable updateValues = null;
+ while (keys.hasMoreElements()) {
+ String key = (String)keys.nextElement();
+ NodeValueImpl value = (NodeValueImpl)getNodeValue(key);
+ if (value != null) {
+ if (value.isModifiedAtTopLayer()) {
+ update = true;
+ if (updateValues == null) {
+ updateValues = new Hashtable();
+ aOutputNode.mValues = updateValues;
+ }
+ updateValues.put(key, value);
+ }
+ }
+ }
+ }
+ }
+ if (update) {
+ /* set the operation attribute to "modify" */
+ aOutputNode.setOperationType(OperationType.OP_MODIFY);
+ }
+ return update;
+ }
+
+}