/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.xml.handlers.xsi;
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.naming.OperationNotSupportedException;
import org.geotools.xml.PrintHandler;
import org.geotools.xml.XSIElementHandler;
import org.geotools.xml.schema.All;
import org.geotools.xml.schema.Attribute;
import org.geotools.xml.schema.AttributeGroup;
import org.geotools.xml.schema.Choice;
import org.geotools.xml.schema.ComplexType;
import org.geotools.xml.schema.Element;
import org.geotools.xml.schema.ElementGrouping;
import org.geotools.xml.schema.ElementValue;
import org.geotools.xml.schema.Group;
import org.geotools.xml.schema.Sequence;
import org.geotools.xml.schema.SimpleType;
import org.geotools.xml.schema.Type;
import org.geotools.xml.schema.impl.SimpleTypeGT;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
/**
* ComplexTypeHandler purpose.
*
* <p>
* Represents a ComplexType element
* </p>
* <p>
* When a specific method of encoding is not specified then the following output will be returned:
*
* ElementValue[]{(null,Attributes),(Element,Value)*,(null,String)?}
* Where the last element will be included iff there is child text.
* </p>
*
* @author dzwiers, Refractions Research, Inc. http://www.refractions.net
* @author $Author:$ (last modification)
* @source $URL$
* @version $Id$
*/
public class ComplexTypeHandler extends XSIElementHandler {
private static final long serialVersionUID = -2001189506633342497L;
/** 'complexType' */
public final static String LOCALNAME = "complexType";
/** ALL */
public static final int ALL = 128;
private static int offset = 0;
private String id;
private String name;
private boolean abstracT;
private boolean mixed;
private int block;
private int finaL;
private List attrDecs = new LinkedList(); // attr or attrGrps
private AnyAttributeHandler anyAttribute;
private Object child; //should be either a ComplexType or a SimpleType,
private int hashCodeOffset = getOffset();
private ComplexType cache = null;
/*
* helper for hashCode();
*/
private static int getOffset() {
return offset++;
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return (LOCALNAME.hashCode() * ((id == null) ? 1 : id.hashCode()) * ((attrDecs == null)
? 1 : attrDecs.hashCode()) * ((name == null) ? 1 : name.hashCode()))
+ hashCodeOffset;
}
/**
* @see org.geotools.xml.XSIElementHandler#getHandler(java.lang.String,
* java.lang.String)
*/
public XSIElementHandler getHandler(String namespaceURI, String localName)
throws SAXException {
if (SchemaHandler.namespaceURI.equalsIgnoreCase(namespaceURI)) {
// child types
//
// group
if (GroupHandler.LOCALNAME.equalsIgnoreCase(localName)) {
GroupHandler sth = new GroupHandler();
if (child == null) {
child = sth;
} else {
throw new SAXNotRecognizedException(LOCALNAME
+ " may only have one child declaration.");
}
return sth;
}
// all
if (AllHandler.LOCALNAME.equalsIgnoreCase(localName)) {
AllHandler sth = new AllHandler();
if (child == null) {
child = sth;
} else {
throw new SAXNotRecognizedException(LOCALNAME
+ " may only have one child declaration.");
}
return sth;
}
// choice
if (ChoiceHandler.LOCALNAME.equalsIgnoreCase(localName)) {
ChoiceHandler sth = new ChoiceHandler();
if (child == null) {
child = sth;
} else {
throw new SAXNotRecognizedException(LOCALNAME
+ " may only have one child declaration.");
}
return sth;
}
// sequence
if (SequenceHandler.LOCALNAME.equalsIgnoreCase(localName)) {
SequenceHandler sth = new SequenceHandler();
if (child == null) {
child = sth;
} else {
throw new SAXNotRecognizedException(LOCALNAME
+ " may only have one child declaration.");
}
return sth;
}
// attribute
if (AttributeHandler.LOCALNAME.equalsIgnoreCase(localName)) {
if (attrDecs == null) {
attrDecs = new LinkedList();
}
AttributeHandler ah = new AttributeHandler();
attrDecs.add(ah);
return ah;
}
// attributeGroup
if (AttributeGroupHandler.LOCALNAME.equalsIgnoreCase(localName)) {
if (attrDecs == null) {
attrDecs = new LinkedList();
}
AttributeGroupHandler ah = new AttributeGroupHandler();
attrDecs.add(ah);
return ah;
}
// anyAttribute
if (AnyAttributeHandler.LOCALNAME.equalsIgnoreCase(localName)) {
AnyAttributeHandler sth = new AnyAttributeHandler();
if (anyAttribute == null) {
anyAttribute = sth;
} else {
throw new SAXNotRecognizedException(LOCALNAME
+ " may only have one child declaration.");
}
return sth;
}
// complexContent
if (ComplexContentHandler.LOCALNAME.equalsIgnoreCase(localName)) {
ComplexContentHandler sth = new ComplexContentHandler();
if (child == null) {
child = sth;
} else {
throw new SAXNotRecognizedException(LOCALNAME
+ " may only have one child declaration.");
}
return sth;
}
// simpleContent
if (SimpleContentHandler.LOCALNAME.equalsIgnoreCase(localName)) {
SimpleContentHandler sth = new SimpleContentHandler();
if (child == null) {
child = sth;
} else {
throw new SAXNotRecognizedException(LOCALNAME
+ " may only have one child declaration.");
}
return sth;
}
}
return null;
}
/**
* @see org.geotools.xml.XSIElementHandler#startElement(java.lang.String,
* java.lang.String, org.xml.sax.Attributes)
*/
public void startElement(String namespaceURI, String localName,
Attributes atts) throws SAXException {
id = atts.getValue("", "id");
if (id == null) {
id = atts.getValue(namespaceURI, "id");
}
name = atts.getValue("", "name");
if (name == null) {
name = atts.getValue(namespaceURI, "name");
}
String abstracT1 = atts.getValue("", "abstract");
if (abstracT1 == null) {
abstracT1 = atts.getValue(namespaceURI, "abstract");
}
if ((abstracT1 == null) || "".equals(abstracT1)) {
this.abstracT = false;
} else {
this.abstracT = Boolean.valueOf(abstracT1).booleanValue();
}
String block1 = atts.getValue("", "block");
if (block1 == null) {
block1 = atts.getValue(namespaceURI, "block");
}
this.block = ComplexTypeHandler.findBlock(block1);
String finaL1 = atts.getValue("", "final");
if (finaL1 == null) {
finaL1 = atts.getValue(namespaceURI, "final");
}
this.finaL = ComplexTypeHandler.findFinal(finaL1);
String mixed1 = atts.getValue("", "mixed");
if (mixed1 == null) {
mixed1 = atts.getValue(namespaceURI, "mixed");
}
if ((mixed1 == null) || "".equalsIgnoreCase(mixed1)) {
this.mixed = false;
} else {
this.mixed = Boolean.getBoolean(mixed1);
}
this.block = findBlock(block1);
this.finaL = findFinal(finaL1);
}
/**
* @see org.geotools.xml.XSIElementHandler#getLocalName()
*/
public String getLocalName() {
return LOCALNAME;
}
// Group, Sequence, All Choice
/**
* <p>
* Converts a 'block' attribute value into an int mask
* </p>
*
* @param block block
*
* @return int
*
* @throws SAXException
*/
public static int findBlock(String block) throws SAXException {
if ((block == null) || "".equalsIgnoreCase(block)) {
return DEFAULT;
}
if ("extension".equalsIgnoreCase(block)) {
return EXTENSION;
}
if ("restriction".equalsIgnoreCase(block)) {
return RESTRICTION;
}
if ("#all".equalsIgnoreCase(block)) {
return ALL;
}
throw new SAXException("Unknown Block Type: '" + block + "'");
}
/**
* <p>
* Reverses the translation from mask to String
* </p>
*
* @param block
*
*/
public static String writeBlock(int block) {
switch (block) {
case EXTENSION:
return "extension";
case RESTRICTION:
return "restriction";
case ALL:
return "#all";
default:
return "";
}
}
/**
* <p>
* Converts a 'final' attribute value to an int mask
* </p>
*
* @param finaL
*
*
* @throws SAXException
*/
public static int findFinal(String finaL) throws SAXException {
try {
return findBlock(finaL); // same enum
} catch (SAXException e) {
throw new SAXException("Unknown Final Type: '" + finaL + "'");
}
}
/**
* <p>
* reverses the conversion of an int mask representing the 'final'
* attribute to String
* </p>
*
* @param finaL
*
*/
public static String writeFinal(int finaL) {
return writeBlock(finaL); // same enum
}
/**
* <p>
* returns the complexType's name
* </p>
*
*/
public String getName() {
return name;
}
/**
* <p>
* compresses the inheritance tree, caching a more efficient copy.
* </p>
*
* @param parent
*
*
* @throws SAXException
* @throws NullPointerException
*/
protected ComplexType compress(SchemaHandler parent)
throws SAXException {
logger.fine("Start compressing ComplexType " + getName());
if (cache != null) {
return cache;
}
DefaultComplexType dct = new DefaultComplexType();
dct.abstracT = abstracT;
dct.anyAttributeNameSpace = (anyAttribute != null)
? anyAttribute.getNamespace() : null;
HashSet attr = new HashSet();
if (child instanceof SimpleContentHandler
|| child instanceof ComplexContentHandler) {
if (child instanceof SimpleContentHandler) {
logger.finest("SimpleContentHandler");
SimpleContentHandler sch = (SimpleContentHandler) child;
if (sch.getChild() instanceof ExtensionHandler) {
ExtensionHandler ext = (ExtensionHandler) sch.getChild();
// attributes
if (ext.getAttributeDeclarations() != null) {
Iterator it = ext.getAttributeDeclarations().iterator();
while (it.hasNext()) {
Object o = it.next();
if (o instanceof AttributeHandler) {
AttributeHandler ah = (AttributeHandler) o;
attr.add(ah.compress(parent));
} else {
AttributeGroupHandler agh = (AttributeGroupHandler) o;
AttributeGroup ag = agh.compress(parent);
attr.addAll(Arrays.asList(ag.getAttributes()));
}
}
}
SimpleType st;
if ((ext.getBase() == null)
|| ext.getBase().equalsIgnoreCase("")) {
st = ((SimpleTypeHandler) ext.getChild()).compress(parent);
} else {
st = parent.lookUpSimpleType(ext.getBase());
}
dct.parent = st;
dct.simple = true;
} else {
// restriction
RestrictionHandler rest = (RestrictionHandler) sch.getChild();
// attributes
if (rest.getAttributeDeclarations() != null) {
Iterator it = rest.getAttributeDeclarations().iterator();
while (it.hasNext()) {
Object o = it.next();
if (o instanceof AttributeHandler) {
AttributeHandler ah = (AttributeHandler) o;
attr.add(ah.compress(parent));
} else {
AttributeGroupHandler agh = (AttributeGroupHandler) o;
AttributeGroup ag = agh.compress(parent);
attr.addAll(Arrays.asList(ag.getAttributes()));
}
}
}
SimpleType st = new SimpleTypeGT(id, name,
parent.getTargetNamespace(),
SimpleType.RESTRICTION,
SimpleTypeHandler.getSimpleTypes(rest, parent),
SimpleTypeHandler.getFacets(rest), finaL);
dct.parent = st;
dct.simple = true;
}
dct.mixed = true;
} else {
// ComplexContentHandler
// TODO deal with these as a special case to incure call backs in the heiarchy
ComplexContentHandler cch = (ComplexContentHandler) child;
if (cch.getChild() instanceof ExtensionHandler) {
ExtensionHandler ext = (ExtensionHandler) cch.getChild();
ComplexType ct = parent.lookUpComplexType(ext.getBase());
dct.parent = ct;
// attributes
if (ct!=null && ct.getAttributes() != null) {
Attribute[] it = ct.getAttributes();
for (int i = 0; i < it.length; i++) {
attr.add(it[i]);
}
}
if (ext.getAttributeDeclarations() != null) {
Iterator it = ext.getAttributeDeclarations().iterator();
while (it.hasNext()) {
Object o = it.next();
if (o instanceof AttributeHandler) {
AttributeHandler ah = (AttributeHandler) o;
attr.add(ah.compress(parent));
} else {
AttributeGroupHandler agh = (AttributeGroupHandler) o;
AttributeGroup ag = agh.compress(parent);
attr.addAll(Arrays.asList(ag.getAttributes()));
}
}
}
if (ct!=null && ext.getChild() != null) {
logger.finest("Looked up " + ext.getBase()
+ " and found "
+ ((ct == null) ? null
: (ct.getName() + ":::"
+ ct.getNamespace())) + " for " + name);
ElementGrouping extensionBaseType = ct.getChild();
ElementGrouping extensionChild = ((ElementGroupingHandler)ext.getChild()).compress(parent);
dct.child = loadNewEG(extensionBaseType,extensionChild, parent); // note should override element def only ... not spot
} else {
if (ct != null)
dct.child = ct.getChild();
}
} else {
//restriction
RestrictionHandler ext = (RestrictionHandler) cch.getChild();
// attributes
if (ext.getAttributeDeclarations() != null) {
Iterator it = ext.getAttributeDeclarations().iterator();
while (it.hasNext()) {
Object o = it.next();
if (o instanceof AttributeHandler) {
AttributeHandler ah = (AttributeHandler) o;
attr.add(ah.compress(parent));
} else {
AttributeGroupHandler agh = (AttributeGroupHandler) o;
AttributeGroup ag = agh.compress(parent);
attr.addAll(Arrays.asList(ag.getAttributes()));
}
}
}
if (ext.getChild() == null) {
dct.child = null; // empty child
} else {
dct.child = ((ElementGroupingHandler) ext.getChild())
.compress(parent);
}
dct.parent = parent.lookUpComplexType(ext.getBase());
}
if (dct.child == null) {
dct.child = new DefaultSequence();
}
dct.isDerived = true;
}
} else {
// one of Choice, Group, Sequence, All
// attributes
if (attrDecs != null) {
Iterator it = attrDecs.iterator();
while (it.hasNext()) {
Object o = it.next();
if (o instanceof AttributeHandler) {
AttributeHandler ah = (AttributeHandler) o;
attr.add(ah.compress(parent));
} else {
AttributeGroupHandler agh = (AttributeGroupHandler) o;
AttributeGroup ag = agh.compress(parent);
attr.addAll(Arrays.asList(ag.getAttributes()));
}
}
}
if (child != null) {
dct.child = ((ElementGroupingHandler) child).compress(parent);
} else {
dct.child = new DefaultSequence();
}
}
dct.attributes = (Attribute[]) attr.toArray(new Attribute[attr.size()]);
dct.namespace = parent.getTargetNamespace();
dct.block = block;
dct.finaL = finaL;
dct.id = id;
if (!dct.mixed) { // simpleContent flag ...
dct.mixed = mixed;
}
dct.name = name;
cache = dct;
if (((cache.getChild() == null) && !abstracT) && !dct.simple) {
logger.warning(getName() + " :: " + parent.getTargetNamespace()
+ " should have a real child: ");
throw new NullPointerException();
}
if ((dct.parent == null) && dct.simple) {
logger.warning(getName() + " :: " + parent.getTargetNamespace()
+ " should have a real parent: ");
throw new NullPointerException();
}
logger.fine("End compressing ComplexType " + getName());
attrDecs = null;
anyAttribute = null;
child = null;
return cache;
}
/*
* Helper method that removes a level of indirection through combining
* the levels into more compact representations
*/
private ElementGrouping loadNewEG(ElementGrouping extensionBaseType, ElementGrouping extensionChild,
SchemaHandler parent) throws SAXException {
if (extensionChild == null) {
if (extensionBaseType.getGrouping() == ElementGrouping.GROUP) {
return ((Group) extensionBaseType).getChild();
}
return extensionBaseType;
}
switch (extensionBaseType.getGrouping()) {
case ElementGrouping.CHOICE:
logger.finest("ElementGrouping eg is CHOICE in loadNewEG");
return new DefaultSequence((Choice) extensionBaseType, extensionChild);
case ElementGrouping.GROUP:
logger.finest("ElementGrouping eg is GROUP in loadNewEG");
Group baseGroup = (Group) extensionBaseType;
if (baseGroup.getChild() == null) {
return extensionChild;
}
return loadNewEG(baseGroup.getChild(),extensionChild,parent);
case ElementGrouping.SEQUENCE:
logger.finest("ElementGrouping eg is SEQUENCE");
return new DefaultSequence((Sequence) extensionBaseType,extensionChild);
default:
return extensionBaseType;
}
}
/**
* @see org.geotools.xml.XSIElementHandler#getHandlerType()
*/
public int getHandlerType() {
return DEFAULT;
}
/**
* @see org.geotools.xml.XSIElementHandler#endElement(java.lang.String,
* java.lang.String)
*/
public void endElement(String namespaceURI, String localName){
// do nothing
}
/**
* <p>
* implementation of a default sequence with some extra logic in the
* constructors.
* </p>
*
* @author dzwiers
*
* @see Sequence
*/
private static class DefaultSequence implements Sequence {
ElementGrouping[] children;
String id;
int maxOccurs;
int minOccurs;
/*
* Should not be called
*/
private DefaultSequence() {
// do nothing
}
/**
* <p>
* Combines the specified Sequence with the element grouping into a
* new Sequence
* </p>
*
* @param sequence
* @param eg
*/
public DefaultSequence(Sequence sequence, ElementGrouping eg) {
logger.finest("merging sequence with an ElementGrouping");
id = sequence.getId();
maxOccurs = sequence.getMaxOccurs();
minOccurs = sequence.getMinOccurs();
if (sequence.getChildren() == null) {
logger.finest("Sequence children are null");
children = new ElementGrouping[1];
children[0] = eg;
return;
}
if (eg.getGrouping() == ElementGrouping.SEQUENCE) {
logger.finest("Two sequences being merged");
Sequence sq2 = (Sequence) eg;
children = new ElementGrouping[sequence.getChildren().length
+ sq2.getChildren().length];
logger.finest("There are a total of " + children.length
+ " Children");
for (int i = 0; i < sequence.getChildren().length; i++) {
children[i] = sequence.getChildren()[i];
}
for (int i = 0; i < sq2.getChildren().length; i++) {
children[sequence.getChildren().length + i] = sq2
.getChildren()[i];
}
} else {
children = new ElementGrouping[sequence.getChildren().length
+ 1];
logger.finest("There are a total of " + children.length
+ " Children");
for (int i = 0; i < sequence.getChildren().length; i++)
children[i] = sequence.getChildren()[i];
children[sequence.getChildren().length] = eg;
}
}
/**
* <p>
* Combines the Choice with the ElementGrouping to form a new Sequence
* </p>
*
* @param sequence
* @param eg
*/
public DefaultSequence(Choice sequence, ElementGrouping eg) {
id = sequence.getId();
maxOccurs = sequence.getMaxOccurs();
minOccurs = sequence.getMinOccurs();
if (sequence.getChildren() == null) {
children = new ElementGrouping[1];
children[0] = eg;
return;
}
children = new ElementGrouping[2];
children[0] = sequence;
children[1] = eg;
}
/**
* @see org.geotools.xml.xsi.Sequence#getChildren()
*/
public ElementGrouping[] getChildren() {
return children;
}
/**
* @see org.geotools.xml.xsi.Sequence#getId()
*/
public String getId() {
return id;
}
/**
* @see org.geotools.xml.xsi.ElementGrouping#getMaxOccurs()
*/
public int getMaxOccurs() {
return maxOccurs;
}
/**
* @see org.geotools.xml.xsi.ElementGrouping#getMinOccurs()
*/
public int getMinOccurs() {
return minOccurs;
}
/**
* @see org.geotools.xml.xsi.ElementGrouping#getGrouping()
*/
public int getGrouping() {
return SEQUENCE;
}
/**
* @see org.geotools.xml.xsi.ElementGrouping#findChildElement(java.lang.String)
*/
public Element findChildElement(String name) {
if (children == null) {
return null;
}
for (int i = 0; i < children.length; i++) {
Element t = children[i].findChildElement(name);
if (t != null) { // found it
return t;
}
}
return null;
}
public Element findChildElement(String localName, URI namespaceURI) {
if (children == null) {
return null;
}
for (int i = 0; i < children.length; i++) {
Element t = children[i].findChildElement(localName,namespaceURI);
if (t != null) { // found it
return t;
}
}
return null;
}
}
/**
* <p>
* Default implementation of a ComplexType
* </p>
*
* @author dzwiers
*
* @see ComplexType
*/
private static class DefaultComplexType implements ComplexType {
boolean isDerived = false;
Type parent;
String anyAttributeNameSpace;
URI namespace;
String id;
String name;
int block;
int finaL;
ElementGrouping child;
boolean simple = false;
Attribute[] attributes;
boolean abstracT;
boolean mixed;
public Element[] getChildElements() {
if (child == null) {
return null;
}
return getChildElements(child);
}
public Element[] getChildElements(ElementGrouping child11) {
if(child11 == null)
return new Element[0];
switch (child11.getGrouping()) {
case ElementGrouping.ALL:
return ((All) child11).getElements();
case ElementGrouping.ANY:
return null;
case ElementGrouping.CHOICE:
ElementGrouping[] children = ((Choice) child11).getChildren();
List l = new LinkedList();
for (int i = 0; i < children.length; i++) {
Element[] t = getChildElements(children[i]);
if (t != null) {
l.addAll(Arrays.asList(t));
}
}
return (l.size() > 0)
? (Element[]) l.toArray(new Element[l.size()]) : null;
case ElementGrouping.ELEMENT:
return new Element[] { (Element) child11, };
case ElementGrouping.GROUP:
ElementGrouping c = ((Group) child11).getChild();
if(c == null)
return new Element[0];
return getChildElements(c);
case ElementGrouping.SEQUENCE:
children = ((Sequence) child11).getChildren();
l = new LinkedList();
if(children!=null){
for (int i = 0; i < children.length; i++) {
Element[] t = getChildElements(children[i]);
if (t != null) {
l.addAll(Arrays.asList(t));
}
}}
return (l.size() > 0)
? (Element[]) l.toArray(new Element[l.size()]) : null;
}
return null;
}
/**
* @see org.geotools.xml.schema.ComplexType#cache()
*/
public boolean cache(Element e, Map m) {
return true;
}
/**
* @see org.geotools.xml.xsi.Type#getNamespace()
*/
public URI getNamespace() {
return namespace;
}
/**
* @see org.geotools.xml.xsi.Type#getParent()
*/
public Type getParent() {
return parent;
}
/**
* @see org.geotools.xml.xsi.ComplexType#isDerived()
*/
public boolean isDerived() {
return isDerived;
}
/**
* @see org.geotools.xml.xsi.ComplexType#getAttributeDescriptors()
*/
public Attribute[] getAttributes() {
return attributes;
}
/**
* @see org.geotools.xml.xsi.ComplexType#isAbstract()
*/
public boolean isAbstract() {
return abstracT;
}
/**
* @see org.geotools.xml.xsi.ComplexType#getBlock()
*/
public int getBlock() {
return block;
}
/**
* @see org.geotools.xml.xsi.ComplexType#getChild()
*/
public ElementGrouping getChild() {
return child;
}
/**
* @see org.geotools.xml.xsi.ComplexType#getFinal()
*/
public int getFinal() {
return finaL;
}
/**
* @see org.geotools.xml.xsi.ComplexType#isMixed()
*/
public boolean isMixed() {
return mixed;
}
/**
* @see org.geotools.xml.xsi.Type#getLocalName()
*/
public String getName() {
return name;
}
/**
* @see org.geotools.xml.xsi.ComplexType#getAnyAttributeNameSpace()
*/
public String getAnyAttributeNameSpace() {
return anyAttributeNameSpace;
}
/**
* @see org.geotools.xml.xsi.ComplexType#getId()
*/
public String getId() {
return id;
}
/**
* @throws SAXException
* @throws OperationNotSupportedException
* @see org.geotools.xml.xsi.Type#getValue(org.geotools.xml.xsi.Element,
* org.geotools.xml.xsi.ElementValue[], org.xml.sax.Attributes)
*/
public Object getValue(Element element, ElementValue[] value,
final Attributes attrs, Map hints) throws OperationNotSupportedException, SAXException {
Object[] values = null;
logger.finest("Getting value for " + name);
if (isDerived || simple) {
try {
Object v = parent.getValue(element, value, attrs, hints);
return v; // this means it's meant to be extended ... and so should already include the extensions.
} catch (SAXNotSupportedException snse) {
logger.finest(snse.toString());
// do nothing ... except pretend it is not derived
}
}
if (simple) {
return null;
}
if( element.getType() instanceof ComplexType
&& ((ComplexType)element.getType()).getChild() instanceof Choice){
if( value.length>0)
return value[0].getValue();
}else{
values = new Object[value.length+1];
logger.finest("Getting value for " + element.getName() + ":" + name);
// This seems to some how be for mixed content? Don't really understand what
// is going on here.
values[0] = new ElementValue(){
public Element getElement() {
return null;
}
public Object getValue() {
return attrs;
}
};
for (int i = 1; i < value.length+1; i++) {
values[i] = value[i-(isMixed()?0:1)].getValue();
logger.finest("*"
+ ((values[i] != null) ? values[i].getClass().getName()
: "null"));
}
if(isMixed())
values[values.length-1] = value[0];
}
return values;
}
/**
* @see org.geotools.xml.xsi.Type#getInstanceType()
*/
public Class getInstanceType() {
return Object[].class;
}
/**
* @see org.geotools.xml.xsi.ComplexType#findChildElement(java.lang.String)
*/
public Element findChildElement(String name1) {
Element e = (child == null) ? null : child.findChildElement(name1);
e = e==null?(parent==null?null:parent.findChildElement(name1)):e;
return e;
}
/**
* @see org.geotools.xml.schema.Type#canEncode(org.geotools.xml.schema.Element,
* java.lang.Object, java.util.Map)
*/
public boolean canEncode(Element element, Object value, Map hints) {
if ((parent != null) && parent.canEncode(element, value, hints)) {
return true;
}
return false;
}
/**
* @see org.geotools.xml.schema.Type#encode(org.geotools.xml.schema.Element,
* java.lang.Object, org.geotools.xml.PrintHandler,
* java.util.Map)
*/
public void encode(Element element, Object value, PrintHandler output,
Map hints) throws IOException, OperationNotSupportedException {
if ((parent != null) && parent.canEncode(element, value, hints)) {
parent.encode(element, value, output, hints);
} else {
output.startElement(element.getNamespace(), element.getName(), null);
Type type=element.getType();
if( type instanceof SimpleType ){
SimpleType simple=(SimpleType) type;
simple.encode(element, value, output, hints);
}else if (type instanceof ComplexType) {
ComplexType complex = (ComplexType) type;
Element[] children = complex.getChildElements();
boolean found=false;
for (int i = 0; i < children.length; i++) {
Element child = children[i];
if( child.getType().canEncode(child, value, hints) ){
child.getType().encode(child, value, output, hints);
found=true;
}
}
if( !found )
throw new RuntimeException(
"It is not known how to print this element");
}else{
throw new OperationNotSupportedException(
"It is not known how to print this element");
}
output.endElement(element.getNamespace(), element.getName());
}
}
}
}