/*
* 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 org.geotools.xml.XSIElementHandler;
import org.geotools.xml.schema.Attribute;
import org.geotools.xml.schema.SimpleType;
import org.geotools.xml.schema.impl.AttributeGT;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
/**
* AttributeHandler purpose.
*
* <p>
* Represents an 'attribute' element
* </p>
*
* <p>
* Example Use:
* <pre><code>
*
* AttributeHandler x = new AttributeHandler(...);
*
* </code></pre>
* </p>
*
* @author dzwiers, Refractions Research, Inc. http://www.refractions.net
* @author $Author:$ (last modification)
* @source $URL$
* @version $Id$
*/
public class AttributeHandler extends XSIElementHandler {
/** 'attribute' */
public final static String LOCALNAME = "attribute";
/** OPTIONAL */
public static final int OPTIONAL = 0;
/** PROHIBITED */
public static final int PROHIBITED = 1;
/** REQUIRED */
public static final int REQUIRED = 2;
private static int offset = 0;
private String id;
private String name;
private String type;
private String ref;
private String def;
private String fixed;
private int use;
private SimpleTypeHandler simpleType;
private int hashCodeOffset = getOffset();
private Attribute cache = null;
/*
* hashCode() helper
*/
private static int getOffset() {
return offset++;
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return (LOCALNAME.hashCode() * ((id == null) ? 1 : id.hashCode()) * ((type == null)
? 1 : type.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
//
// simpleType
if (SimpleTypeHandler.LOCALNAME.equalsIgnoreCase(localName)) {
SimpleTypeHandler sth = new SimpleTypeHandler();
if (simpleType == null) {
simpleType = sth;
} else {
throw new SAXNotRecognizedException(
"Extension may only have one 'simpleType' or 'complexType' 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){
id = atts.getValue("", "id");
if (id == null) {
id = atts.getValue(namespaceURI, "id");
}
String name1 = atts.getValue("", "name");
if (name1 == null) {
name1 = atts.getValue(namespaceURI, "name");
}
String ref1 = atts.getValue("", "ref");
if (ref1 == null) {
ref1 = atts.getValue(namespaceURI, "ref");
}
String type1 = atts.getValue("", "type");
if (type1 == null) {
type1 = atts.getValue(namespaceURI, "type");
}
this.name = name1;
this.type = type1;
this.ref = ref1;
def = atts.getValue("", "default");
if (def == null) {
def = atts.getValue(namespaceURI, "default");
}
fixed = atts.getValue("", "fixed");
if (fixed == null) {
fixed = atts.getValue(namespaceURI, "fixed");
}
// form -- Ignore
String use1 = atts.getValue("", "use");
if (use1 == null) {
use1 = atts.getValue(namespaceURI, "use");
}
this.use = findUse(use1);
}
/**
* @see org.geotools.xml.XSIElementHandler#getLocalName()
*/
public String getLocalName() {
return LOCALNAME;
}
/**
* <p>
* Convert the 'use' attribute to an int mask
* </p>
*
* @param use
*
*/
public static int findUse(String use) {
if ("optional".equalsIgnoreCase(use)) {
return OPTIONAL;
}
if ("prohibited".equalsIgnoreCase(use)) {
return PROHIBITED;
}
if ("required".equalsIgnoreCase(use)) {
return REQUIRED;
}
return -1;
}
/**
* <p>
* converts an int mask representing use to the string representation
* </p>
*
* @param use
*
*/
public static String writeUse(int use) {
switch (use) {
case OPTIONAL:
return "optional";
case PROHIBITED:
return "prohibited";
case REQUIRED:
return "required";
default:
return null;
}
}
/**
* <p>
* Returns the attribute name
* </p>
*
*/
public String getName() {
return name;
}
/**
* <p>
* creates a smaller simpler version
* </p>
*
* @param parent
*
*
* @throws SAXException
*/
protected Attribute compress(SchemaHandler parent)
throws SAXException {
if (cache != null) {
return cache;
}
// a.form = form; TODO add form support?
SimpleType st = null;
String name1 = this.name;
String def1 = this.def;
String fixed1 = this.fixed;
int use1 = this.use;
if (simpleType != null) {
st = simpleType.compress(parent);
} else {
if ((ref != null) && !"".equalsIgnoreCase(ref)) {
Attribute refA = parent.lookUpAttribute(ref);
if (refA == null) {
throw new SAXException("Attribute '" + ref
+ "' was refered and not found");
}
st = refA.getSimpleType();
name1 = refA.getName();
use1 = use1 | refA.getUse();
if ((def1 == null) || "".equalsIgnoreCase(def1)) {
def1 = refA.getDefault();
}
if ((fixed1 == null) || "".equalsIgnoreCase(fixed1)) {
fixed1 = refA.getFixed();
}
} else if ((type != null) && (!"".equalsIgnoreCase(type))) {
// look it up --- find it
st = parent.lookUpSimpleType(type);
}
}
cache = new AttributeGT(id, name1, parent.getTargetNamespace(), st,
use1, def1, fixed1, false);
id = type = ref = null;
return cache;
}
/**
* @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
}
}