org.simpleframework.xml.stream.PrefixResolver Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of simple-xml Show documentation
Show all versions of simple-xml Show documentation
Simple is a high performance XML serialization and configuration framework for Java
/*
* PrefixResolver.java July 2008
*
* Copyright (C) 2008, Niall Gallagher
*
* Licensed 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.simpleframework.xml.stream;
import java.util.Iterator;
import java.util.LinkedHashMap;
/**
* The PrefixResolver
object will store the namespaces
* for an element. Each namespace added to this map can be added
* with a prefix. A prefix is added only if the associated reference
* has not been added to a parent element. If a parent element has
* the associated reference, then the parents prefix is the one that
* will be returned when requested from this map.
*
* @author Niall Gallagher
*
* @see org.simpleframework.xml.stream.OutputElement
*/
class PrefixResolver extends LinkedHashMap implements NamespaceMap {
/**
* Represents the actual XML element this is associated with.
*/
private final OutputNode source;
/**
* Constructor for the PrefixResolver
object. This
* is used to create a resolver for namespace prefixes using
* the hierarchy of elements. Resolving the prefix in this way
* avoids having to redeclare the same namespace with another
* prefix in a child element if it has already been declared.
*
* @param source this is the XML element this is associated to
*/
public PrefixResolver(OutputNode source) {
this.source = source;
}
/**
* This is the prefix that is associated with the source element.
* If the source element does not contain a namespace reference
* then this will return its parents namespace. This ensures
* that if a namespace has been declared its child elements will
* inherit its prefix.
*
* @return this returns the prefix that is currently in scope
*/
public String getPrefix() {
return source.getPrefix();
}
/**
* This is used to add the namespace reference to the namespace
* map. If the namespace has been added to a parent node then
* this will not add the reference. The prefix added to the map
* will be the default namespace, which is an empty prefix.
*
* @param reference this is the reference to be added
*
* @return this returns the prefix that has been replaced
*/
public String setReference(String reference) {
return setReference(reference, "");
}
/**
* This is used to add the namespace reference to the namespace
* map. If the namespace has been added to a parent node then
* this will not add the reference.
*
* @param reference this is the reference to be added
* @param prefix this is the prefix to be added to the reference
*
* @return this returns the prefix that has been replaced
*/
public String setReference(String reference, String prefix) {
String parent = resolvePrefix(reference);
if(parent != null) {
return null;
}
return put(reference, prefix);
}
/**
* This acquires the prefix for the specified namespace reference.
* If the namespace reference has been set on this node with a
* given prefix then that prefix is returned, however if it has
* not been set this will search the parent elements to find the
* prefix that is in scope for the specified reference.
*
* @param reference the reference to find a matching prefix for
*
* @return this will return the prefix that is is scope
*/
public String getPrefix(String reference) {
int size = size();
if(size > 0) {
String prefix = get(reference);
if(prefix != null) {
return prefix;
}
}
return resolvePrefix(reference);
}
/**
* This acquires the namespace reference for the specified prefix.
* If the provided prefix has been set on this node with a given
* reference then that reference is returned, however if it has
* not been set this will search the parent elements to find the
* reference that is in scope for the specified reference.
*
* @param prefix the prefix to find a matching reference for
*
* @return this will return the reference that is is scope
*/
public String getReference(String prefix) {
if(containsValue(prefix)) {
for(String reference : this) {
String value = get(reference);
if(value != null) {
if(value.equals(prefix)) {
return reference;
}
}
}
}
return resolveReference(prefix);
}
/**
* This method will resolve the reference or the specified prefix
* by searching the parent nodes in order. This allows the prefix
* that is currently in scope for the reference to be acquired.
*
* @param prefix the prefix to find a matching reference for
*
* @return this will return the reference that is is scope
*/
private String resolveReference(String prefix) {
NamespaceMap parent = source.getNamespaces();
if(parent != null) {
return parent.getReference(prefix);
}
return null;
}
/**
* This method will resolve the prefix or the specified reference
* by searching the parent nodes in order. This allows the prefix
* that is currently in scope for the reference to be acquired.
*
* @param reference the reference to find a matching prefix for
*
* @return this will return the prefix that is is scope
*/
private String resolvePrefix(String reference) {
NamespaceMap parent = source.getNamespaces();
if(parent != null) {
String prefix = parent.getPrefix(reference);
if(!containsValue(prefix)) {
return prefix;
}
}
return null;
}
/**
* This returns an iterator for the namespace of all the nodes
* in this NamespaceMap
. This allows the namespaces
* to be iterated within a for each loop in order to extract the
* prefix values associated with the map.
*
* @return this returns the namespaces contained in this map
*/
public Iterator iterator() {
return keySet().iterator();
}
}