blob: 2a271d2f76b289aa170a08c2296bf3813e7984f1 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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 org.apache.axiom.core;
import java.util.Iterator;
public aspect CoreElementSupport {
private CoreAttribute CoreElement.firstAttribute;
final void CoreElement.beforeDetach() {
if (getState() == CoreParentNode.INCOMPLETE && getBuilder() == coreGetParent().getBuilder()) {
build();
}
}
public final CoreAttribute CoreElement.coreGetFirstAttribute() {
forceExpand();
return firstAttribute;
}
final void CoreElement.internalSetFirstAttribute(CoreAttribute firstAttribute) {
this.firstAttribute = firstAttribute;
}
public final CoreAttribute CoreElement.coreGetLastAttribute() {
CoreAttribute previousAttribute = null;
CoreAttribute attribute = firstAttribute;
while (attribute != null) {
previousAttribute = attribute;
attribute = attribute.coreGetNextAttribute();
}
return previousAttribute;
}
public final CoreAttribute CoreElement.coreGetAttribute(AttributeMatcher matcher, String namespaceURI, String name) {
CoreAttribute attr = coreGetFirstAttribute();
while (attr != null && !matcher.matches(attr, namespaceURI, name)) {
attr = attr.coreGetNextAttribute();
}
return attr;
}
public final void CoreElement.coreAppendAttribute(CoreAttribute attr) {
// TODO: we should probably check if the attribute is already owned by the element
attr.internalRemove(null, this);
CoreAttribute lastAttribute = coreGetLastAttribute();
if (lastAttribute == null) {
firstAttribute = attr;
} else {
lastAttribute.internalSetNextAttribute(attr);
}
}
public final void CoreElement.coreSetAttribute(AttributeMatcher matcher, String namespaceURI, String name, String prefix, String value) {
CoreAttribute attr = firstAttribute;
CoreAttribute previousAttr = null;
while (attr != null && !matcher.matches(attr, namespaceURI, name)) {
previousAttr = attr;
attr = attr.coreGetNextAttribute();
}
if (attr == null) {
CoreAttribute newAttr = matcher.createAttribute(this, namespaceURI, name, prefix, value);
if (previousAttr == null) {
coreAppendAttribute(newAttr);
} else {
previousAttr.insertAttributeAfter(newAttr);
}
} else {
matcher.update(attr, prefix, value);
}
}
public final CoreAttribute CoreElement.coreSetAttribute(AttributeMatcher matcher, CoreAttribute attr, Semantics semantics) {
if (attr.coreGetOwnerElement() == this) {
// TODO: document this and add assertion
return attr;
}
attr.internalRemove(null, this);
String namespaceURI = matcher.getNamespaceURI(attr);
String name = matcher.getName(attr);
CoreAttribute existingAttr = coreGetFirstAttribute();
CoreAttribute previousAttr = null;
while (existingAttr != null && !matcher.matches(existingAttr, namespaceURI, name)) {
previousAttr = existingAttr;
existingAttr = existingAttr.coreGetNextAttribute();
}
if (existingAttr == null) {
if (previousAttr == null) {
firstAttribute = attr;
} else {
previousAttr.internalSetNextAttribute(attr);
}
} else {
if (previousAttr == null) {
firstAttribute = attr;
} else {
previousAttr.internalSetNextAttribute(attr);
}
existingAttr.internalUnsetOwnerElement(semantics.getDetachPolicy().getNewOwnerDocument(this));
attr.internalSetNextAttribute(existingAttr.coreGetNextAttribute());
existingAttr.internalSetNextAttribute(null);
}
return existingAttr;
}
public final boolean CoreElement.coreRemoveAttribute(AttributeMatcher matcher, String namespaceURI, String name, Semantics semantics) {
CoreAttribute att = coreGetAttribute(matcher, namespaceURI, name);
if (att != null) {
att.coreRemove(semantics);
return true;
} else {
return false;
}
}
public final <T extends CoreAttribute,S> Iterator<S> CoreElement.coreGetAttributesByType(Class<T> type, Mapper<T,S> mapper, Semantics semantics) {
return AttributeIterator.create(this, type, mapper, semantics);
}
public abstract String CoreElement.getImplicitNamespaceURI(String prefix);
public final String CoreElement.coreLookupNamespaceURI(String prefix, Semantics semantics) {
if (!semantics.isUseStrictNamespaceLookup()) {
String namespaceURI = getImplicitNamespaceURI(prefix);
if (namespaceURI != null) {
return namespaceURI;
}
}
for (CoreAttribute attr = coreGetFirstAttribute(); attr != null; attr = attr.coreGetNextAttribute()) {
if (attr instanceof CoreNamespaceDeclaration) {
CoreNamespaceDeclaration decl = (CoreNamespaceDeclaration)attr;
if (prefix.equals(decl.coreGetDeclaredPrefix())) {
return decl.coreGetCharacterData().toString();
}
}
}
CoreElement parentElement = coreGetParentElement();
if (parentElement != null) {
return parentElement.coreLookupNamespaceURI(prefix, semantics);
} else if (prefix.length() == 0) {
return "";
} else {
return null;
}
}
public abstract String CoreElement.getImplicitPrefix(String namespaceURI);
public final String CoreElement.coreLookupPrefix(String namespaceURI, Semantics semantics) {
if (namespaceURI == null) {
throw new IllegalArgumentException("namespaceURI must not be null");
}
if (!semantics.isUseStrictNamespaceLookup()) {
String prefix = getImplicitPrefix(namespaceURI);
if (prefix != null) {
return prefix;
}
}
for (CoreAttribute attr = coreGetFirstAttribute(); attr != null; attr = attr.coreGetNextAttribute()) {
if (attr instanceof CoreNamespaceDeclaration) {
CoreNamespaceDeclaration decl = (CoreNamespaceDeclaration)attr;
if (decl.coreGetCharacterData().toString().equals(namespaceURI)) {
return decl.coreGetDeclaredPrefix();
}
}
}
CoreElement parentElement = coreGetParentElement();
if (parentElement != null) {
String prefix = parentElement.coreLookupPrefix(namespaceURI, semantics);
// The prefix declared on one of the ancestors may be masked by another
// namespace declaration on this element (or one of its descendants).
if (!semantics.isUseStrictNamespaceLookup() && getImplicitNamespaceURI(prefix) != null) {
return null;
}
for (CoreAttribute attr = coreGetFirstAttribute(); attr != null; attr = attr.coreGetNextAttribute()) {
if (attr instanceof CoreNamespaceDeclaration) {
CoreNamespaceDeclaration decl = (CoreNamespaceDeclaration)attr;
if (decl.coreGetDeclaredPrefix().equals(prefix)) {
return null;
}
}
}
return prefix;
} else {
return null;
}
}
public final <T> void CoreElement.init(ClonePolicy<T> policy, T options, CoreNode other) {
CoreElement o = (CoreElement)other;
initSource(policy, options, o);
initName(o);
if (isExpanded()) {
CoreAttribute attr = o.coreGetFirstAttribute();
while (attr != null) {
coreAppendAttribute((CoreAttribute)attr.coreClone(policy, options));
// TODO: needed?
// clonedAttr.coreSetSpecified(attr.coreGetSpecified());
attr = attr.coreGetNextAttribute();
}
}
}
// This is basically a hook for OMSourcedElement
public <T> void CoreElement.initSource(ClonePolicy<T> policy, T options, CoreElement other) {
}
}