}
public final XSDSchema buildSchemaInternal(FeatureTypeInfo[] featureTypeInfos, String baseUrl,
boolean resolveAppSchemaImports) throws IOException {
XSDFactory factory = XSDFactory.eINSTANCE;
XSDSchema schema = factory.createXSDSchema();
schema.setSchemaForSchemaQNamePrefix("xsd");
schema.getQNamePrefixToNamespaceMap().put("xsd", XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001);
schema.setElementFormDefault(XSDForm.get(XSDForm.QUALIFIED));
//group the feature types by namespace
HashMap ns2featureTypeInfos = new HashMap();
for (int i = 0; i < featureTypeInfos.length; i++) {
String prefix = featureTypeInfos[i].getNamespace().getPrefix();
List l = (List) ns2featureTypeInfos.get(prefix);
if (l == null) {
l = new ArrayList();
}
l.add(featureTypeInfos[i]);
ns2featureTypeInfos.put(prefix, l);
}
if (baseUrl == null)
baseUrl = gs.getService(WFSInfo.class).getSchemaBaseURL();
if (ns2featureTypeInfos.entrySet().size() == 0) {
// for WFS 2.0 encoding to work we need to have at least a dependency on GML and
// a target namespace. We are going to use the GML one.
importGMLSchema(schema, factory, baseUrl);
schema.setTargetNamespace(gmlSchema().getTargetNamespace());
} else if (ns2featureTypeInfos.entrySet().size() == 1) {
// only 1 namespace, write target namespace out
String targetPrefix = (String) ns2featureTypeInfos.keySet().iterator().next();
String targetNamespace = catalog.getNamespaceByPrefix(targetPrefix).getURI();
schema.setTargetNamespace(targetNamespace);
schema.getQNamePrefixToNamespaceMap().put(targetPrefix, targetNamespace);
// add secondary namespaces from catalog
for (NamespaceInfo nameSpaceinfo : catalog.getNamespaces()) {
if (!schema.getQNamePrefixToNamespaceMap().containsKey(nameSpaceinfo.getPrefix())) {
schema.getQNamePrefixToNamespaceMap().put(nameSpaceinfo.getPrefix(),
nameSpaceinfo.getURI());
}
}
// would result in some xsd:include or xsd:import if schema location is specified
try {
FeatureType featureType = featureTypeInfos[0].getFeatureType();
Object schemaUri = featureType.getUserData().get("schemaURI");
if (schemaUri != null && schemaUri instanceof Map) {
// should always be a Map.. set in AppSchemaDataAccessConfigurator
// impose iteration order
@SuppressWarnings("unchecked")
Map<String, String> schemaURIs = new TreeMap<String, String>(
(Map<String, String>) schemaUri);
// schema is supplied by the user.. just include the top level schema instead of
// building the type
if (!findTypeInSchema(featureTypeInfos[0], schema, factory)) {
// map of namespace to schemaLocation used to prevent duplicate imports
Map<String, String> imports = new HashMap<String, String>();
// set of schemaLocations used to prevent duplicate includes
Set<String> includes = new HashSet<String>();
for (String namespace : schemaURIs.keySet()) {
addReference(schema, factory, namespace,
schemaURIs.get(namespace), imports, includes);
}
}
return schema;
}
} catch (IOException e) {
logger.warning("Unable to get schema location for feature type '"
+ featureTypeInfos[0].getPrefixedName() + "'. Reason: '" + e.getMessage()
+ "'. Building the schema manually instead.");
}
// user didn't define schema location
// import gml schema
importGMLSchema(schema, factory, baseUrl);
schema.getQNamePrefixToNamespaceMap().put(gmlPrefix, gmlNamespace);
//schema.getQNamePrefixToNamespaceMap().put("gml", "http://www.opengis.net/gml");
// then manually build schema
for (int i = 0; i < featureTypeInfos.length; i++) {
try {
buildSchemaContent(featureTypeInfos[i], schema, factory, baseUrl);
} catch (Exception e) {
logger.log(Level.WARNING, "Could not build xml schema for type: "
+ featureTypeInfos[i].getName(), e);
}
}
} else {
//different namespaces, write out import statements
//set the first namespace as the target one
NamespaceInfo ns = featureTypeInfos[0].getNamespace();
//hack for wfs 1.0, the cite tests mandate that in the case of a heterogeneous schema
// no target namespace be declared, this conflicts with wfs 2.0
if (!(this instanceof GML2)) {
schema.setTargetNamespace(ns.getURI());
}
// map of namespace to schemaLocation used to prevent duplicate imports
Map<String, String> imports = new HashMap<String, String>();
// set of schemaLocations used to prevent duplicate includes
Set<String> includes = new HashSet<String>();
for (Iterator i = ns2featureTypeInfos.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry) i.next();
String prefix = (String) entry.getKey();
List types = (List) entry.getValue();
StringBuffer typeNames = new StringBuffer();
for (Iterator t = types.iterator(); t.hasNext();) {
FeatureTypeInfo info = (FeatureTypeInfo) t.next();
FeatureType featureType = info.getFeatureType();
Object schemaUri = featureType.getUserData().get("schemaURI");
if (schemaUri != null && schemaUri instanceof Map) {
// should always be a Map.. set in AppSchemaDataAccessConfigurator
// impose iteration order
@SuppressWarnings("unchecked")
Map<String, String> schemaURIs = new TreeMap<String, String>(
(Map<String, String>) schemaUri);
// schema is supplied by the user.. just import the specified location
for (String namespace : schemaURIs.keySet()) {
addReference(schema, factory, namespace,
schemaURIs.get(namespace), imports, includes);
}
} else {
typeNames.append(info.getPrefixedName()).append(",");
}
}
if (typeNames.length() > 0) {
typeNames.setLength(typeNames.length()-1);
// schema not found, encode describe feature type URL
Map<String, String> params = new LinkedHashMap<String, String>(describeFeatureTypeParams);
params.put("typeName", typeNames.toString().trim());
String schemaLocation = buildURL(baseUrl, "wfs", params, URLType.RESOURCE);
String namespace = catalog.getNamespaceByPrefix(prefix).getURI();
//register the namespace prefix
schema.getQNamePrefixToNamespaceMap().put(prefix, namespace);
XSDImport imprt = factory.createXSDImport();
imprt.setNamespace(namespace);
imprt.setSchemaLocation(schemaLocation);
XSDSchema resolved = null;
if (resolveAppSchemaImports) {