/* See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * Esri Inc. licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.esri.gpt.catalog.gxe; import java.util.ArrayList; import java.util.List; /** * An XML element collection. */ public class XmlElements { /** instance variables ====================================================== */ private List<XmlElement> members = new ArrayList<XmlElement>(); /** constructors ============================================================ */ /** Default constructor. */ public XmlElements() {} /** * Construct by duplicating an existing object. * @param objectToDuplicate the object to duplicate * @param parent the parent */ public XmlElements(XmlElements objectToDuplicate,XmlElement parent) { if (objectToDuplicate != null) { List<XmlElement> values = objectToDuplicate.values(); if (values != null) { for (XmlElement member: values) { this.add(member.duplicate(parent)); } } } } /** methods ================================================================= */ /** * Adds a member to the collection. * @param member the member to add */ public void add(XmlElement member) { if (member != null) { this.members.add(member); } } /** * Produces a deep clone of the object. * <br/>The duplication constructor is invoked. * <br/>return new XmlElements(this,parent); * @param parent the parent * @return the duplicated object */ public XmlElements duplicate(XmlElement parent) { return new XmlElements(this,parent); } /** * Finds an extensible element within the collection. * @param target the target to match (same element name and namespace; * @return the extensible element (null if none) */ public XmlElement findExtensible(XmlElement target) { return this.findMatchingElement(target,"extensible","true"); } /** * Finds a matching child element. * @param target the target to match (same element name and namespace) * @param gxdAttributeName a configured attribute name the the matching child must possess * (within the GXD namespace, typically "overridable" or "extensible") * @param gxdAttributeValue the attribute value that must match (typically "true") * @return the matching element (null if none) */ public XmlElement findMatchingElement(XmlElement target, String gxdAttributeName, String gxdAttributeValue) { String namespaceURI = target.getNodeInfo().getNamespaceURI(); String nodeName = target.getNodeInfo().getLocalName(); List<XmlElement> values = this.values(); String uriGxd = GxeContext.URI_GXE; for (XmlElement child: values) { boolean bMatch = false; if (child.getAttributes() != null) { XmlAttribute attribute = child.getAttributes().find(uriGxd,gxdAttributeName); if ((attribute != null) && (attribute.getNodeInfo().getNodeValue() != null)) { bMatch = attribute.getNodeInfo().getNodeValue().equals(gxdAttributeValue); } } if (bMatch) { bMatch = false; String ns = child.getNodeInfo().getNamespaceURI(); String name = child.getNodeInfo().getLocalName(); if (namespaceURI == null) { bMatch = (ns == null); } else if (ns != null) { bMatch = (ns.equals(namespaceURI)); } if (bMatch && name.equals(nodeName)) return child; } } return null; } /** * Finds an overridable element within the collection. * @param target the target to match (same element name and namespace; * @return the overridable element (null if none) */ public XmlElement findOverridable(XmlElement target) { return this.findMatchingElement(target,"overridable","true"); } /** * Replaces an element within the collection. * @param elementToReplace the element to be replaced * @param newElement the new element */ public void replace(XmlElement elementToReplace, XmlElement newElement) { List<XmlElement> values = this.members; int nIdx = -1; for (XmlElement child: values) { nIdx++; if (child == elementToReplace) { values.set(nIdx,newElement); return; } } } /** * Resets the parent for all child elements.. * @param parent the new parent */ public void resetParent(XmlElement parent) { List<XmlElement> values = this.members; for (XmlElement child: values) { child.setParent(parent); } } /** * Returns the size of the collection. * @return the size */ public int size() { return this.members.size(); } /** * Returns the list of values. * @return the values */ public List<XmlElement> values() { return this.members; } }