Skip to content

Commit

Permalink
#6475 - export original schema (if exactly one local schema is config…
Browse files Browse the repository at this point in the history
…ured)
  • Loading branch information
lgoltz committed May 4, 2020
1 parent 1f2b253 commit a9f3d99
Show file tree
Hide file tree
Showing 4 changed files with 261 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,59 @@
----------------------------------------------------------------------------*/
package org.deegree.gml.schema;

import org.apache.xerces.xs.StringList;
import org.apache.xerces.xs.XSAttributeUse;
import org.apache.xerces.xs.XSComplexTypeDefinition;
import org.apache.xerces.xs.XSElementDeclaration;
import org.apache.xerces.xs.XSFacet;
import org.apache.xerces.xs.XSModel;
import org.apache.xerces.xs.XSModelGroup;
import org.apache.xerces.xs.XSNamedMap;
import org.apache.xerces.xs.XSNamespaceItem;
import org.apache.xerces.xs.XSNamespaceItemList;
import org.apache.xerces.xs.XSObjectList;
import org.apache.xerces.xs.XSParticle;
import org.apache.xerces.xs.XSSimpleTypeDefinition;
import org.apache.xerces.xs.XSTerm;
import org.apache.xerces.xs.XSTypeDefinition;
import org.apache.xerces.xs.XSWildcard;
import org.deegree.commons.tom.gml.property.PropertyType;
import org.deegree.commons.tom.primitive.BaseType;
import org.deegree.commons.utils.Pair;
import org.deegree.commons.utils.URITranslator;
import org.deegree.commons.xml.stax.XMLStreamUtils;
import org.deegree.feature.types.AppSchema;
import org.deegree.feature.types.FeatureCollectionType;
import org.deegree.feature.types.FeatureType;
import org.deegree.feature.types.property.CodePropertyType;
import org.deegree.feature.types.property.CustomPropertyType;
import org.deegree.feature.types.property.FeaturePropertyType;
import org.deegree.feature.types.property.GeometryPropertyType;
import org.deegree.feature.types.property.GeometryPropertyType.GeometryType;
import org.deegree.feature.types.property.MeasurePropertyType;
import org.deegree.feature.types.property.SimplePropertyType;
import org.deegree.gml.GMLVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static javax.xml.XMLConstants.DEFAULT_NS_PREFIX;
import static org.apache.xerces.xs.XSComplexTypeDefinition.CONTENTTYPE_ELEMENT;
import static org.apache.xerces.xs.XSComplexTypeDefinition.CONTENTTYPE_EMPTY;
Expand Down Expand Up @@ -72,63 +125,19 @@
import static org.deegree.commons.xml.CommonNamespaces.GML_PREFIX;
import static org.deegree.commons.xml.CommonNamespaces.XLNNS;
import static org.deegree.commons.xml.CommonNamespaces.XSNS;
import static org.deegree.commons.xml.schema.SchemaUtils.copy;
import static org.deegree.commons.xml.schema.SchemaUtils.writeWrapperDoc;
import static org.deegree.gml.GMLVersion.GML_2;
import static org.deegree.gml.GMLVersion.GML_30;
import static org.deegree.gml.GMLVersion.GML_31;
import static org.deegree.gml.schema.GMLSchemaInfoSet.isGMLNamespace;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.apache.xerces.xs.StringList;
import org.apache.xerces.xs.XSAttributeUse;
import org.apache.xerces.xs.XSComplexTypeDefinition;
import org.apache.xerces.xs.XSElementDeclaration;
import org.apache.xerces.xs.XSFacet;
import org.apache.xerces.xs.XSModel;
import org.apache.xerces.xs.XSModelGroup;
import org.apache.xerces.xs.XSNamedMap;
import org.apache.xerces.xs.XSNamespaceItem;
import org.apache.xerces.xs.XSNamespaceItemList;
import org.apache.xerces.xs.XSObjectList;
import org.apache.xerces.xs.XSParticle;
import org.apache.xerces.xs.XSSimpleTypeDefinition;
import org.apache.xerces.xs.XSTerm;
import org.apache.xerces.xs.XSTypeDefinition;
import org.apache.xerces.xs.XSWildcard;
import org.deegree.commons.tom.gml.property.PropertyType;
import org.deegree.commons.tom.primitive.BaseType;
import org.deegree.commons.utils.Pair;
import org.deegree.commons.utils.URITranslator;
import org.deegree.feature.types.AppSchema;
import org.deegree.feature.types.FeatureCollectionType;
import org.deegree.feature.types.FeatureType;
import org.deegree.feature.types.property.CodePropertyType;
import org.deegree.feature.types.property.CustomPropertyType;
import org.deegree.feature.types.property.FeaturePropertyType;
import org.deegree.feature.types.property.GeometryPropertyType;
import org.deegree.feature.types.property.GeometryPropertyType.GeometryType;
import org.deegree.feature.types.property.MeasurePropertyType;
import org.deegree.feature.types.property.SimplePropertyType;
import org.deegree.gml.GMLVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Stream-based writer for exporting {@link AppSchema} or {@link FeatureType} instances as a GML application schema.
*
*
* @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a>
* @author last edited by: $Author$
*
*
* @version $Revision$, $Date$
*/
public class GMLAppSchemaWriter {
Expand Down Expand Up @@ -172,7 +181,7 @@ public class GMLAppSchemaWriter {

/**
* Creates a new {@link GMLAppSchemaWriter} for the given GML version and optional import URL.
*
*
* @param version
* gml version that exported schemas will comply to, must not be <code>null</code>
* @param targetNamespace
Expand Down Expand Up @@ -256,7 +265,7 @@ private void addNsBinding( String prefix, String ns ) {

/**
* Exports a wrapper schema document for the given XML Schema Infoset.
*
*
* @param writer
* @param xsModel
* @param targetNs
Expand All @@ -265,18 +274,45 @@ private void addNsBinding( String prefix, String ns ) {
*/
public static void export( XMLStreamWriter writer, GMLSchemaInfoSet xsModel, String targetNs,
URITranslator translator )
throws XMLStreamException {

throws XMLStreamException, IOException {
Set<String> schemaLocations = new HashSet<>();
List<Pair<String, String>> nsImports = new ArrayList<Pair<String, String>>();
for ( String ns : xsModel.getAppNamespaces() ) {
List<String> locations = xsModel.getComponentLocations( ns );
for ( String location : locations ) {
if ( !location.startsWith( "http" ) )
schemaLocations.add( location );
String translated = translator.translate( location );
nsImports.add( new Pair<String, String>( ns, translated ) );
}
}

writeWrapperDoc( writer, targetNs, nsImports );
if ( schemaLocations.size() == 1 ) {
try {
copyOriginalSchema( writer, schemaLocations );
} catch ( URISyntaxException e ) {
// fallback
writeWrapperDoc( writer, targetNs, nsImports );
}
} else {
writeWrapperDoc( writer, targetNs, nsImports );
}
}

private static void copyOriginalSchema( XMLStreamWriter writer, Set<String> schemaLocations )
throws IOException, XMLStreamException, URISyntaxException {
XMLStreamReader reader = null;
try {
String next = schemaLocations.iterator().next();
File file = new File( new URI( next ) );
InputStream schemaLocation = new FileInputStream( file );
reader = XMLInputFactory.newFactory().createXMLStreamReader( schemaLocation );
XMLStreamUtils.skipStartDocument( reader );
copy( reader, writer );
} finally {
if ( reader != null )
reader.close();
}
}

public void export( XMLStreamWriter writer, AppSchema schema )
Expand All @@ -289,7 +325,7 @@ public void export( XMLStreamWriter writer, AppSchema schema )
* <p>
* NOTE: The given writer must be configured to repair namespaces.
* </p>
*
*
* @param writer
* @param fts
* @throws XMLStreamException
Expand Down Expand Up @@ -516,7 +552,7 @@ private void exportFeatureComplexType( XMLStreamWriter writer, FeatureType ft, F

/**
* Returns the XML schema type name to use for exporting the complex type for the given {@link FeatureType}.
*
*
* @param ft
* feature type, must not be <code>null</code>
* @return the qualified complex type name or <code>null</code> if the type should be exported anonymously
Expand All @@ -543,7 +579,8 @@ private QName getXSTypeName( FeatureType ft ) {
XSTypeDefinition typeDef = elDecl.getTypeDefinition();
if ( !typeDef.getAnonymous() ) {
if ( isGMLNamespace( typeDef.getNamespace() )
&& ( typeDef.getName().equals( "AbstractFeatureType" ) || typeDef.getName().equals( "AbstractFeatureCollectionType" ) ) ) {
&& ( typeDef.getName().equals( "AbstractFeatureType" ) || typeDef.getName().equals(
"AbstractFeatureCollectionType" ) ) ) {
if ( ft instanceof FeatureCollectionType && abstractGMLFeatureCollectionElement != null ) {
typeName = new QName( gmlNsURI, "AbstractFeatureCollectionType" );
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,23 @@
----------------------------------------------------------------------------*/
package org.deegree.gml.schema;

import static org.slf4j.LoggerFactory.getLogger;
import junit.framework.Assert;
import org.apache.xerces.xs.XSElementDeclaration;
import org.apache.xerces.xs.XSTypeDefinition;
import org.deegree.commons.xml.stax.IndentingXMLStreamWriter;
import org.deegree.feature.types.AppSchema;
import org.deegree.gml.GMLVersion;
import org.junit.Test;
import org.slf4j.Logger;
import org.xmlmatchers.namespace.SimpleNamespaceContext;

import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
Expand All @@ -45,29 +60,19 @@
import java.util.List;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import junit.framework.Assert;

import org.apache.xerces.xs.XSElementDeclaration;
import org.apache.xerces.xs.XSTypeDefinition;
import org.deegree.commons.xml.stax.IndentingXMLStreamWriter;
import org.deegree.feature.types.AppSchema;
import org.deegree.gml.GMLVersion;
import org.deegree.gml.schema.GMLSchemaInfoSet;
import org.junit.Test;
import org.slf4j.Logger;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.slf4j.LoggerFactory.getLogger;
import static org.xmlmatchers.XmlMatchers.hasXPath;
import static org.xmlmatchers.transform.XmlConverters.the;
import static org.xmlmatchers.xpath.XpathReturnType.returningANumber;

/**
* TODO add documentation here
*
*
* @author <a href="mailto:schneider@lat-lon.de">Markus Schneider </a>
* @author last edited by: $Author:$
*
*
* @version $Revision:$, $Date:$
*/
public class GMLAppSchemaWriterTest {
Expand Down Expand Up @@ -339,4 +344,53 @@ public void testReexportCiteSF1()
encoder.export( writer, schema );
writer.close();
}

@Test
public void testExportSchemaWrappped()
throws Exception {
String schemaURL = this.getClass().getResource( "../cite/schema/cite-gmlsf1.xsd" ).toURI().toString();
GMLSchemaInfoSet gmlSchemaInfoSet = new GMLSchemaInfoSet( null, schemaURL );

GMLAppSchemaReader adapter = new GMLAppSchemaReader( GMLVersion.GML_31, null, schemaURL );
AppSchema schema = adapter.extractAppSchema();

XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
outputFactory.setProperty( XMLOutputFactory.IS_REPAIRING_NAMESPACES, true );
ByteArrayOutputStream os = new ByteArrayOutputStream();
XMLStreamWriter writer = new IndentingXMLStreamWriter( outputFactory.createXMLStreamWriter( os ) );
GMLAppSchemaWriter encoder = new GMLAppSchemaWriter( GMLVersion.GML_31, "http://cite.opengeospatial.org/gmlsf",
null, schema.getNamespaceBindings() );
encoder.export( writer, gmlSchemaInfoSet, "http://cite.opengeospatial.org/gmlsf", uri -> uri );
writer.close();

assertThat( the( os.toString() ),
hasXPath( "count(/xs:schema/xs:include)", nsContext(), returningANumber(), is( 2.0 ) ) );
}

@Test
public void testExportSchema()
throws Exception {
String schemaURL = this.getClass().getResource( "../cite/schema/cite-gmlsf0.xsd" ).toURI().toString();

GMLSchemaInfoSet gmlSchemaInfoSet = new GMLSchemaInfoSet( null, schemaURL );

GMLAppSchemaReader adapter = new GMLAppSchemaReader( GMLVersion.GML_31, null, schemaURL );
AppSchema schema = adapter.extractAppSchema();

XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
outputFactory.setProperty( XMLOutputFactory.IS_REPAIRING_NAMESPACES, true );
ByteArrayOutputStream os = new ByteArrayOutputStream();
XMLStreamWriter writer = new IndentingXMLStreamWriter( outputFactory.createXMLStreamWriter( os ) );
GMLAppSchemaWriter encoder = new GMLAppSchemaWriter( GMLVersion.GML_31, "http://cite.opengeospatial.org/gmlsf",
null, schema.getNamespaceBindings() );
encoder.export( writer, gmlSchemaInfoSet, "http://cite.opengeospatial.org/gmlsf", uri -> uri );
writer.close();

System.out.println( os.toString() );
}

private NamespaceContext nsContext() {
return new SimpleNamespaceContext().withBinding( "xs", "http://www.w3.org/2001/XMLSchema" );
}

}
Loading

0 comments on commit a9f3d99

Please sign in to comment.