/* * 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.schema.impl; import java.io.IOException; import java.net.URI; import java.text.DateFormat; import java.text.ParseException; import java.util.Date; 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.schema.Attribute; import org.geotools.xml.schema.AttributeValue; import org.geotools.xml.schema.Element; import org.geotools.xml.schema.ElementValue; import org.geotools.xml.schema.Facet; import org.geotools.xml.schema.SimpleType; import org.xml.sax.Attributes; import org.xml.sax.SAXException; /** * <p> * DOCUMENT ME! * </p> * * @author dzwiers * * @source $URL$ */ public class SimpleTypeGT implements SimpleType { // file visible to avoid set* methods private int finaL; private String id; private String name; private URI namespace; private SimpleType[] parents = null; private int type = 0; private Facet[] constraints; private SimpleTypeGT() { // should not be called } /** * Creates a new SimpleTypeGT object. * * @param id DOCUMENT ME! * @param name DOCUMENT ME! * @param namespace DOCUMENT ME! * @param type DOCUMENT ME! * @param parents DOCUMENT ME! * @param constraints DOCUMENT ME! * @param finaL DOCUMENT ME! */ public SimpleTypeGT(String id, String name, URI namespace, int type, SimpleType[] parents, Facet[] constraints, int finaL) { this.id = id; this.name = name; this.namespace = namespace; this.parents = parents; this.type = type; this.constraints = constraints; if(constraints!=null){ for(int i=0;i<constraints.length;i++) if(constraints[i] == null) throw new NullPointerException(name+" constraint #"+i+" is null"); } } /** * @see org.geotools.xml.xsi.Type#getInstanceType() */ public Class getInstanceType() { // if it's a union ... deal with it i guess return parents[0].getInstanceType(); } /** * @see org.geotools.xml.schema.Type#findChildElement(java.lang.String) */ public Element findChildElement(String name1) { return null; // will never happen } /** * @see org.geotools.xml.xsi.SimpleType#getFinal() */ public int getFinal() { return finaL; } /** * @see org.geotools.xml.xsi.SimpleType#getId() */ public String getId() { return id; } /** * @see org.geotools.xml.xsi.Type#getLocalName() */ public String getName() { return name; } /** * @see org.geotools.xml.xsi.Type#getLocalName() */ public URI getNamespace() { return namespace; } /** * @see org.geotools.xml.xsi.Type#getParent() */ public SimpleType[] getParents() { return parents; } /** * <p> * This method ignores the attributes from the xml node * </p> * @throws SAXException * @throws OperationNotSupportedException * * @see schema.Type#getValue(java.lang.Object, org.xml.sax.Attributes) */ public Object getValue(Element element, ElementValue[] value, Attributes attrs, Map hints) throws OperationNotSupportedException, SAXException { if ((value == null) || (value.length != 1)) { throw new SAXException( "can only have one text value ... and one is required"); } if (type == UNION) { return getUnionValue(element, value[0], attrs, hints); } if (type == LIST) { return getListValue(element, value[0], attrs, hints); } return getRestValue(element, value[0], attrs, hints); } /* * Helper for getValue(Element,ElementValue[]) */ private Object getUnionValue(Element element, ElementValue value, Attributes attrs, Map hints) throws OperationNotSupportedException, SAXException { if (parents == null) { return null; } ElementValue[] valss = new ElementValue[1]; valss[0] = value; for (int i = 0; i < parents.length; i++) { Object o = parents[0].getValue(element, valss, attrs, hints); if (o != null) { return o; } } return null; } /* * Helper for getValue(Element,ElementValue[]) */ private Object getListValue(Element element, ElementValue value, Attributes attrs, Map hints) throws OperationNotSupportedException, SAXException { if ((parents == null) || (parents[0] == null)) { return null; } String[] vals = ((String) value.getValue()).split("\\s"); List l = new LinkedList(); ElementValueGT[] valss = new ElementValueGT[1]; for (int i = 0; i < vals.length; i++) { valss[0] = new ElementValueGT(value.getElement(), vals[i]); l.add(parents[0].getValue(element, valss, attrs, hints)); } valss[0] = new ElementValueGT(value.getElement(), l); return valss[0]; } /* * Helper for getValue(Element,ElementValue[]) */ private Object getRestValue(Element element, ElementValue value, Attributes attrs, Map hints) throws OperationNotSupportedException, SAXException { if ((parents == null) || (parents[0] == null)) { return null; } if (constraints == null) { return null; } if (constraints.length == 0) { ElementValue[] t = new ElementValue[1]; t[0] = value; return parents[0].getValue(element, t, attrs, hints); } String val = (String) value.getValue(); if (val !=null && constraints[0].getFacetType() == Facet.ENUMERATION) { for (int i = 0; i < constraints.length; i++) { if (val.equalsIgnoreCase(constraints[i].getValue())) { ElementValue[] t = new ElementValue[1]; t[0] = value; return parents[0].getValue(element, t, attrs, hints); } } return null; } Number nval = null; Date dval = null; ElementValue[] t = new ElementValue[1]; t[0] = value; Object o = parents[0].getValue(element, t, attrs, hints); if (o instanceof Number) { nval = (Number) o; } if (o instanceof Date) { dval = (Date) o; } // check each constraint for (int i = 0; i < constraints.length; i++) { switch (constraints[i].getFacetType()) { case Facet.ENUMERATION: /*throw new SAXException( "cannot have enumerations mixed with other facets.");*/ break; case Facet.FRACTIONDIGITS: int decimals = val.length() - val.indexOf("."); int maxDec = Integer.parseInt(constraints[i].getValue()); if (decimals > maxDec) { throw new SAXException("Too many decimal places"); } break; case Facet.LENGTH: int maxLength = Integer.parseInt(constraints[i].getValue()); if (val.length() != maxLength) { throw new SAXException("Too long places"); } break; case Facet.MAXEXCLUSIVE: if (nval != null) { Double max = Double.valueOf(constraints[i].getValue()); if (nval.doubleValue() > max.doubleValue()) { throw new SAXException("Too large a value"); } } if (dval != null) { Date max; try { max = DateFormat.getDateTimeInstance().parse(constraints[i] .getValue()); } catch (ParseException e) { throw new SAXException(e); } if (dval.after(max)) { throw new SAXException("Too large a value"); } } break; case Facet.MAXINCLUSIVE: if (nval != null) { Double max = Double.valueOf(constraints[i].getValue()); if (nval.doubleValue() >= max.doubleValue()) { throw new SAXException("Too large a value"); } } if (dval != null) { Date max; try { max = DateFormat.getDateTimeInstance().parse(constraints[i] .getValue()); } catch (ParseException e) { throw new SAXException(e); } if (dval.compareTo(max) > 0) { throw new SAXException("Too large a value"); } } case Facet.MAXLENGTH: maxLength = Integer.parseInt(constraints[i].getValue()); if (val.length() > maxLength) { throw new SAXException("Too long places"); } break; case Facet.MINEXCLUSIVE: if (nval != null) { Double max = Double.valueOf(constraints[i].getValue()); if (nval.doubleValue() < max.doubleValue()) { throw new SAXException("Too large a value"); } } if (dval != null) { Date max; try { max = DateFormat.getDateTimeInstance().parse(constraints[i] .getValue()); } catch (ParseException e) { throw new SAXException(e); } if (dval.before(max)) { throw new SAXException("Too large a value"); } } case Facet.MININCLUSIVE: if (nval != null) { Double max = Double.valueOf(constraints[i].getValue()); if (nval.doubleValue() <= max.doubleValue()) { throw new SAXException("Too large a value"); } } if (dval != null) { Date max; try { max = DateFormat.getDateTimeInstance().parse(constraints[i] .getValue()); } catch (ParseException e) { throw new SAXException(e); } if (dval.compareTo(max) < 0) { throw new SAXException("Too large a value"); } } case Facet.MINLENGTH: maxLength = Integer.parseInt(constraints[i].getValue()); if (val.length() < maxLength) { throw new SAXException("Too short places"); } break; case Facet.PATTERN: if (val.split(constraints[i].getValue()).length != 1) { throw new SAXException("Does not match pattern"); } break; case Facet.TOTALDIGITS: maxLength = Integer.parseInt(constraints[i].getValue()) + 1; if (val.length() > maxLength) { throw new SAXException("Too many digits"); } break; } } return o; } /** * @see org.geotools.xml.schema.SimpleType#getChildType() */ public int getChildType() { return type; } /** * @see org.geotools.xml.schema.SimpleType#getFacets() */ public Facet[] getFacets() { return constraints; } /** * @throws OperationNotSupportedException * @see org.geotools.xml.schema.SimpleType#toAttribute(org.geotools.xml.schema.Attribute, * java.lang.Object, java.util.Map) */ public AttributeValue toAttribute(Attribute attribute, Object value, Map hints) throws OperationNotSupportedException { if (value == null) { return null; } if (type == UNION) { for (int i = 0; i < parents.length; i++) { // finds first that works // TODO check that 'equals' works here if (parents[i].equals(attribute.getSimpleType()) && parents[i].canCreateAttributes(attribute, value, hints)) { return parents[i].toAttribute(attribute, value, hints); } } return parents[0].toAttribute(attribute, value, hints); } if (type == LIST) { List l = (List) value; Iterator i = l.iterator(); String s = ""; if (i.hasNext()) { Object t = parents[0].toAttribute(attribute, i.next(), hints) .getValue(); s = t.toString(); while (i.hasNext()) { t = parents[0].toAttribute(attribute, i.next(), hints) .getValue(); s = s + " " + t.toString(); } } return new AttributeValueGT(attribute, s); } return parents[0].toAttribute(attribute, value, hints); } /** * @see org.geotools.xml.schema.SimpleType#canCreateAttributes(org.geotools.xml.schema.Attribute, * java.lang.Object, java.util.Map) */ public boolean canCreateAttributes(Attribute attribute, Object value, Map hints) { if (value == null) { return false; } if (type == UNION) { for (int i = 0; i < parents.length; i++) { // finds first that works // TODO check that 'equals' works here if (parents[i].equals(attribute.getSimpleType()) && parents[i].canCreateAttributes(attribute, value, hints)) { return true; } } return false; } if (type == LIST) { return parents[0].canCreateAttributes(attribute, value, hints); } return parents[0].canCreateAttributes(attribute, value, hints); } /** * @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 (value == null) { return false; } if (type == UNION) { for (int i = 0; i < parents.length; i++) { // finds first that works // TODO check that 'equals' works here if (parents[i].equals(element.getType()) && parents[i].canEncode(element, value, hints)) { return true; } } return false; } if (type == LIST) { return parents[0].canEncode(element, value, hints); } return parents[0].canEncode(element, value, hints); } /** * @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 (value == null) { return; } if (type == UNION) { for (int i = 0; i < parents.length; i++) { // finds first that works // TODO check that 'equals' works here if (parents[i].equals(element.getType()) && parents[i].canEncode(element, value, hints)) { parents[i].encode(element, value, output, hints); } return; } parents[0].encode(element, value, output, hints); return; } if (type == LIST) { List l = (List) value; Iterator i = l.iterator(); String s = ""; if (i.hasNext()) { Object t = parents[0].toAttribute(new AttributeGT(null, null, namespace, parents[0], 0, null, null, false), value, hints).getValue(); s = t.toString(); while (i.hasNext()) { t = parents[0].toAttribute(new AttributeGT(null, null, namespace, parents[0], 0, null, null, false), value, hints).getValue(); s = s + " " + t.toString(); } } parents[0].encode(element, s, output, hints); return; } parents[0].encode(element, value, output, hints); } }