/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved. * This code is licensed under the GPL 2.0 license, availible at the root * application directory. */ /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved. * This code is licensed under the GPL 2.0 license, availible at the root * application directory. */ package org.vfny.geoserver.config; import org.opengis.feature.type.AttributeDescriptor; import org.vfny.geoserver.global.dto.AttributeTypeInfoDTO; import org.vfny.geoserver.global.xml.NameSpaceElement; import org.vfny.geoserver.global.xml.NameSpaceTranslator; import org.vfny.geoserver.global.xml.NameSpaceTranslatorFactory; /** * Allows editing of AttributeTypeInfo. * * <p> * Represents most of a xs:element for an XMLSchema. * </p> * * <p> * we have three types of information to store, Schema defined types, * references and extentions on types. If the type represented is either a * reference or a Schema defined type then isRef should be true. * </p> * * <p> * Non-complex types are of the form: * </p> * * <ul> * <li> * <code>{element name='test' type='xs:string'/}</code> * </li> * <li> * <code>{element name='test' type='gml:PointType'/}</code> * </li> * </ul> * * <p> * These cases have their type name stored in this.type * </p> * * <p> * For complex types such as:<pre><code> * {element name='test' * {xs:complexContent} * {xs:extension base="gml:AbstractFeatureType"} * {xs:sequence} * {xs:element name="id" * type="xs:string" * minOccurs="0"/} * {xs:element ref="gml:pointProperty" * minOccurs="0"/} * {/xs:sequence} * {/xs:extension} * {/xs:complexContent} * {/element} * </code></pre> * The type will be equals to "(xml fragment)" and * fragment contains a similar to above. * </p> * * <p> * minOccurs, maxOccurs and nillable are all attributes for all cases. There is * more stuff in the XMLSchema spec but we don't care to parse it out right now. * </p> * * @author dzwiers, Refractions Research, Inc. * @version $Id$ */ public class AttributeTypeInfoConfig { /** Value of getType() used to indicate that fragement is in use */ public static final String TYPE_FRAGMENT = "(xml fragment)"; /** * XML Fragment used to define stuff. * * <p> * This property is only used with getType() is equals to "(xml fragment)". * </p> * * <p> * baseGMLTypes can only be used in your XML fragment. * </p> */ private String fragment; /** * Maxmium number of occurances of this attribute in a feature. * * <p> * For Features based on the Simple Feature Specification this should be a * value of 1. If the attribute is optional it should still be 1, although * often optional is represented by allowing the Attribute to be * <code>nillable</code>. * </p> * * <p> * Common Min..Max Occurs values: * </p> * * <ul> * <li> * 0..<b>1</b>: attribute is optional * </li> * <li> * 1..<b>1</b>: attribute is required (usual for Simple Features) * </li> * <li> * 0..<b>N</b>: attribute forms a list that may be empty * </li> * </ul> * * * @see AttributeTypeInfoDTO.isNillable */ private int maxOccurs; /** attribute min occurs */ private int minOccurs; /** attribute name */ private final String name; /** * Indicate if the attribute is allowed to be <code>null</code>. * * <p> * Nillable is often used to indicate that an attribute is optional. The * use of minOccurs and maxOccurs may be a more correct way to indicate * optional attribtues. * </p> * * @see AttributeTypeInfoDTO.minOccurs * @see AttributeTypeInfoDTO.maxOccurs */ private boolean nillable; /** * Element type, a well-known gml or xs type or <code>TYPE_FRAGMENT</code>. * * <p> * If getType is equals to TYPE_FRAGMENT please consult getFragment() to * examin the actual user's definition. * </p> * * <p> * Other than that getType should be one of the constants defined by * GMLUtils. * </p> */ public String type; /** * Set up AttributeTypeInfo based on attributeType. * * <p> * Set up is determined by the AttributeTypeInfoDTO( AttributeDescriptor ) * constructor. This allows all Schema generation to be acomplished in the * same palce. * </p> * * @param attributeType GeoTools2 attributeType used for configuration */ public AttributeTypeInfoConfig(AttributeDescriptor attributeType) { name = attributeType.getLocalName(); minOccurs = 1; maxOccurs = 1; NameSpaceTranslatorFactory nsFactory = NameSpaceTranslatorFactory.getInstance(); NameSpaceTranslator nst = nsFactory.getNameSpaceTranslator("xs"); NameSpaceElement nse = nst.getElement(name); if (nse == null) { nse = nst.getDefaultElement(attributeType.getType().getBinding()); } if (nse == null) { nst = nsFactory.getNameSpaceTranslator("gml"); nse = nst.getElement(name); if (nse == null) { nse = nst.getDefaultElement(attributeType.getType().getBinding()); } } //System.out.println("creating new atypininfig for: " + attributeType + // ", nse = " + nse); //if (nse != null) System.out.println(", nse type = " + nse.getTypeDefName()); fragment = "<!-- definition for " + attributeType.getType() + " -->"; if (nse == null) { type = TYPE_FRAGMENT; } else { type = nse.getTypeDefName(); fragment = ""; } } /** * Set up AttributeTypeInfo based on Data Transfer Object. * * @param dto AttributeTypeInfoDTO used for configuration */ public AttributeTypeInfoConfig(AttributeTypeInfoDTO dto) { name = dto.getName(); if (dto.isComplex()) { type = TYPE_FRAGMENT; fragment = dto.getType(); } else { type = dto.getType(); fragment = ""; } minOccurs = dto.getMinOccurs(); maxOccurs = dto.getMaxOccurs(); nillable = dto.isNillable(); } /** * XML Fragment used to define stuff. * * <p> * This property is only used with getType() is equals to "(xml fragment)". * </p> * * <p> * baseGMLTypes can only be used in your XML fragment. * </p> * * @return Returns the fragment. */ public String getFragment() { return fragment; } /** * getMaxOccurs purpose. * * <p> * The max number of occurences for this element. * </p> * * @return max number of occurences */ public int getMaxOccurs() { return maxOccurs; } /** * getMinOccurs purpose. * * <p> * the min number of occurences for this element * </p> * * @return min number of occurences */ public int getMinOccurs() { return minOccurs; } /** * getName purpose. * * <p> * returns the element name * </p> * * @return the element name */ public String getName() { return name; } /** * Element type, a well-known gml or xs type or <code>TYPE_FRAGMENT</code>. * * <p> * If getType is equals to <code>TYPE_FRAGMENT</code> please consult * getFragment() to examine the actual user's definition. * </p> * * <p> * Other than that getType should be one of the constants defined by * GMLUtils. * </p> * * @return The element, or <code>TYPE_FRAGMENT</code> */ public String getType() { return type; } /** * Indicate if the attribute is allowed to be <code>null</code>. * * <p> * Nillable is often used to indicate that an attribute is optional. The * use of minOccurs and maxOccurs may be a more correct way to indicate * optional attribtues. * </p> * * @return <code>true </code> to indicate attribute is alloed to be * <code>null</code> * * @see AttributeTypeInfoDTO.setMinOccurs * @see AttributeTypeInfoDTO.setMaxOccurs */ public boolean isNillable() { return nillable; } /** * XML Fragment used to define stuff. * * <p> * This property is only used with getType() is equals to "(xml fragment)". * </p> * * <p> * baseGMLTypes can only be used in your XML fragment. * </p> * * @param fragment The fragment to set. */ public void setFragment(String fragment) { this.fragment = fragment; } /** * Maxmium number of occurances of this attribute in a feature. * * <p> * For Features based on the Simple Feature Specification this should be a * value of 1. If the attribute is optional it should still be 1, although * often optional is represented by allowing the Attribute to be * <code>nillable</code>. * </p> * * <p> * Common Min..Max Occurs values: * </p> * * <ul> * <li> * 0..<b>1</b>: attribute is optional * </li> * <li> * 1..<b>1</b>: attribute is required (usual for Simple Features) * </li> * <li> * 0..<b>N</b>: attribute forms a list that may be empty * </li> * </ul> * * * @param max The maximum number of occurances * * @see AttributeTypeInfoDTO.isNillable */ public void setMaxOccurs(int max) { maxOccurs = max; } /** * Minimum number of occrances of this attribute in a feature. * * <p> * For Features based on the Simple Feture Specification this should be a * value of 1. If the attribute is optional is should be 0, although often * optional is represented by allowing the attribute to be nillable. * </p> * Common Min..Max Occurs values: * * <ul> * <li> * <b>0</b>..1: attribute is optional * </li> * <li> * <b>1</b>..1: attribute is required (usual for Simple Features) * </li> * <li> * <b>0</b>..N: attribute forms a list that may be empty * </li> * </ul> * * * @param min The minimum number of occurances * * @see AttributeTypeInfoDTO.isNillable */ public void setMinOccurs(int min) { minOccurs = min; } /** * Indicate if the attribute is allowed to be <code>null</code>. * * <p> * Nillable is often used to indicate that an attribute is optional. The * use of minOccurs and maxOccurs may be a more correct way to indicate * optional attribtues. * </p> * * @param nillable <code>true </code> to indicate attribute is alloed to be * <code>null</code> * * @see AttributeTypeInfoDTO.setMinOccurs * @see AttributeTypeInfoDTO.setMaxOccurs */ public void setNillable(boolean nillable) { this.nillable = nillable; } /** * Element type, a well-known gml or xs type or <code>TYPE_FRAGMENT</code>. * * <p> * If getType is equals to <code>TYPE_FRAGMENT</code> please consult * getFragment() to examin the actual user's definition. <br> * Other than that getType should be one of the constants defined by * GMLUtils. * </p> * * @param type DOCUMENT ME! */ public void setType(String type) { this.type = type; } public AttributeTypeInfoDTO toDTO() { AttributeTypeInfoDTO dto = new AttributeTypeInfoDTO(); dto.setNillable(nillable); dto.setName(name); dto.setMaxOccurs(maxOccurs); dto.setMinOccurs(minOccurs); if (type != TYPE_FRAGMENT) { dto.setComplex(false); dto.setType(type); } else { dto.setComplex(true); dto.setType(fragment); } return dto; } }