@SuppressWarnings("unchecked") protected void importSchema(Schema schema) { for (Iterator it = schema.entrySet().iterator(); it.hasNext(); ) { Map.Entry entry = (Entry) it.next(); Name key = (Name) entry.getKey(); Object value = entry.getValue(); if (typeRegistry.containsKey(key)) { LOGGER.finer( "Ignoring " + key + " as it already exists. type " + value.getClass().getName()); } else { LOGGER.finer("Importing " + key + " of type " + value.getClass().getName()); if (value instanceof AttributeType) { AttributeType type = (AttributeType) value; register(type, false); } else if (value instanceof AttributeDescriptor) { AttributeDescriptor descriptor = (AttributeDescriptor) value; register(descriptor); } } } LOGGER.fine("Schema " + schema.getURI() + " imported successfully"); }
public AttributeDescriptor getDescriptor( final Name descriptorName, CoordinateReferenceSystem crs) { AttributeDescriptor descriptor = descriptorRegistry.get(descriptorName); if (descriptor == null) { // top level elements XSDElementDeclaration elemDecl = getElementDeclaration(descriptorName); descriptor = createAttributeDescriptor(null, elemDecl, crs); LOGGER.finest("Registering attribute descriptor " + descriptor.getName()); register(descriptor); } return descriptor; }
/** * Creates an {@link AttributeType} that matches the xsd type definition as much as possible. * * <p>The original type definition given by the {@link XSDTypeDefinition} is kept as * AttributeType's metadata stored as a "user data" property using <code>XSDTypeDefinition.class * </code> as key. * * <p>If it is a complex attribute, it will contain all the properties declared in the <code> * typeDefinition</code>, as well as all the properties declared in its super types. TODO: handle * the case where the extension mechanism is restriction. * * @param assignedName * @param typeDefinition * @return */ private AttributeType createType( final Name assignedName, final XSDTypeDefinition typeDefinition, CoordinateReferenceSystem crs, boolean anonymous) { AttributeType attType; // ///////// if (processingTypes.contains(assignedName)) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("Recursion found for type " + assignedName + ". Proxying it."); } attType = createProxiedType( assignedName, typeDefinition, anonymous ? anonTypeRegistry : typeRegistry); return attType; } processingTypes.push(assignedName); // ////////// final XSDTypeDefinition baseType = typeDefinition.getBaseType(); AttributeType superType = null; if (baseType != null) { String targetNamespace = baseType.getTargetNamespace(); String name = baseType.getName(); if (name != null) { Name baseTypeName = new NameImpl(targetNamespace, name); superType = getAttributeType(baseTypeName, baseType, crs); } } else { LOGGER.warning(assignedName + " has no super type"); } if (typeDefinition instanceof XSDComplexTypeDefinition) { XSDComplexTypeDefinition complexTypeDef; complexTypeDef = (XSDComplexTypeDefinition) typeDefinition; boolean includeParents = true; List<XSDElementDeclaration> children = Schemas.getChildElementDeclarations(typeDefinition, includeParents); final Collection<PropertyDescriptor> schema = new ArrayList<PropertyDescriptor>(children.size()); XSDElementDeclaration childDecl; AttributeDescriptor descriptor; for (Iterator it = children.iterator(); it.hasNext(); ) { childDecl = (XSDElementDeclaration) it.next(); try { descriptor = createAttributeDescriptor(complexTypeDef, childDecl, crs); } catch (NoSuchElementException e) { String msg = "Failed to create descriptor for '" + childDecl.getTargetNamespace() + "#" + childDecl.getName() + " from container '" + typeDefinition.getTargetNamespace() + "#" + typeDefinition.getName() + "'"; NoSuchElementException nse = new NoSuchElementException(msg); nse.initCause(e); throw nse; } schema.add(descriptor); } if (includeAttributes) { for (XSDAttributeUse attgcontent : complexTypeDef.getAttributeUses()) { XSDAttributeDeclaration att = attgcontent.getContent(); descriptor = createAttributeDescriptor( getXmlAttributeType(), null, new NameImpl(null, "@" + att.getName()), 0, 1, false, null); schema.add(descriptor); } } // set substitution group for descriptors here for (XSDElementDeclaration elemDecl : children) { if (elemDecl.isElementDeclarationReference()) { elemDecl = elemDecl.getResolvedElementDeclaration(); } PropertyDescriptor att = null; for (PropertyDescriptor desc : schema) { if (desc.getName().getLocalPart().equals(elemDecl.getName()) && desc.getName().getNamespaceURI().equals(elemDecl.getTargetNamespace())) { att = desc; break; } } setSubstitutionGroup(complexTypeDef, elemDecl, att, crs); } attType = createComplexAttributeType(assignedName, schema, complexTypeDef, superType); } else { Class<?> binding = String.class; boolean isIdentifiable = false; boolean isAbstract = false; List<Filter> restrictions = Collections.emptyList(); InternationalString description = null; attType = typeFactory.createAttributeType( assignedName, binding, isIdentifiable, isAbstract, restrictions, superType, description); } attType.getUserData().put(XSDTypeDefinition.class, typeDefinition); processingTypes.pop(); // even if the type is anonymous, it still has to be registered somewhere because // it's needed for the proxied types to find them. That's why we have 2 registries, // typeRegistry // and anonTypeRegistry. TypeRegistry is the global one, since anonymous types are meant to // be // local and shouldn't be searchable. register(attType, anonymous); return attType; }
public void register(AttributeType type) { register(type, false); }
static { // prepare the common namespace support NAMESPACES = new NamespaceSupport(); NAMESPACES.declarePrefix("csw", CSW.NAMESPACE); NAMESPACES.declarePrefix("rim", "urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0"); NAMESPACES.declarePrefix("dc", DC.NAMESPACE); NAMESPACES.declarePrefix("dct", DCT.NAMESPACE); NAMESPACES.declarePrefix("ows", OWS.NAMESPACE); NAMESPACES.declarePrefix("ogc", OGC.NAMESPACE); // prepare the CSW record related types FeatureTypeFactory typeFactory = new FeatureTypeFactoryImpl(); TypeBuilder builder = new TypeBuilder(typeFactory); // create the SimpleLiteral type builder.setNamespaceURI(DC.SimpleLiteral.getNamespaceURI()); builder.name("scheme"); builder.bind(URI.class); AttributeType schemeType = builder.attribute(); builder.setNamespaceURI(DC.SimpleLiteral.getNamespaceURI()); builder.name("value"); builder.bind(Object.class); AttributeType valueType = builder.attribute(); builder.setNillable(true); builder.addAttribute("scheme", schemeType); builder.addAttribute("value", valueType); builder.setName("SimpleLiteral"); SIMPLE_LITERAL = builder.complex(); builder.setNamespaceURI(OWS.NAMESPACE); builder.setName("BoundingBoxType"); builder.setBinding(MultiPolygon.class); builder.crs(DEFAULT_CRS); AttributeType bboxType = builder.geometry(); EmfComplexFeatureReader reader = EmfComplexFeatureReader.newInstance(); SchemaIndex index = null; try { index = reader.parse(new URL("http://schemas.opengis.net/csw/2.0.2/record.xsd")); } catch (IOException e) { // this is fatal throw new RuntimeException("Failed to parse CSW Record Schemas", e); } FeatureTypeRegistry featureTypeRegistry = new FeatureTypeRegistry( NAMESPACES, typeFactory, new RecordFeatureTypeRegistryHelper("RecordType")); featureTypeRegistry.register(SIMPLE_LITERAL); featureTypeRegistry.register(bboxType); featureTypeRegistry.addSchemas(index); RECORD_TYPE = (FeatureType) featureTypeRegistry.getAttributeType(new NameImpl(CSW.NAMESPACE, "RecordType")); RECORD_DESCRIPTOR = featureTypeRegistry.getDescriptor(new NameImpl(CSW.NAMESPACE, "Record"), null); RECORD_BBOX_DESCRIPTOR = (AttributeDescriptor) RECORD_TYPE.getDescriptor(RECORD_BBOX_NAME); DC_ELEMENT = (AttributeDescriptor) RECORD_TYPE.getDescriptor(DC_ELEMENT_NAME); // --- // setup the list of names for brief and summary records BRIEF_ELEMENTS = createNameList(NAMESPACES, "dc:identifier", "dc:title", "dc:type", "ows:BoundingBox"); SUMMARY_ELEMENTS = createNameList( NAMESPACES, "dc:identifier", "dc:title", "dc:type", "dc:subject", "dc:format", "dc:relation", "dct:modified", "dct:abstract", "dct:spatial", "ows:BoundingBox"); // create the xpath extender that fill adapt dc:title to dc:title/dc:value PATH_EXTENDER = new CRSRecordProjectyPathAdapter(NAMESPACES); // qualified the xpath in the filters NSS_QUALIFIER = new NamespaceQualifier(NAMESPACES); // applies the default CRS to geometry filters coming from the outside CRS_DEFAULTER = new DefaultCRSFilterVisitor(FF, DEFAULT_CRS); // transforms geometry filters into the internal representation CRS_REPROJECTOR = new ReprojectingFilterVisitor(FF, RECORD_TYPE); // build queriables list QUERIABLES = createNameList( NAMESPACES, "dc:contributor", "dc:source", "dc:language", "dc:title", "dc:subject", "dc:creator", "dc:type", "ows:BoundingBox", "dct:modified", "dct:abstract", "dc:relation", "dc:date", "dc:identifier", "dc:publisher", "dc:format", "csw:AnyText", "dc:rights"); }