001: /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
002: * This code is licensed under the GPL 2.0 license, availible at the root
003: * application directory.
004: */
005: package org.geoserver.wfs.xml;
006:
007: import net.opengis.wfs.PropertyType;
008: import org.eclipse.xsd.XSDElementDeclaration;
009: import org.eclipse.xsd.XSDFacet;
010: import org.eclipse.xsd.XSDFactory;
011: import org.eclipse.xsd.XSDParticle;
012: import org.eclipse.xsd.XSDTypeDefinition;
013: import org.geotools.xml.PropertyExtractor;
014: import org.geotools.xml.SchemaIndex;
015: import org.geotools.xml.Schemas;
016: import org.opengis.feature.type.Name;
017: import java.util.ArrayList;
018: import java.util.Arrays;
019: import java.util.Iterator;
020: import java.util.List;
021: import javax.xml.namespace.QName;
022:
023: /**
024: * Extracts properties from an instance of {@link PropertyType}.
025: * <p>
026: * In a sense this class retypes {@link PropertyType#getValue()} to a new xml
027: * type so that the encoder can encode it properly.
028: * </p>
029: * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
030: *
031: */
032: public class PropertyTypePropertyExtractor implements PropertyExtractor {
033: /**
034: * index for looking up xml types
035: */
036: SchemaIndex index;
037:
038: public PropertyTypePropertyExtractor(SchemaIndex index) {
039: this .index = index;
040: }
041:
042: public boolean canHandle(Object object) {
043: return object instanceof PropertyType;
044: }
045:
046: public List properties(Object object, XSDElementDeclaration element) {
047: PropertyType property = (PropertyType) object;
048:
049: List properties = new ArrayList(2);
050:
051: //the Name particle we can use as is
052: properties.add(new Object[] {
053: Schemas.getChildElementParticle(element.getType(),
054: "Name", false), property.getName() });
055:
056: //the Value particle we must retype
057:
058: //first guess its type
059: QName newTypeName = guessValueType(property.getValue());
060: XSDTypeDefinition type = (newTypeName != null) ? index
061: .getTypeDefinition(newTypeName) : null;
062:
063: if (type != null) {
064: //create a new particle based on the new type
065: XSDElementDeclaration value = XSDFactory.eINSTANCE
066: .createXSDElementDeclaration();
067: value.setName("Value");
068: value.setTypeDefinition(type);
069:
070: XSDParticle particle = XSDFactory.eINSTANCE
071: .createXSDParticle();
072: particle.setMinOccurs(1);
073: particle.setMaxOccurs(1);
074: particle.setContent(value);
075:
076: properties
077: .add(new Object[] { particle, property.getValue() });
078: } else {
079: //coudl not determine new type, just fall back to xs:anyType
080: Object[] p = new Object[] {
081: Schemas.getChildElementParticle(element.getType(),
082: "Value", false), property.getValue() };
083: properties.add(p);
084: }
085:
086: return properties;
087: }
088:
089: private QName guessValueType(Object value) {
090: Class clazz = value.getClass();
091: List profiles = Arrays.asList(new Object[] { new XSProfile(),
092: new GML3Profile() });
093:
094: for (Iterator it = profiles.iterator(); it.hasNext();) {
095: TypeMappingProfile profile = (TypeMappingProfile) it.next();
096: Name name = profile.name(clazz);
097:
098: if (name != null) {
099: return new QName(name.getNamespaceURI(), name
100: .getLocalPart());
101: }
102: }
103:
104: return null;
105: }
106: }
|