├── .gitignore ├── LICENSE ├── gs-main-iso ├── .gitignore ├── .settings │ └── org.eclipse.core.resources.prefs ├── pom.xml └── src │ └── main │ └── java │ ├── applicationContext.xml │ └── org │ ├── geoserver │ ├── catalog │ │ ├── ISOCatalogBuilder.java │ │ ├── ISOResourcePool.java │ │ └── impl │ │ │ ├── ISOCatalogFactoryImpl.java │ │ │ ├── ISOCatalogImpl.java │ │ │ └── ISODefaultCatalogFacade.java │ ├── config │ │ └── ISOGeoServerLoader.java │ ├── feature │ │ ├── ISOCompositeFeatureCollection.java │ │ └── retype │ │ │ ├── ISOFidTransformerVisitor.java │ │ │ ├── ISORetypingDataStore.java │ │ │ ├── ISORetypingFeatureCollection.java │ │ │ ├── ISORetypingFeatureLocking.java │ │ │ ├── ISORetypingFeatureSource.java │ │ │ ├── ISORetypingFeatureStore.java │ │ │ └── WrappingFeatureListener.java │ └── security │ │ └── decorators │ │ ├── DecoratingCatalogFactory.java │ │ ├── DecoratingDataAccess.java │ │ ├── DecoratingDataStore.java │ │ ├── DecoratingDataStoreInfo.java │ │ ├── DecoratingFeatureSource.java │ │ ├── DecoratingFeatureTypeInfo.java │ │ ├── DecoratingLayerGroupInfo.java │ │ ├── DecoratingLayerInfo.java │ │ ├── DecoratingSimpleFeatureSource.java │ │ ├── ISODefaultSecureCatalogFactory.java │ │ ├── ISODefaultSecureDataFactory.java │ │ ├── ISOReadOnlyDataStore.java │ │ ├── ISOSecuredFeatureLocking.java │ │ ├── ISOSecuredFeatureSource.java │ │ ├── ISOSecuredFeatureStore.java │ │ ├── ISOSecuredFeatureTypeInfo.java │ │ ├── ISOSecuredSimpleFeatureCollection.java │ │ ├── ISOSecuredSimpleFeatureLocking.java │ │ ├── ISOSecuredSimpleFeatureSource.java │ │ └── ISOSecuredSimpleFeatureStore.java │ └── vfny │ └── geoserver │ ├── global │ ├── ISOGeoServerFeatureLocking.java │ ├── ISOGeoServerFeatureSource.java │ └── ISOGeoServerFeatureStore.java │ └── util │ └── ISODataStoreUtils.java ├── gs-web-iso ├── .gitignore ├── pom.xml └── src │ └── main │ ├── java │ ├── applicationContext.xml │ └── org │ │ └── geoserver │ │ ├── web │ │ ├── data │ │ │ ├── layer │ │ │ │ ├── ISOAttributeDescription.java │ │ │ │ ├── ISOAttributeEditPage.java │ │ │ │ ├── ISOAttributeNewPage.java │ │ │ │ ├── ISOAttributesProvider.java │ │ │ │ ├── ISOLayerPage.html │ │ │ │ ├── ISOLayerPage.java │ │ │ │ └── ISONewFeatureTypePage.java │ │ │ ├── resource │ │ │ │ └── ISOResourceConfigurationPage.java │ │ │ └── store │ │ │ │ ├── ISONewDataPage.html │ │ │ │ ├── ISONewDataPage.java │ │ │ │ ├── ISOStorePage.html │ │ │ │ ├── ISOStorePage.java │ │ │ │ ├── ISOStorePanel.html │ │ │ │ ├── ISOStorePanel.java │ │ │ │ └── ISOStoreProvider.java │ │ └── iso │ │ │ ├── ISOMainPage.html │ │ │ └── ISOMainPage.java │ │ └── wfs │ │ └── web │ │ ├── WFSAdminPage$GMLPanel.html │ │ ├── WFSAdminPage.html │ │ ├── WFSAdminPage.java │ │ ├── publish │ │ ├── WFSLayerConfig.html │ │ └── WFSLayerConfig.java │ │ └── server_vector.png │ └── resources │ └── GeoServerApplication.properties ├── gs-wfs-iso ├── .gitignore ├── .settings │ └── org.eclipse.core.resources.prefs ├── pom.xml └── src │ └── main │ └── java │ ├── META-INF │ └── services │ │ ├── org.geotools.filter.ExtendedOperatorFactory │ │ └── org.vfny.geoserver.wfs.FeatureResponseDelegateProducerSpi │ ├── WEB-INF │ ├── struts-config.xml │ └── tiles-defs.xml │ ├── applicationContext.xml │ └── org │ └── geoserver │ └── wfs │ ├── CapabilitiesTransformer3D.java │ ├── DescribeFeatureType3D.java │ ├── GetCapabilities3D.java │ ├── GetFeature3D.java │ ├── ISOAbstractTransactionElementHandler.java │ ├── ISODefaultWebFeatureService.java │ ├── ISODefaultWebFeatureService20.java │ ├── ISOFeatureBoundsFeatureCollection.java │ ├── ISOInsertElementHandler.java │ ├── ISOJoinExtractingVisitor.java │ ├── ISONativeElementHandler.java │ ├── ISOTransactionElementHandler.java │ ├── ISOTransactionEvent.java │ ├── ISOTransactionListener.java │ ├── Transaction3D.java │ ├── WFSDescribeFeatureTypeOutputFormat_ISO.java │ ├── WFSFactoryExtension_ISO.java │ ├── WFSInfoImpl_ISO.java │ ├── WFSLoader_ISO.java │ ├── WFSReprojectionUtil_ISO.java │ ├── WFSXStreamLoader_ISO.java │ ├── kvp │ ├── AcceptFormatsKvpParser.java │ ├── AcceptVersionsKvpParser.java │ ├── BBoxKvpParser.java │ ├── DescribeFeatureTypeKvpRequestReader.java │ ├── FilterKvpParser.java │ ├── Filter_1_0_0_KvpParser.java │ ├── Filter_1_1_0_KvpParser.java │ ├── Filter_2_0_0_KvpParser.java │ ├── GetCapabilitiesKvpRequestReader.java │ ├── GetFeatureKvpRequestReader.java │ ├── QNameKvpParser.java │ ├── QNameNestedKvpParser.java │ ├── ReleaseLockKvpRequestReader.java │ ├── ResultTypeKvpParser.java │ ├── SRSEnvelope.java │ ├── SortByKvpParser.java │ ├── SrsNameKvpParser.java │ ├── TypeNameKvpParser.java │ ├── TypeNamesKvpParser.java │ ├── URIKvpParser.java │ └── WFSKvpRequestReader.java │ ├── request │ ├── Delete3D.java │ ├── GetCapabilitiesRequest3D.java │ ├── GetFeatureRequest3D.java │ ├── Insert3D.java │ ├── Native3D.java │ ├── TransactionRequest3D.java │ └── Update3D.java │ ├── response │ └── GetCapabilitiesResponse3D.java │ └── xml │ ├── GML2OutputFormat_ISO.java │ ├── GML2Profile_ISO.java │ ├── GML3FeatureTransformer.java │ ├── GML3GeometryTranslator.java │ ├── GML3OutputFormat_ISO.java │ ├── GML3Profile_ISO.java │ ├── ISOFeatureTypeSchemaBuilder.java │ ├── ISOWFSHandlerFactory.java │ ├── WFSXmlUtils_ISO.java │ ├── gml2 │ └── GMLBoxTypeBinding_ISO.java │ ├── v1_0_0 │ ├── GMLAbstractFeatureTypeBinding.java │ ├── WFSConfiguration_ISO.java │ ├── WFS_ISO.java │ ├── WfsXmlReader_ISO.java │ └── XmlSchemaEncoder_ISO.java │ ├── v1_1_0 │ ├── ISOFeatureCollectionTypeBinding.java │ ├── ISOInsertElementTypeBinding.java │ ├── ISOQueryTypeBinding.java │ ├── WFSConfiguration_ISO.java │ ├── WFS_ISO.java │ ├── WfsXmlReader_ISO.java │ └── XmlSchemaEncoder_ISO.java │ └── v2_0 │ ├── GetFeatureTypeBinding.java │ ├── WFSConfiguration_ISO.java │ └── WfsXmlReader.java └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | pom.xml.tag 3 | pom.xml.releaseBackup 4 | pom.xml.versionsBackup 5 | pom.xml.next 6 | release.properties 7 | dependency-reduced-pom.xml 8 | buildNumber.properties 9 | .mvn/timing.properties 10 | /.project 11 | -------------------------------------------------------------------------------- /gs-main-iso/.gitignore: -------------------------------------------------------------------------------- 1 | /.classpath 2 | /.project 3 | -------------------------------------------------------------------------------- /gs-main-iso/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | -------------------------------------------------------------------------------- /gs-main-iso/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.geoserver 5 | geoserver-iso 6 | 2.9-SNAPSHOT 7 | 8 | gs-main-iso 9 | 10 | 11 | 12 | 13 | org.geoserver 14 | gs-main 15 | 2.10-SNAPSHOT 16 | 17 | 18 | org.geotools 19 | gt-main-iso 20 | 15-SNAPSHOT 21 | 22 | 23 | 24 | javax.servlet 25 | javax.servlet-api 26 | ${servlet-api.version} 27 | provided 28 | 29 | 30 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/catalog/impl/ISOCatalogFactoryImpl.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.catalog.impl; 7 | 8 | import org.geoserver.catalog.AttributeTypeInfo; 9 | import org.geoserver.catalog.AttributionInfo; 10 | import org.geoserver.catalog.Catalog; 11 | import org.geoserver.catalog.CatalogFactory; 12 | import org.geoserver.catalog.CoverageDimensionInfo; 13 | import org.geoserver.catalog.CoverageInfo; 14 | import org.geoserver.catalog.CoverageStoreInfo; 15 | import org.geoserver.catalog.DataLinkInfo; 16 | import org.geoserver.catalog.DataStoreInfo; 17 | import org.geoserver.catalog.FeatureTypeInfo; 18 | import org.geoserver.catalog.LayerGroupInfo; 19 | import org.geoserver.catalog.LayerInfo; 20 | import org.geoserver.catalog.LegendInfo; 21 | import org.geoserver.catalog.MapInfo; 22 | import org.geoserver.catalog.MetadataLinkInfo; 23 | import org.geoserver.catalog.NamespaceInfo; 24 | import org.geoserver.catalog.StyleInfo; 25 | import org.geoserver.catalog.WMSLayerInfo; 26 | import org.geoserver.catalog.WMSStoreInfo; 27 | import org.geoserver.catalog.WorkspaceInfo; 28 | 29 | public class ISOCatalogFactoryImpl implements CatalogFactory { 30 | 31 | Catalog catalog; 32 | 33 | public ISOCatalogFactoryImpl( Catalog catalog ) { 34 | this.catalog = catalog; 35 | } 36 | 37 | public CoverageInfo createCoverage() { 38 | return new CoverageInfoImpl(catalog); 39 | } 40 | 41 | public CoverageDimensionInfo createCoverageDimension() { 42 | return new CoverageDimensionImpl(); 43 | } 44 | 45 | public CoverageStoreInfo createCoverageStore() { 46 | return new CoverageStoreInfoImpl(catalog); 47 | } 48 | 49 | public DataStoreInfo createDataStore() { 50 | return new DataStoreInfoImpl(catalog); 51 | } 52 | 53 | public WMSStoreInfo createWebMapServer() { 54 | return new WMSStoreInfoImpl(catalog); 55 | } 56 | 57 | public AttributeTypeInfo createAttribute() { 58 | return new AttributeTypeInfoImpl(); 59 | } 60 | 61 | public FeatureTypeInfo createFeatureType() { 62 | return new FeatureTypeInfoImpl(catalog); 63 | } 64 | 65 | public WMSLayerInfo createWMSLayer() { 66 | return new WMSLayerInfoImpl(catalog); 67 | } 68 | 69 | public AttributionInfo createAttribution() { 70 | return new AttributionInfoImpl(); 71 | } 72 | 73 | public LayerInfo createLayer() { 74 | return new LayerInfoImpl(); 75 | } 76 | 77 | public MapInfo createMap() { 78 | return new MapInfoImpl(); 79 | } 80 | 81 | public LayerGroupInfo createLayerGroup() { 82 | return new LayerGroupInfoImpl(); 83 | } 84 | 85 | public LegendInfo createLegend() { 86 | return new LegendInfoImpl(); 87 | } 88 | 89 | public MetadataLinkInfo createMetadataLink() { 90 | return new MetadataLinkInfoImpl(); 91 | } 92 | 93 | public DataLinkInfo createDataLink() { 94 | return new DataLinkInfoImpl(); 95 | } 96 | 97 | public NamespaceInfo createNamespace() { 98 | return new NamespaceInfoImpl(); 99 | } 100 | 101 | public WorkspaceInfo createWorkspace() { 102 | return new WorkspaceInfoImpl(); 103 | } 104 | 105 | public StyleInfo createStyle() { 106 | return new StyleInfoImpl(catalog); 107 | } 108 | 109 | public Object create(Class clazz) { 110 | return null; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/feature/ISOCompositeFeatureCollection.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 - 2015 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.feature; 7 | 8 | import java.io.IOException; 9 | import java.util.ArrayList; 10 | import java.util.Iterator; 11 | import java.util.List; 12 | 13 | import org.geotools.data.ISODataUtilities; 14 | import org.geotools.data.store.DataFeatureCollection; 15 | import org.geotools.feature.FeatureCollection; 16 | import org.geotools.feature.FeatureIterator; 17 | import org.geotools.geometry.jts.ReferencedEnvelope; 18 | import org.opengis.feature.simple.SimpleFeatureType; 19 | import org.opengis.filter.identity.FeatureId; 20 | 21 | 22 | /** 23 | * Wraps multiple feature collections into a single. 24 | * 25 | * @author Justin Deoliveira, The Open Planning Project 26 | * 27 | */ 28 | public class ISOCompositeFeatureCollection extends DataFeatureCollection { 29 | /** 30 | * wrapped collecitons 31 | */ 32 | List collections; 33 | 34 | public ISOCompositeFeatureCollection(List collections) { 35 | this.collections = collections; 36 | } 37 | 38 | protected Iterator openIterator() throws IOException { 39 | return new CompositeIterator(); 40 | } 41 | 42 | public SimpleFeatureType getSchema() { 43 | return null; 44 | } 45 | 46 | public ReferencedEnvelope getBounds() { 47 | return ISODataUtilities.bounds(this); 48 | } 49 | 50 | public int getCount() throws IOException { 51 | int count = 0; 52 | Iterator i = iterator(); 53 | 54 | try { 55 | while (i.hasNext()) { 56 | i.next(); 57 | count++; 58 | } 59 | } finally { 60 | close(i); 61 | } 62 | 63 | return count; 64 | } 65 | 66 | class CompositeIterator implements Iterator { 67 | int index; 68 | FeatureIterator iterator; 69 | 70 | public CompositeIterator() { 71 | index = 0; 72 | } 73 | 74 | public void remove() { 75 | } 76 | 77 | public boolean hasNext() { 78 | //is there a current iterator that has another element 79 | if ((iterator != null) && iterator.hasNext()) { 80 | return true; 81 | } 82 | 83 | //get the next iterator 84 | while (index < collections.size()) { 85 | //close current before we move to next 86 | if (iterator != null) { 87 | iterator.close(); 88 | } 89 | 90 | //grap next 91 | iterator = collections.get(index++).features(); 92 | 93 | if (iterator.hasNext()) { 94 | return true; 95 | } 96 | } 97 | 98 | //no more 99 | if (iterator != null) { 100 | //close the last iterator 101 | iterator.close(); 102 | } 103 | 104 | return false; 105 | } 106 | 107 | public Object next() { 108 | return iterator.next(); 109 | } 110 | } 111 | 112 | public Object[] toArray(Object[] arg0) { 113 | List list = new ArrayList(); 114 | 115 | Iterator it = collections.iterator(); 116 | while(it.hasNext()){ 117 | FeatureCollection col = (FeatureCollection)it.next(); 118 | FeatureIterator it2 = col.features(); 119 | while (it2.hasNext()){ 120 | list.add(it.next()); 121 | } 122 | it2.close(); 123 | } 124 | 125 | return list.toArray(arg0); 126 | } 127 | 128 | public FeatureId getIdentifier() { 129 | throw new RuntimeException("Can't get the id for a composite featurecollection; you need to identify the consituent collections directly."); 130 | } 131 | 132 | /** 133 | * @return the collections 134 | */ 135 | public List getCollections() { 136 | return collections; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/feature/retype/ISOFidTransformerVisitor.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.feature.retype; 7 | 8 | import java.util.HashSet; 9 | import java.util.Iterator; 10 | import java.util.Set; 11 | 12 | import org.geotools.filter.ISOFilterFactoryImpl; 13 | import org.geotools.filter.identity.FeatureIdImpl; 14 | import org.geotools.filter.visitor.ISODuplicatingFilterVisitor; 15 | import org.opengis.filter.Filter; 16 | import org.opengis.filter.Id; 17 | import org.opengis.filter.identity.FeatureId; 18 | 19 | /** 20 | * Takes a filter that eventually contains a fid filter and builds a new filter that contains 21 | * the same fids but with a different prefix 22 | * @author Andrea Aime 23 | */ 24 | class FidTransformeVisitor extends ISODuplicatingFilterVisitor { 25 | private Object featureType; 26 | private FeatureTypeMap map; 27 | 28 | public FidTransformeVisitor(FeatureTypeMap map) { 29 | super(new ISOFilterFactoryImpl()); 30 | this.map = map; 31 | } 32 | 33 | public Object visit(Id filter, Object extraData) { 34 | Set ids = filter.getIDs(); 35 | if (ids.isEmpty()) { 36 | throw new IllegalArgumentException( 37 | "Invalid fid filter provides, has no fids inside"); 38 | } 39 | Filter external = null; 40 | Set fids = new HashSet(); 41 | for (Iterator it = ids.iterator(); it.hasNext();) { 42 | FeatureId id = new FeatureIdImpl((String) it.next()); 43 | FeatureId retyped = ISORetypingFeatureCollection.reTypeId(id, map.getFeatureType(), map.getOriginalFeatureType()); 44 | fids.add(retyped); 45 | } 46 | return ff.id(fids); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/feature/retype/ISORetypingFeatureLocking.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.feature.retype; 7 | 8 | import java.io.IOException; 9 | 10 | import org.geotools.data.FeatureLock; 11 | import org.geotools.data.FeatureLocking; 12 | import org.geotools.data.Query; 13 | import org.geotools.data.simple.SimpleFeatureLocking; 14 | import org.opengis.filter.Filter; 15 | 16 | /** 17 | * Renaming wrapper for a {@link FeatureLocking} instance, to be used along with {@link ISORetypingDataStore} 18 | */ 19 | class ISORetypingFeatureLocking extends ISORetypingFeatureStore implements 20 | SimpleFeatureLocking { 21 | 22 | ISORetypingFeatureLocking(ISORetypingDataStore ds, 23 | SimpleFeatureLocking wrapped, FeatureTypeMap typeMap) { 24 | super(ds, wrapped, typeMap); 25 | } 26 | 27 | ISORetypingFeatureLocking(SimpleFeatureLocking wrapped, FeatureTypeMap typeMap) throws IOException { 28 | super(wrapped, typeMap); 29 | } 30 | 31 | SimpleFeatureLocking featureLocking() { 32 | return (SimpleFeatureLocking) wrapped; 33 | } 34 | 35 | public int lockFeatures() throws IOException { 36 | return featureLocking().lockFeatures(); 37 | } 38 | 39 | public int lockFeatures(Query query) throws IOException { 40 | return featureLocking().lockFeatures(store.retypeQuery(query, typeMap)); 41 | } 42 | 43 | public int lockFeatures(Filter filter) throws IOException { 44 | return featureLocking().lockFeatures(store.retypeFilter(filter, typeMap)); 45 | } 46 | 47 | public void setFeatureLock(FeatureLock lock) { 48 | featureLocking().setFeatureLock(lock); 49 | } 50 | 51 | public void unLockFeatures() throws IOException { 52 | featureLocking().unLockFeatures(); 53 | } 54 | 55 | public void unLockFeatures(Filter filter) throws IOException { 56 | featureLocking().unLockFeatures(store.retypeFilter(filter, typeMap)); 57 | } 58 | 59 | public void unLockFeatures(Query query) throws IOException { 60 | featureLocking().unLockFeatures(store.retypeQuery(query, typeMap)); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/feature/retype/WrappingFeatureListener.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.feature.retype; 7 | 8 | import org.geotools.data.FeatureEvent; 9 | import org.geotools.data.FeatureListener; 10 | 11 | /** 12 | * A FeatureListener wrapper that changes the feature source, to be used in 13 | * wrapping feature sources 14 | */ 15 | public class WrappingFeatureListener implements FeatureListener { 16 | 17 | ISORetypingFeatureSource source; 18 | FeatureListener listener; 19 | 20 | public WrappingFeatureListener(ISORetypingFeatureSource source, FeatureListener listener) { 21 | this.source = source; 22 | this.listener = listener; 23 | } 24 | 25 | public void changed(FeatureEvent featureEvent) { 26 | FeatureEvent retyped = new FeatureEvent(source, featureEvent.getEventType(), featureEvent 27 | .getBounds()); 28 | listener.changed(retyped); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/security/decorators/DecoratingCatalogFactory.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.security.decorators; 7 | 8 | import org.geoserver.catalog.AttributeTypeInfo; 9 | import org.geoserver.catalog.AttributionInfo; 10 | import org.geoserver.catalog.CatalogFactory; 11 | import org.geoserver.catalog.CoverageDimensionInfo; 12 | import org.geoserver.catalog.CoverageInfo; 13 | import org.geoserver.catalog.CoverageStoreInfo; 14 | import org.geoserver.catalog.DataLinkInfo; 15 | import org.geoserver.catalog.DataStoreInfo; 16 | import org.geoserver.catalog.FeatureTypeInfo; 17 | import org.geoserver.catalog.LayerGroupInfo; 18 | import org.geoserver.catalog.LayerInfo; 19 | import org.geoserver.catalog.LegendInfo; 20 | import org.geoserver.catalog.MapInfo; 21 | import org.geoserver.catalog.MetadataLinkInfo; 22 | import org.geoserver.catalog.NamespaceInfo; 23 | import org.geoserver.catalog.StyleInfo; 24 | import org.geoserver.catalog.WMSLayerInfo; 25 | import org.geoserver.catalog.WMSStoreInfo; 26 | import org.geoserver.catalog.WorkspaceInfo; 27 | import org.geoserver.catalog.impl.AbstractDecorator; 28 | 29 | /** 30 | * 31 | * Delegates all methods to the provided delegate. Suclasses will override 32 | * methods in order to perform their decoration work 33 | * 34 | * @author Niels Charlier 35 | * 36 | */ 37 | public class DecoratingCatalogFactory extends AbstractDecorator implements CatalogFactory { 38 | 39 | public DecoratingCatalogFactory(CatalogFactory delegate) { 40 | super(delegate); 41 | } 42 | 43 | @Override 44 | public DataStoreInfo createDataStore() { 45 | return delegate.createDataStore(); 46 | } 47 | 48 | @Override 49 | public WMSStoreInfo createWebMapServer() { 50 | return delegate.createWebMapServer(); 51 | } 52 | 53 | @Override 54 | public MetadataLinkInfo createMetadataLink() { 55 | return delegate.createMetadataLink(); 56 | } 57 | 58 | @Override 59 | public DataLinkInfo createDataLink() { 60 | return delegate.createDataLink(); 61 | } 62 | 63 | @Override 64 | public CoverageStoreInfo createCoverageStore() { 65 | return delegate.createCoverageStore(); 66 | } 67 | 68 | @Override 69 | public AttributeTypeInfo createAttribute() { 70 | return delegate.createAttribute(); 71 | } 72 | 73 | @Override 74 | public FeatureTypeInfo createFeatureType() { 75 | return delegate.createFeatureType(); 76 | } 77 | 78 | @Override 79 | public CoverageInfo createCoverage() { 80 | return delegate.createCoverage(); 81 | } 82 | 83 | @Override 84 | public WMSLayerInfo createWMSLayer() { 85 | return delegate.createWMSLayer(); 86 | } 87 | 88 | @Override 89 | public CoverageDimensionInfo createCoverageDimension() { 90 | return delegate.createCoverageDimension(); 91 | } 92 | 93 | @Override 94 | public LegendInfo createLegend() { 95 | return delegate.createLegend(); 96 | } 97 | 98 | @Override 99 | public AttributionInfo createAttribution() { 100 | return delegate.createAttribution(); 101 | } 102 | 103 | @Override 104 | public LayerInfo createLayer() { 105 | return delegate.createLayer(); 106 | } 107 | 108 | @Override 109 | public MapInfo createMap() { 110 | return delegate.createMap(); 111 | } 112 | 113 | @Override 114 | public LayerGroupInfo createLayerGroup() { 115 | return delegate.createLayerGroup(); 116 | } 117 | 118 | @Override 119 | public StyleInfo createStyle() { 120 | return delegate.createStyle(); 121 | } 122 | 123 | @Override 124 | public NamespaceInfo createNamespace() { 125 | return delegate.createNamespace(); 126 | } 127 | 128 | @Override 129 | public WorkspaceInfo createWorkspace() { 130 | return delegate.createWorkspace(); 131 | } 132 | 133 | @Override 134 | public T create(Class clazz) { 135 | return delegate.create(clazz); 136 | } 137 | 138 | } 139 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/security/decorators/DecoratingDataAccess.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.security.decorators; 7 | 8 | import java.io.IOException; 9 | import java.util.List; 10 | 11 | import org.geoserver.catalog.impl.AbstractDecorator; 12 | import org.geotools.data.DataAccess; 13 | import org.geotools.data.FeatureSource; 14 | import org.geotools.data.ServiceInfo; 15 | import org.opengis.feature.Feature; 16 | import org.opengis.feature.type.FeatureType; 17 | import org.opengis.feature.type.Name; 18 | 19 | /** 20 | * Delegates all methods to the provided delegate. Suclasses will override 21 | * methods in order to perform their decoration work 22 | * 23 | * @author Andrea Aime - TOPP 24 | * 25 | * @param 26 | * @param 27 | */ 28 | public abstract class DecoratingDataAccess extends 29 | AbstractDecorator> implements DataAccess { 30 | 31 | public DecoratingDataAccess(DataAccess delegate) { 32 | super(delegate); 33 | } 34 | 35 | public void createSchema(T featureType) throws IOException { 36 | delegate.createSchema(featureType); 37 | } 38 | 39 | public void dispose() { 40 | delegate.dispose(); 41 | } 42 | 43 | public FeatureSource getFeatureSource(Name typeName) throws IOException { 44 | return delegate.getFeatureSource(typeName); 45 | } 46 | 47 | public ServiceInfo getInfo() { 48 | return delegate.getInfo(); 49 | } 50 | 51 | public List getNames() throws IOException { 52 | return delegate.getNames(); 53 | } 54 | 55 | public T getSchema(Name name) throws IOException { 56 | return delegate.getSchema(name); 57 | } 58 | 59 | public void updateSchema(Name typeName, T featureType) throws IOException { 60 | delegate.updateSchema(typeName, featureType); 61 | } 62 | 63 | public void removeSchema(Name typeName) throws IOException { 64 | delegate.removeSchema(typeName); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/security/decorators/DecoratingDataStore.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.security.decorators; 7 | 8 | import java.io.IOException; 9 | import java.util.List; 10 | 11 | import org.geoserver.catalog.impl.AbstractDecorator; 12 | import org.geotools.data.DataStore; 13 | import org.geotools.data.FeatureReader; 14 | import org.geotools.data.FeatureWriter; 15 | import org.geotools.data.LockingManager; 16 | import org.geotools.data.Query; 17 | import org.geotools.data.ServiceInfo; 18 | import org.geotools.data.Transaction; 19 | import org.geotools.data.simple.SimpleFeatureSource; 20 | import org.geotools.feature.SchemaException; 21 | import org.opengis.feature.simple.SimpleFeature; 22 | import org.opengis.feature.simple.SimpleFeatureType; 23 | import org.opengis.feature.type.Name; 24 | import org.opengis.filter.Filter; 25 | 26 | /** 27 | * Delegates every method to the wrapped feature source. Subclasses will 28 | * override selected methods to perform their "decoration" job 29 | * 30 | * @author Andrea Aime - TOPP TODO: Move this class to gt2 31 | */ 32 | public abstract class DecoratingDataStore extends AbstractDecorator implements DataStore { 33 | 34 | public DecoratingDataStore(DataStore delegate) { 35 | super(delegate); 36 | } 37 | 38 | public void createSchema(SimpleFeatureType featureType) throws IOException { 39 | delegate.createSchema(featureType); 40 | } 41 | 42 | public void dispose() { 43 | delegate.dispose(); 44 | } 45 | 46 | public FeatureReader getFeatureReader(Query query, 47 | Transaction transaction) throws IOException { 48 | return delegate.getFeatureReader(query, transaction); 49 | } 50 | 51 | public SimpleFeatureSource getFeatureSource(Name typeName) 52 | throws IOException { 53 | return delegate.getFeatureSource(typeName); 54 | } 55 | 56 | public SimpleFeatureSource getFeatureSource(String typeName) 57 | throws IOException { 58 | return delegate.getFeatureSource(typeName); 59 | } 60 | 61 | public FeatureWriter getFeatureWriter(String typeName, 62 | Filter filter, Transaction transaction) throws IOException { 63 | return delegate.getFeatureWriter(typeName, filter, transaction); 64 | } 65 | 66 | public FeatureWriter getFeatureWriter(String typeName, 67 | Transaction transaction) throws IOException { 68 | return delegate.getFeatureWriter(typeName, transaction); 69 | } 70 | 71 | public FeatureWriter getFeatureWriterAppend(String typeName, 72 | Transaction transaction) throws IOException { 73 | return delegate.getFeatureWriterAppend(typeName, transaction); 74 | } 75 | 76 | public ServiceInfo getInfo() { 77 | return delegate.getInfo(); 78 | } 79 | 80 | public LockingManager getLockingManager() { 81 | return delegate.getLockingManager(); 82 | } 83 | 84 | public List getNames() throws IOException { 85 | return delegate.getNames(); 86 | } 87 | 88 | public SimpleFeatureType getSchema(Name name) throws IOException { 89 | return delegate.getSchema(name); 90 | } 91 | 92 | public SimpleFeatureType getSchema(String typeName) throws IOException { 93 | return delegate.getSchema(typeName); 94 | } 95 | 96 | public String[] getTypeNames() throws IOException { 97 | return delegate.getTypeNames(); 98 | } 99 | 100 | public void updateSchema(Name typeName, SimpleFeatureType featureType) throws IOException { 101 | delegate.updateSchema(typeName, featureType); 102 | } 103 | 104 | public void updateSchema(String typeName, SimpleFeatureType featureType) throws IOException { 105 | delegate.updateSchema(typeName, featureType); 106 | } 107 | 108 | public void removeSchema(Name typeName) throws IOException { 109 | delegate.removeSchema(typeName); 110 | } 111 | 112 | public void removeSchema(String typeName) throws IOException { 113 | delegate.removeSchema(typeName); 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/security/decorators/DecoratingDataStoreInfo.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.security.decorators; 7 | 8 | import java.io.IOException; 9 | import java.io.Serializable; 10 | import java.util.Map; 11 | 12 | import org.geoserver.catalog.Catalog; 13 | import org.geoserver.catalog.CatalogVisitor; 14 | import org.geoserver.catalog.DataStoreInfo; 15 | import org.geoserver.catalog.MetadataMap; 16 | import org.geoserver.catalog.WorkspaceInfo; 17 | import org.geoserver.catalog.impl.AbstractDecorator; 18 | import org.geotools.data.DataAccess; 19 | import org.opengis.feature.Feature; 20 | import org.opengis.feature.type.FeatureType; 21 | import org.opengis.util.ProgressListener; 22 | 23 | /** 24 | * Delegates every method to the wrapped {@link DataStoreInfo}. Subclasses will 25 | * override selected methods to perform their "decoration" job 26 | * 27 | * @author Andrea Aime 28 | */ 29 | @SuppressWarnings("serial") 30 | public class DecoratingDataStoreInfo extends AbstractDecorator implements 31 | DataStoreInfo { 32 | 33 | public DecoratingDataStoreInfo(DataStoreInfo delegate) { 34 | super(delegate); 35 | } 36 | 37 | public Catalog getCatalog() { 38 | return delegate.getCatalog(); 39 | } 40 | 41 | public Map getConnectionParameters() { 42 | return delegate.getConnectionParameters(); 43 | } 44 | 45 | public DataAccess getDataStore( 46 | ProgressListener listener) throws IOException { 47 | return delegate.getDataStore(listener); 48 | } 49 | 50 | public String getDescription() { 51 | return delegate.getDescription(); 52 | } 53 | 54 | public String getType() { 55 | return delegate.getType(); 56 | } 57 | 58 | public Throwable getError() { 59 | return delegate.getError(); 60 | } 61 | 62 | public String getId() { 63 | return delegate.getId(); 64 | } 65 | 66 | public MetadataMap getMetadata() { 67 | return delegate.getMetadata(); 68 | } 69 | 70 | public String getName() { 71 | return delegate.getName(); 72 | } 73 | 74 | public WorkspaceInfo getWorkspace() { 75 | return delegate.getWorkspace(); 76 | } 77 | 78 | public boolean isEnabled() { 79 | return delegate.isEnabled(); 80 | } 81 | 82 | public void setDescription(String description) { 83 | delegate.setDescription(description); 84 | } 85 | 86 | public void setType(String type) { 87 | delegate.setType(type); 88 | } 89 | 90 | public void setEnabled(boolean enabled) { 91 | delegate.setEnabled(enabled); 92 | } 93 | 94 | public void setError(Throwable t) { 95 | delegate.setError(t); 96 | } 97 | 98 | public void setName(String name) { 99 | delegate.setName(name); 100 | } 101 | 102 | public void setWorkspace(WorkspaceInfo workspace) { 103 | delegate.setWorkspace(workspace); 104 | } 105 | 106 | public void accept(CatalogVisitor visitor) { 107 | delegate.accept(visitor); 108 | } 109 | 110 | public T getAdapter(Class adapterClass, Map hints) { 111 | return delegate.getAdapter(adapterClass, hints); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/security/decorators/DecoratingFeatureSource.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.security.decorators; 7 | 8 | import java.awt.RenderingHints.Key; 9 | import java.io.IOException; 10 | import java.util.Set; 11 | 12 | import org.geoserver.catalog.impl.AbstractDecorator; 13 | import org.geotools.data.DataAccess; 14 | import org.geotools.data.FeatureListener; 15 | import org.geotools.data.FeatureSource; 16 | import org.geotools.data.Query; 17 | import org.geotools.data.QueryCapabilities; 18 | import org.geotools.data.ResourceInfo; 19 | import org.geotools.feature.FeatureCollection; 20 | import org.geotools.geometry.jts.ReferencedEnvelope; 21 | import org.opengis.feature.Feature; 22 | import org.opengis.feature.type.FeatureType; 23 | import org.opengis.feature.type.Name; 24 | import org.opengis.filter.Filter; 25 | 26 | /** 27 | * Delegates every method to the wrapped feature source. Subclasses will 28 | * override selected methods to perform their "decoration" job 29 | * 30 | * @author Andrea Aime 31 | */ 32 | public abstract class DecoratingFeatureSource extends 33 | AbstractDecorator> implements FeatureSource { 34 | 35 | public DecoratingFeatureSource(FeatureSource delegate) { 36 | super(delegate); 37 | } 38 | 39 | public void addFeatureListener(FeatureListener listener) { 40 | delegate.addFeatureListener(listener); 41 | } 42 | 43 | public ReferencedEnvelope getBounds() throws IOException { 44 | return delegate.getBounds(); 45 | } 46 | 47 | public ReferencedEnvelope getBounds(Query query) throws IOException { 48 | return delegate.getBounds(query); 49 | } 50 | 51 | public int getCount(Query query) throws IOException { 52 | return delegate.getCount(query); 53 | } 54 | 55 | public DataAccess getDataStore() { 56 | return delegate.getDataStore(); 57 | } 58 | 59 | public FeatureCollection getFeatures() throws IOException { 60 | return delegate.getFeatures(); 61 | } 62 | 63 | public FeatureCollection getFeatures(Filter filter) throws IOException { 64 | return delegate.getFeatures(filter); 65 | } 66 | 67 | public FeatureCollection getFeatures(Query query) throws IOException { 68 | return delegate.getFeatures(query); 69 | } 70 | 71 | public ResourceInfo getInfo() { 72 | return delegate.getInfo(); 73 | } 74 | 75 | public Name getName() { 76 | return delegate.getName(); 77 | } 78 | 79 | public QueryCapabilities getQueryCapabilities() { 80 | return delegate.getQueryCapabilities(); 81 | } 82 | 83 | public T getSchema() { 84 | return delegate.getSchema(); 85 | } 86 | 87 | public Set getSupportedHints() { 88 | return delegate.getSupportedHints(); 89 | } 90 | 91 | public void removeFeatureListener(FeatureListener listener) { 92 | delegate.removeFeatureListener(listener); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/security/decorators/DecoratingSimpleFeatureSource.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.security.decorators; 7 | 8 | import java.awt.RenderingHints.Key; 9 | import java.io.IOException; 10 | import java.util.Set; 11 | 12 | import org.geoserver.catalog.impl.AbstractDecorator; 13 | import org.geotools.data.DataAccess; 14 | import org.geotools.data.FeatureListener; 15 | import org.geotools.data.FeatureSource; 16 | import org.geotools.data.Query; 17 | import org.geotools.data.QueryCapabilities; 18 | import org.geotools.data.ResourceInfo; 19 | import org.geotools.data.simple.SimpleFeatureCollection; 20 | import org.geotools.data.simple.SimpleFeatureSource; 21 | import org.geotools.feature.FeatureCollection; 22 | import org.geotools.geometry.jts.ReferencedEnvelope; 23 | import org.opengis.feature.Feature; 24 | import org.opengis.feature.simple.SimpleFeature; 25 | import org.opengis.feature.simple.SimpleFeatureType; 26 | import org.opengis.feature.type.FeatureType; 27 | import org.opengis.feature.type.Name; 28 | import org.opengis.filter.Filter; 29 | 30 | /** 31 | * Delegates every method to the wrapped simple feature source. Subclasses will 32 | * override selected methods to perform their "decoration" job 33 | * 34 | * @author Josh Vote, CSIRO Earth Science and Resource Engineering 35 | */ 36 | public abstract class DecoratingSimpleFeatureSource extends 37 | AbstractDecorator implements SimpleFeatureSource { 38 | 39 | public DecoratingSimpleFeatureSource(SimpleFeatureSource delegate) { 40 | super(delegate); 41 | } 42 | 43 | public void addFeatureListener(FeatureListener listener) { 44 | delegate.addFeatureListener(listener); 45 | } 46 | 47 | public ReferencedEnvelope getBounds() throws IOException { 48 | return delegate.getBounds(); 49 | } 50 | 51 | public ReferencedEnvelope getBounds(Query query) throws IOException { 52 | return delegate.getBounds(query); 53 | } 54 | 55 | public int getCount(Query query) throws IOException { 56 | return delegate.getCount(query); 57 | } 58 | 59 | public DataAccess getDataStore() { 60 | return delegate.getDataStore(); 61 | } 62 | 63 | public SimpleFeatureCollection getFeatures() throws IOException { 64 | return delegate.getFeatures(); 65 | } 66 | 67 | public SimpleFeatureCollection getFeatures(Filter filter) throws IOException { 68 | return delegate.getFeatures(filter); 69 | } 70 | 71 | public SimpleFeatureCollection getFeatures(Query query) throws IOException { 72 | return delegate.getFeatures(query); 73 | } 74 | 75 | public ResourceInfo getInfo() { 76 | return delegate.getInfo(); 77 | } 78 | 79 | public Name getName() { 80 | return delegate.getName(); 81 | } 82 | 83 | public QueryCapabilities getQueryCapabilities() { 84 | return delegate.getQueryCapabilities(); 85 | } 86 | 87 | public SimpleFeatureType getSchema() { 88 | return delegate.getSchema(); 89 | } 90 | 91 | public Set getSupportedHints() { 92 | return delegate.getSupportedHints(); 93 | } 94 | 95 | public void removeFeatureListener(FeatureListener listener) { 96 | delegate.removeFeatureListener(listener); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/security/decorators/ISODefaultSecureCatalogFactory.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.security.decorators; 7 | 8 | import org.geoserver.catalog.CoverageInfo; 9 | import org.geoserver.catalog.CoverageStoreInfo; 10 | import org.geoserver.catalog.DataStoreInfo; 11 | import org.geoserver.catalog.FeatureTypeInfo; 12 | import org.geoserver.catalog.LayerInfo; 13 | import org.geoserver.platform.ExtensionPriority; 14 | import org.geoserver.security.WrapperPolicy; 15 | 16 | /** 17 | * Creates security wrappers for the most common catalog objects 18 | * 19 | * @author Andrea Aime - TOPP 20 | * 21 | */ 22 | public class ISODefaultSecureCatalogFactory implements SecuredObjectFactory { 23 | 24 | public boolean canSecure(Class clazz) { 25 | return CoverageInfo.class.isAssignableFrom(clazz) 26 | || CoverageStoreInfo.class.isAssignableFrom(clazz) 27 | || DataStoreInfo.class.isAssignableFrom(clazz) 28 | || FeatureTypeInfo.class.isAssignableFrom(clazz) 29 | || LayerInfo.class.isAssignableFrom(clazz); 30 | } 31 | 32 | public Object secure(Object object, WrapperPolicy policy) { 33 | // null safe 34 | if (object == null) 35 | return null; 36 | 37 | Class clazz = object.getClass(); 38 | if (CoverageInfo.class.isAssignableFrom(clazz)) 39 | return new SecuredCoverageInfo((CoverageInfo) object, policy); 40 | else if (CoverageStoreInfo.class.isAssignableFrom(clazz)) 41 | return new SecuredCoverageStoreInfo((CoverageStoreInfo) object, policy); 42 | else if (DataStoreInfo.class.isAssignableFrom(clazz)) 43 | return new SecuredDataStoreInfo((DataStoreInfo) object, policy); 44 | else if (FeatureTypeInfo.class.isAssignableFrom(clazz)) 45 | return new ISOSecuredFeatureTypeInfo((FeatureTypeInfo) object, policy); 46 | else if (LayerInfo.class.isAssignableFrom(clazz)) 47 | return new SecuredLayerInfo((LayerInfo) object, policy); 48 | else 49 | throw new IllegalArgumentException("Don't know how to wrap"); 50 | } 51 | 52 | /** 53 | * Returns {@link ExtensionPriority#LOWEST} since the wrappers generated by 54 | * this factory 55 | */ 56 | public int getPriority() { 57 | return ExtensionPriority.LOWEST; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/security/decorators/ISOReadOnlyDataStore.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.security.decorators; 7 | 8 | import java.io.IOException; 9 | 10 | import org.geoserver.catalog.FeatureTypeInfo; 11 | import org.geoserver.security.Response; 12 | import org.geoserver.security.SecureCatalogImpl; 13 | import org.geoserver.security.WrapperPolicy; 14 | import org.geotools.data.DataStore; 15 | import org.geotools.data.FeatureSource; 16 | import org.geotools.data.FeatureStore; 17 | import org.geotools.data.FeatureWriter; 18 | import org.geotools.data.ISODataUtilities; 19 | import org.geotools.data.Transaction; 20 | import org.geotools.data.simple.SimpleFeatureSource; 21 | import org.opengis.feature.simple.SimpleFeature; 22 | import org.opengis.feature.simple.SimpleFeatureType; 23 | import org.opengis.feature.type.Name; 24 | import org.opengis.filter.Filter; 25 | 26 | /** 27 | * Given a {@link DataStore} subclass makes sure no write operations can be 28 | * performed through it. Regardless of the policy the store is kept read only as 29 | * services are supposed to perform writes via {@link FeatureStore} instances returned 30 | * by {@link FeatureTypeInfo} and not via direct data store access. 31 | * 32 | * @author Andrea Aime - TOPP 33 | */ 34 | public class ISOReadOnlyDataStore extends DecoratingDataStore { 35 | 36 | 37 | WrapperPolicy policy; 38 | 39 | protected ISOReadOnlyDataStore(DataStore delegate, WrapperPolicy policy) { 40 | super(delegate); 41 | this.policy = policy; 42 | } 43 | 44 | @Override 45 | public SimpleFeatureSource getFeatureSource(Name typeName) 46 | throws IOException { 47 | final SimpleFeatureSource fs = super.getFeatureSource(typeName); 48 | return wrapFeatureSource(fs); 49 | } 50 | 51 | @Override 52 | public SimpleFeatureSource getFeatureSource(String typeName) 53 | throws IOException { 54 | final SimpleFeatureSource fs = super.getFeatureSource(typeName); 55 | return wrapFeatureSource(fs); 56 | 57 | } 58 | 59 | @SuppressWarnings("unchecked") 60 | SimpleFeatureSource wrapFeatureSource( 61 | final SimpleFeatureSource fs) { 62 | if (fs == null) 63 | return null; 64 | 65 | return ISODataUtilities.simple((FeatureSource) SecuredObjects.secure(fs, policy)); 66 | } 67 | 68 | @Override 69 | public FeatureWriter getFeatureWriter(String typeName, 70 | Filter filter, Transaction transaction) throws IOException { 71 | throw notifyUnsupportedOperation(); 72 | } 73 | 74 | @Override 75 | public FeatureWriter getFeatureWriter(String typeName, 76 | Transaction transaction) throws IOException { 77 | throw notifyUnsupportedOperation(); 78 | } 79 | 80 | @Override 81 | public FeatureWriter getFeatureWriterAppend(String typeName, 82 | Transaction transaction) throws IOException { 83 | throw notifyUnsupportedOperation(); 84 | } 85 | 86 | @Override 87 | public void updateSchema(Name typeName, SimpleFeatureType featureType) throws IOException { 88 | throw notifyUnsupportedOperation(); 89 | } 90 | 91 | @Override 92 | public void updateSchema(String typeName, SimpleFeatureType featureType) throws IOException { 93 | throw notifyUnsupportedOperation(); 94 | } 95 | 96 | @Override 97 | public void createSchema(SimpleFeatureType featureType) throws IOException { 98 | throw notifyUnsupportedOperation(); 99 | } 100 | 101 | @Override 102 | public void removeSchema(Name typeName) throws IOException { 103 | throw notifyUnsupportedOperation(); 104 | } 105 | 106 | @Override 107 | public void removeSchema(String typeName) throws IOException { 108 | throw notifyUnsupportedOperation(); 109 | } 110 | 111 | /** 112 | * Notifies the caller the requested operation is not supported, using a plain {@link UnsupportedOperationException} 113 | * in case we have to conceal the fact the data is actually writable, using an Spring security exception otherwise 114 | * to force an authentication from the user 115 | */ 116 | protected RuntimeException notifyUnsupportedOperation() { 117 | if(policy.response == Response.CHALLENGE) { 118 | return SecureCatalogImpl.unauthorizedAccess(); 119 | } else 120 | return new UnsupportedOperationException("This datastore is read only, service code is supposed to perform writes via FeatureStore instead"); 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/security/decorators/ISOSecuredFeatureLocking.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.security.decorators; 7 | 8 | import java.io.IOException; 9 | 10 | import org.geoserver.security.WrapperPolicy; 11 | import org.geotools.data.FeatureLock; 12 | import org.geotools.data.FeatureLocking; 13 | import org.geotools.data.Query; 14 | import org.opengis.feature.Feature; 15 | import org.opengis.feature.type.FeatureType; 16 | import org.opengis.filter.Filter; 17 | 18 | import static org.geoserver.security.SecurityUtils.*; 19 | 20 | /** 21 | * See {@link ISOSecuredFeatureStore} for an explanation of why this class exists 22 | * 23 | * @author Andrea Aime GeoSolutions 24 | * 25 | * @param 26 | * @param 27 | */ 28 | public class ISOSecuredFeatureLocking extends 29 | ISOSecuredFeatureStore implements FeatureLocking { 30 | 31 | FeatureLocking lockDelegate; 32 | 33 | protected ISOSecuredFeatureLocking(FeatureLocking delegate, WrapperPolicy policy) { 34 | super(delegate, policy); 35 | this.lockDelegate = delegate; 36 | } 37 | 38 | public int lockFeatures() throws IOException { 39 | return lockFeatures(Filter.INCLUDE); 40 | } 41 | 42 | public int lockFeatures(Query query) throws IOException { 43 | Query writeQuery = getWriteQuery(policy); 44 | Query mixed = mixQueries(query, writeQuery); 45 | final Filter writeFilter = writeQuery.getFilter(); 46 | 47 | if(writeFilter == Filter.EXCLUDE) { 48 | throw unsupportedOperation(); 49 | } else if(writeFilter == Filter.INCLUDE) { 50 | return lockDelegate.lockFeatures(query); 51 | } else { 52 | return lockDelegate.lockFeatures(mixed); 53 | } 54 | } 55 | 56 | public int lockFeatures(Filter filter) throws IOException { 57 | return lockDelegate.lockFeatures(new Query(null, filter)); 58 | } 59 | 60 | public void setFeatureLock(FeatureLock lock) { 61 | Query writeQuery = getWriteQuery(policy); 62 | if(writeQuery.getFilter() == Filter.EXCLUDE) { 63 | throw unsupportedOperation(); 64 | } else { 65 | lockDelegate.setFeatureLock(lock); 66 | } 67 | } 68 | 69 | public void unLockFeatures() throws IOException { 70 | unLockFeatures(Query.ALL); 71 | } 72 | 73 | public void unLockFeatures(Filter filter) throws IOException { 74 | unLockFeatures(new Query(null, filter)); 75 | } 76 | 77 | public void unLockFeatures(Query query) throws IOException { 78 | Query writeQuery = getWriteQuery(policy); 79 | Query mixed = mixQueries(query, writeQuery); 80 | final Filter writeFilter = writeQuery.getFilter(); 81 | 82 | if(writeFilter == Filter.EXCLUDE) { 83 | throw unsupportedOperation(); 84 | } else if(writeFilter == Filter.INCLUDE) { 85 | lockDelegate.unLockFeatures(query); 86 | } else { 87 | lockDelegate.unLockFeatures(mixed); 88 | } 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/security/decorators/ISOSecuredFeatureTypeInfo.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 7 | * (c) 2001 - 2013 OpenPlans 8 | * This code is licensed under the GPL 2.0 license, available at the root 9 | * application directory. 10 | */ 11 | package org.geoserver.security.decorators; 12 | 13 | import java.io.IOException; 14 | import java.util.Arrays; 15 | import java.util.HashSet; 16 | import java.util.Set; 17 | 18 | import org.geoserver.catalog.DataStoreInfo; 19 | import org.geoserver.catalog.FeatureTypeInfo; 20 | import org.geoserver.security.AccessLevel; 21 | import org.geoserver.security.SecureCatalogImpl; 22 | import org.geoserver.security.VectorAccessLimits; 23 | import org.geoserver.security.WrapperPolicy; 24 | import org.geotools.data.FeatureSource; 25 | import org.geotools.data.Query; 26 | import org.geotools.factory.Hints; 27 | import org.geotools.feature.FeatureCollection; 28 | import org.geotools.feature.simple.ISOSimpleFeatureTypeBuilder; 29 | import org.opengis.feature.simple.SimpleFeatureType; 30 | import org.opengis.feature.type.AttributeDescriptor; 31 | import org.opengis.feature.type.FeatureType; 32 | import org.opengis.filter.Filter; 33 | import org.opengis.util.ProgressListener; 34 | 35 | /** 36 | * Wraps a {@link FeatureTypeInfo} so that it will return a secured 37 | * FeatureSource 38 | * 39 | * @author Andrea Aime - TOPP 40 | */ 41 | public class ISOSecuredFeatureTypeInfo extends DecoratingFeatureTypeInfo { 42 | 43 | WrapperPolicy policy; 44 | 45 | public ISOSecuredFeatureTypeInfo(FeatureTypeInfo info, WrapperPolicy policy) { 46 | super(info); 47 | this.policy = policy; 48 | } 49 | 50 | @Override 51 | public FeatureType getFeatureType() throws IOException { 52 | 53 | FeatureType ft = super.getFeatureType(); 54 | 55 | if(policy.getLimits() == null) { 56 | return ft; 57 | } else if(policy.getLimits() instanceof VectorAccessLimits) { 58 | VectorAccessLimits val = (VectorAccessLimits) policy.getLimits(); 59 | 60 | // get what we can actually read (and it makes it easier to deal with property names) 61 | Query query = val.getReadQuery(); 62 | 63 | // do we have any attribute filtering? 64 | if(query.getPropertyNames() == Query.ALL_NAMES) { 65 | return ft; 66 | } 67 | 68 | if(ft instanceof SimpleFeatureType) { 69 | SimpleFeatureType sft = (SimpleFeatureType) ft; 70 | Set properties = new HashSet(Arrays.asList(query.getPropertyNames())); 71 | ISOSimpleFeatureTypeBuilder tb = new ISOSimpleFeatureTypeBuilder(); 72 | tb.init(sft); 73 | for (AttributeDescriptor at : sft.getAttributeDescriptors()) { 74 | String attName = at.getLocalName(); 75 | if(!properties.contains(attName)) { 76 | tb.remove(attName); 77 | } 78 | } 79 | return tb.buildFeatureType(); 80 | } else { 81 | // if it's a complex type, we don't have a type builder on all branches, so 82 | // we'll run an empty query instead 83 | 84 | query.setFilter(Filter.EXCLUDE); 85 | FeatureSource fs = getFeatureSource(null, null); 86 | FeatureCollection fc = fs.getFeatures(query); 87 | return fc.getSchema(); 88 | } 89 | } else { 90 | throw new IllegalArgumentException("SecureFeatureSources has been fed " + 91 | "with unexpected AccessLimits class " + policy.getLimits().getClass()); 92 | } 93 | 94 | } 95 | 96 | //-------------------------------------------------------------------------- 97 | // WRAPPED METHODS TO ENFORCE SECURITY POLICY 98 | //-------------------------------------------------------------------------- 99 | 100 | public FeatureSource getFeatureSource(ProgressListener listener, Hints hints) 101 | throws IOException { 102 | final FeatureSource fs = delegate.getFeatureSource(listener, hints); 103 | 104 | if(policy.level == AccessLevel.METADATA) { 105 | throw SecureCatalogImpl.unauthorizedAccess(this.getName()); 106 | } else { 107 | return (FeatureSource) SecuredObjects.secure(fs, policy); 108 | } 109 | } 110 | 111 | public DataStoreInfo getStore() { 112 | return (DataStoreInfo) SecuredObjects.secure(delegate.getStore(), policy); 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/security/decorators/ISOSecuredSimpleFeatureCollection.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 - 2016 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.security.decorators; 7 | 8 | import java.io.IOException; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | import org.geoserver.security.VectorAccessLimits; 13 | import org.geoserver.security.WrapperPolicy; 14 | import org.geotools.data.DataUtilities; 15 | import org.geotools.data.simple.SimpleFeatureCollection; 16 | import org.geotools.data.simple.SimpleFeatureIterator; 17 | import org.geotools.data.store.ISOReTypingFeatureCollection; 18 | import org.geotools.feature.FeatureCollection; 19 | import org.geotools.feature.SchemaException; 20 | import org.opengis.feature.FeatureVisitor; 21 | import org.opengis.feature.simple.SimpleFeature; 22 | import org.opengis.feature.simple.SimpleFeatureType; 23 | import org.opengis.filter.Filter; 24 | import org.opengis.filter.expression.PropertyName; 25 | import org.opengis.filter.sort.SortBy; 26 | 27 | /** 28 | * Simple version of {@link SecuredFeatureCollection} 29 | * @author Andrea Aime - GeoSolutions 30 | * 31 | */ 32 | public class ISOSecuredSimpleFeatureCollection extends 33 | SecuredFeatureCollection implements 34 | SimpleFeatureCollection { 35 | 36 | SimpleFeatureType readSchema; 37 | 38 | ISOSecuredSimpleFeatureCollection(FeatureCollection delegate, 39 | WrapperPolicy policy) { 40 | super(delegate, policy); 41 | if(policy.getLimits() instanceof VectorAccessLimits) { 42 | List properties = ((VectorAccessLimits) policy.getLimits()).getReadAttributes(); 43 | if(properties == null) { 44 | this.readSchema = getSchema(); 45 | } else { 46 | List names = new ArrayList(); 47 | for (PropertyName property : properties) { 48 | names.add(property.getPropertyName()); 49 | } 50 | String[] nameArray = (String[]) names.toArray(new String[names.size()]); 51 | try { 52 | this.readSchema = DataUtilities.createSubType(getSchema(), nameArray); 53 | } catch (SchemaException e) { 54 | // should just not happen 55 | throw new RuntimeException(e); 56 | } 57 | } 58 | } else { 59 | this.readSchema = getSchema(); 60 | } 61 | } 62 | 63 | public SimpleFeatureCollection sort(SortBy order) { 64 | return (SimpleFeatureCollection) super.sort(order); 65 | } 66 | 67 | @Override 68 | public SimpleFeatureCollection subCollection(Filter filter) { 69 | return (SimpleFeatureCollection) super.subCollection(filter); 70 | } 71 | 72 | @Override 73 | public SimpleFeatureIterator features() { 74 | return (SimpleFeatureIterator) super.features(); 75 | } 76 | 77 | public void accepts(org.opengis.feature.FeatureVisitor visitor, 78 | org.opengis.util.ProgressListener progress) throws IOException { 79 | if (canDelegate(visitor)) { 80 | delegate.accepts(visitor, progress); 81 | } else { 82 | super.accepts(visitor, progress); 83 | } 84 | } 85 | 86 | protected boolean canDelegate(FeatureVisitor visitor) { 87 | return ISOReTypingFeatureCollection.isTypeCompatible(visitor, readSchema); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/security/decorators/ISOSecuredSimpleFeatureLocking.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.security.decorators; 7 | 8 | import static org.geoserver.security.SecurityUtils.getWriteQuery; 9 | 10 | import java.io.IOException; 11 | import java.util.Arrays; 12 | import java.util.HashSet; 13 | import java.util.Set; 14 | 15 | import org.geoserver.security.SecureCatalogImpl; 16 | import org.geoserver.security.WrapperPolicy; 17 | import org.geotools.data.FeatureLocking; 18 | import org.geotools.data.ISODataUtilities; 19 | import org.geotools.data.Query; 20 | import org.geotools.data.simple.SimpleFeatureCollection; 21 | import org.geotools.data.simple.SimpleFeatureLocking; 22 | import org.geotools.data.simple.SimpleFeatureStore; 23 | import org.opengis.feature.simple.SimpleFeature; 24 | import org.opengis.feature.simple.SimpleFeatureType; 25 | import org.opengis.filter.Filter; 26 | 27 | /** 28 | * Simple version of SecuredFeatureStore 29 | * 30 | * @author Andrea Aime - GeoSolutions 31 | */ 32 | public class ISOSecuredSimpleFeatureLocking extends 33 | ISOSecuredFeatureLocking implements SimpleFeatureLocking { 34 | 35 | protected ISOSecuredSimpleFeatureLocking(FeatureLocking delegate, WrapperPolicy policy) { 36 | super(delegate, policy); 37 | } 38 | 39 | @Override 40 | public SimpleFeatureCollection getFeatures() throws IOException { 41 | return ISODataUtilities.simple(super.getFeatures()); 42 | } 43 | 44 | @Override 45 | public SimpleFeatureCollection getFeatures(Filter filter) throws IOException { 46 | return ISODataUtilities.simple(super.getFeatures(filter)); 47 | } 48 | 49 | @Override 50 | public SimpleFeatureCollection getFeatures(Query query) throws IOException { 51 | return ISODataUtilities.simple(super.getFeatures(query)); 52 | } 53 | 54 | public void modifyFeatures(String name, Object attributeValue, Filter filter) 55 | throws IOException { 56 | modifyFeatures(new String[] { name }, new Object[] { attributeValue }, filter); 57 | 58 | } 59 | 60 | public void modifyFeatures(String[] names, Object[] values, Filter filter) throws IOException { 61 | // are we limiting anything? 62 | Query writeQuery = getWriteQuery(policy); 63 | if (writeQuery == Query.ALL) { 64 | ((SimpleFeatureStore) storeDelegate).modifyFeatures(names, values, filter); 65 | } else if (writeQuery.getFilter() == Filter.EXCLUDE 66 | || writeQuery.getPropertyNames() == Query.NO_NAMES) { 67 | throw unsupportedOperation(); 68 | } 69 | 70 | // get the mixed filter 71 | final Query local = new Query(null, filter); 72 | Query mixed = mixQueries(local, writeQuery); 73 | 74 | if (writeQuery.getPropertyNames() == Query.ALL_NAMES) { 75 | // it was just a matter of filtering. 76 | ((SimpleFeatureStore) storeDelegate).modifyFeatures(names, values, mixed.getFilter()); 77 | } else { 78 | // get the writable attribute set 79 | Set queryNames = new HashSet(Arrays.asList(writeQuery 80 | .getPropertyNames())); 81 | 82 | // check the update fields 83 | for (int i = 0; i < names.length; i++) { 84 | if (!queryNames.contains(names[i])) { 85 | String typeName = getSchema().getName().getLocalPart(); 86 | if (policy.getResponse() == org.geoserver.security.Response.CHALLENGE) { 87 | throw SecureCatalogImpl.unauthorizedAccess(typeName); 88 | } else { 89 | throw new UnsupportedOperationException( 90 | "Trying to write on the write protected attribute " + names[i]); 91 | } 92 | } 93 | } 94 | 95 | ((SimpleFeatureStore) storeDelegate).modifyFeatures(names, values, mixed.getFilter()); 96 | } 97 | 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/security/decorators/ISOSecuredSimpleFeatureSource.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.security.decorators; 7 | 8 | import java.io.IOException; 9 | 10 | import org.geoserver.security.WrapperPolicy; 11 | import org.geotools.data.ISODataUtilities; 12 | import org.geotools.data.Query; 13 | import org.geotools.data.simple.SimpleFeatureCollection; 14 | import org.geotools.data.simple.SimpleFeatureSource; 15 | import org.opengis.feature.simple.SimpleFeature; 16 | import org.opengis.feature.simple.SimpleFeatureType; 17 | import org.opengis.filter.Filter; 18 | 19 | /** 20 | * Secure version of {@link ISOSecuredFeatureSource} 21 | * 22 | * @author Andrea Aime - GeoSolutions 23 | * 24 | */ 25 | public class ISOSecuredSimpleFeatureSource extends 26 | ISOSecuredFeatureSource implements SimpleFeatureSource { 27 | 28 | protected ISOSecuredSimpleFeatureSource(SimpleFeatureSource delegate, WrapperPolicy policy) { 29 | super(delegate, policy); 30 | } 31 | 32 | @Override 33 | public SimpleFeatureCollection getFeatures() throws IOException { 34 | return ISODataUtilities.simple(super.getFeatures()); 35 | } 36 | 37 | @Override 38 | public SimpleFeatureCollection getFeatures(Filter filter) 39 | throws IOException { 40 | return ISODataUtilities.simple(super.getFeatures(filter)); 41 | } 42 | 43 | @Override 44 | public SimpleFeatureCollection getFeatures(Query query) 45 | throws IOException { 46 | return ISODataUtilities.simple(super.getFeatures(query)); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /gs-main-iso/src/main/java/org/geoserver/security/decorators/ISOSecuredSimpleFeatureStore.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.security.decorators; 7 | 8 | import static org.geoserver.security.SecurityUtils.getWriteQuery; 9 | 10 | import java.io.IOException; 11 | import java.util.Arrays; 12 | import java.util.HashSet; 13 | import java.util.Set; 14 | 15 | import org.geoserver.security.Response; 16 | import org.geoserver.security.SecureCatalogImpl; 17 | import org.geoserver.security.WrapperPolicy; 18 | import org.geotools.data.ISODataUtilities; 19 | import org.geotools.data.Query; 20 | import org.geotools.data.simple.SimpleFeatureCollection; 21 | import org.geotools.data.simple.SimpleFeatureStore; 22 | import org.opengis.feature.simple.SimpleFeature; 23 | import org.opengis.feature.simple.SimpleFeatureType; 24 | import org.opengis.filter.Filter; 25 | 26 | /** 27 | * The secure version of {@link ISOSecuredFeatureStore} 28 | * @author Andrea Aime - GeoSolutions 29 | */ 30 | public class ISOSecuredSimpleFeatureStore extends ISOSecuredFeatureStore implements 31 | SimpleFeatureStore { 32 | 33 | public ISOSecuredSimpleFeatureStore(SimpleFeatureStore delegate, WrapperPolicy policy) { 34 | super(delegate, policy); 35 | } 36 | 37 | @Override 38 | public SimpleFeatureCollection getFeatures() throws IOException { 39 | return ISODataUtilities.simple(super.getFeatures()); 40 | } 41 | 42 | @Override 43 | public SimpleFeatureCollection getFeatures(Filter filter) 44 | throws IOException { 45 | return ISODataUtilities.simple(super.getFeatures(filter)); 46 | } 47 | 48 | @Override 49 | public SimpleFeatureCollection getFeatures(Query query) 50 | throws IOException { 51 | return ISODataUtilities.simple(super.getFeatures(query)); 52 | } 53 | 54 | public void modifyFeatures(String name, Object attributeValue, Filter filter) 55 | throws IOException { 56 | modifyFeatures(new String[] {name}, new Object[] {attributeValue}, filter); 57 | 58 | } 59 | 60 | public void modifyFeatures(String[] names, Object[] values, Filter filter) 61 | throws IOException { 62 | // are we limiting anything? 63 | Query writeQuery = getWriteQuery(policy); 64 | if (writeQuery == Query.ALL) { 65 | ((SimpleFeatureStore) storeDelegate).modifyFeatures(names, values, filter); 66 | return; 67 | } else if (writeQuery.getFilter() == Filter.EXCLUDE 68 | || writeQuery.getPropertyNames() == Query.NO_NAMES) { 69 | throw unsupportedOperation(); 70 | } 71 | 72 | // get the mixed filter 73 | final Query local = new Query(null, filter); 74 | Query mixed = mixQueries(local, writeQuery); 75 | 76 | if (writeQuery.getPropertyNames() == Query.ALL_NAMES) { 77 | // it was just a matter of filtering. 78 | ((SimpleFeatureStore) storeDelegate).modifyFeatures(names, values, mixed.getFilter()); 79 | } else { 80 | // get the writable attribute set 81 | Set queryNames = new HashSet(Arrays.asList(writeQuery 82 | .getPropertyNames())); 83 | 84 | // check the update fields 85 | for (int i = 0; i < names.length; i++) { 86 | if (!queryNames.contains(names[i])) { 87 | String typeName = getSchema().getName().getLocalPart(); 88 | if (policy.getResponse() == Response.CHALLENGE) { 89 | throw SecureCatalogImpl.unauthorizedAccess(typeName); 90 | } else { 91 | throw new UnsupportedOperationException( 92 | "Trying to write on the write protected attribute " + names[i]); 93 | } 94 | } 95 | } 96 | 97 | ((SimpleFeatureStore) storeDelegate).modifyFeatures(names, values, mixed.getFilter()); 98 | } 99 | 100 | } 101 | 102 | 103 | 104 | } 105 | -------------------------------------------------------------------------------- /gs-web-iso/.gitignore: -------------------------------------------------------------------------------- 1 | /.classpath 2 | /.project 3 | -------------------------------------------------------------------------------- /gs-web-iso/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.geoserver 5 | geoserver-iso 6 | 2.9-SNAPSHOT 7 | 8 | gs-web-iso 9 | 10 | 11 | 12 | org.geoserver.web 13 | gs-web-core 14 | 2.9-SNAPSHOT 15 | 16 | 17 | 18 | org.geotools 19 | gt-opengis 20 | 15-SNAPSHOT 21 | 22 | 23 | 24 | org.geoserver 25 | gs-main-iso 26 | 2.9-SNAPSHOT 27 | 28 | 29 | 30 | org.geoserver 31 | gs-wfs-iso 32 | 2.9-SNAPSHOT 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | ${basedir}/src/main/resources 41 | 42 | 43 | ${basedir}/src/main/java 44 | 45 | **/*.java 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /gs-web-iso/src/main/java/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.geoserver.catalog.FeatureTypeInfo 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /gs-web-iso/src/main/java/org/geoserver/web/data/layer/ISOAttributeDescription.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 - 2016 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.web.data.layer; 7 | 8 | import java.io.Serializable; 9 | import java.sql.Date; 10 | import java.sql.Time; 11 | import java.sql.Timestamp; 12 | import java.util.Arrays; 13 | import java.util.List; 14 | 15 | import org.geoserver.web.wicket.ParamResourceModel; 16 | import org.geotools.referencing.CRS; 17 | import org.opengis.geometry.Geometry; 18 | import org.opengis.geometry.aggregate.MultiCurve; 19 | import org.opengis.geometry.aggregate.MultiPoint; 20 | import org.opengis.geometry.aggregate.MultiPrimitive; 21 | import org.opengis.geometry.aggregate.MultiSurface; 22 | import org.opengis.geometry.primitive.Curve; 23 | import org.opengis.geometry.primitive.Point; 24 | import org.opengis.geometry.primitive.Solid; 25 | import org.opengis.geometry.primitive.Surface; 26 | import org.opengis.referencing.crs.CoordinateReferenceSystem; 27 | 28 | @SuppressWarnings("serial") 29 | class ISOAttributeDescription implements Serializable { 30 | 31 | static final List> BINDINGS = Arrays.asList(String.class, Boolean.class, Integer.class, 32 | Long.class, Float.class, Double.class, Date.class, Time.class, Timestamp.class, 33 | Geometry.class, Point.class, Curve.class, Surface.class, Solid.class, MultiPoint.class, 34 | MultiCurve.class, MultiSurface.class, MultiPrimitive.class); 35 | 36 | static final CoordinateReferenceSystem WGS84; 37 | 38 | static { 39 | try { 40 | WGS84 = CRS.decode("EPSG:4326"); 41 | } catch(Exception e) { 42 | throw new RuntimeException(e); 43 | } 44 | } 45 | 46 | String name; 47 | 48 | Class binding = String.class; 49 | 50 | boolean nullable = true; 51 | 52 | int size = 100; 53 | 54 | CoordinateReferenceSystem crs = WGS84; 55 | 56 | /** 57 | * Returns the localized named of the attribute type 58 | * 59 | * @param binding 60 | * 61 | */ 62 | static String getLocalizedName(Class binding) { 63 | if (binding == null) { 64 | return "-"; 65 | } else if (BINDINGS.contains(binding)) { 66 | return new ParamResourceModel("AttributeType." + binding.getSimpleName(), null) 67 | .getString(); 68 | } else { 69 | return binding.getSimpleName(); 70 | } 71 | } 72 | 73 | public String getName() { 74 | return name; 75 | } 76 | 77 | public void setName(String name) { 78 | this.name = name; 79 | } 80 | 81 | public Class getBinding() { 82 | return binding; 83 | } 84 | 85 | public void setBinding(Class binding) { 86 | this.binding = binding; 87 | } 88 | 89 | public boolean isNullable() { 90 | return nullable; 91 | } 92 | 93 | public void setNullable(boolean nullable) { 94 | this.nullable = nullable; 95 | } 96 | 97 | public int getSize() { 98 | return size; 99 | } 100 | 101 | public void setSize(int size) { 102 | this.size = size; 103 | } 104 | 105 | public CoordinateReferenceSystem getCrs() { 106 | return crs; 107 | } 108 | 109 | public void setCrs(CoordinateReferenceSystem crs) { 110 | this.crs = crs; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /gs-web-iso/src/main/java/org/geoserver/web/data/layer/ISOAttributeNewPage.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.web.data.layer; 7 | 8 | 9 | @SuppressWarnings("serial") 10 | public class ISOAttributeNewPage extends ISOAttributeEditPage { 11 | 12 | public ISOAttributeNewPage(ISOAttributeDescription attribute, ISONewFeatureTypePage previousPage) { 13 | super(attribute, previousPage, true); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /gs-web-iso/src/main/java/org/geoserver/web/data/layer/ISOAttributesProvider.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 - 2016 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.web.data.layer; 7 | 8 | import java.util.ArrayList; 9 | import java.util.Arrays; 10 | import java.util.List; 11 | 12 | import org.geoserver.web.wicket.GeoServerDataProvider; 13 | 14 | class ISOAttributesProvider extends GeoServerDataProvider { 15 | 16 | /** serialVersionUID */ 17 | private static final long serialVersionUID = -1478240785822735763L; 18 | 19 | List attributes = new ArrayList(); 20 | 21 | static final Property NAME = new BeanProperty( 22 | "name", "name"); 23 | 24 | static final Property BINDING = new BeanProperty( 25 | "binding", "binding"); 26 | 27 | static final Property NULLABLE = new BeanProperty( 28 | "nullable", "nullable"); 29 | 30 | static final Property SIZE = new BeanProperty( 31 | "size", "size"); 32 | 33 | static final Property CRS = new BeanProperty( 34 | "crs", "crs"); 35 | 36 | static final PropertyPlaceholder UPDOWN = new PropertyPlaceholder("upDown"); 37 | 38 | public ISOAttributesProvider() { 39 | } 40 | 41 | public void addNewAttribute(ISOAttributeDescription attribute) { 42 | attributes.add(attribute); 43 | } 44 | 45 | @Override 46 | protected List getItems() { 47 | return attributes; 48 | } 49 | 50 | @Override 51 | protected List> getProperties() { 52 | return Arrays.asList(NAME, BINDING, NULLABLE, SIZE, CRS, UPDOWN); 53 | } 54 | 55 | public void removeAll(List removed) { 56 | this.attributes.removeAll(removed); 57 | } 58 | 59 | public boolean isFirst(ISOAttributeDescription attribute) { 60 | return attributes.get(0).equals(attribute); 61 | } 62 | 63 | public boolean isLast(ISOAttributeDescription attribute) { 64 | return attributes.get(attributes.size() - 1).equals(attribute); 65 | } 66 | 67 | public void moveUp(ISOAttributeDescription attribute) { 68 | int idx = attributes.indexOf(attribute); 69 | attributes.remove(idx); 70 | attributes.add(idx - 1, attribute); 71 | } 72 | 73 | public void moveDown(ISOAttributeDescription attribute) { 74 | int idx = attributes.indexOf(attribute); 75 | attributes.remove(idx); 76 | attributes.add(idx + 1, attribute); 77 | } 78 | 79 | public List getAttributes() { 80 | return attributes; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /gs-web-iso/src/main/java/org/geoserver/web/data/layer/ISOLayerPage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | <wicket:message key="layerList">Layer list</wicket:message> 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 |
  • 16 |
  • 17 |
18 |
19 | 20 | 21 |
22 |
23 | 24 | -------------------------------------------------------------------------------- /gs-web-iso/src/main/java/org/geoserver/web/data/store/ISONewDataPage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
    6 |
  • 7 |

    Vector Data Sources

    8 |
    9 | 10 | 11 | 12 | - 13 |
    14 |
  • 15 | 33 |
34 |
35 |
36 | 37 | 38 | -------------------------------------------------------------------------------- /gs-web-iso/src/main/java/org/geoserver/web/data/store/ISOStorePage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | <wicket:message key="title">3D Stores</wicket:message> 4 | 5 | 6 | 7 |
8 | 9 | 10 |
    11 |
  • 12 |
  • 13 |
14 |
15 | 16 | 17 |
18 |
19 | 20 | -------------------------------------------------------------------------------- /gs-web-iso/src/main/java/org/geoserver/web/data/store/ISOStorePage.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 - 2016 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.web.data.store; 7 | 8 | import org.apache.wicket.Component; 9 | import org.apache.wicket.ajax.AjaxRequestTarget; 10 | import org.apache.wicket.markup.html.link.BookmarkablePageLink; 11 | import org.apache.wicket.markup.html.panel.Fragment; 12 | import org.geoserver.web.ComponentAuthorizer; 13 | import org.geoserver.web.GeoServerSecuredPage; 14 | import org.geoserver.web.data.SelectionRemovalLink; 15 | import org.geoserver.web.wicket.GeoServerDialog; 16 | 17 | /** 18 | * Page listing all the available stores. Follows the usual filter/sort/page approach, provides ways 19 | * to bulk delete stores and to add new ones 20 | * 21 | * @see ISOStorePanel 22 | */ 23 | @SuppressWarnings("serial") 24 | public class ISOStorePage extends GeoServerSecuredPage { 25 | ISOStoreProvider provider = new ISOStoreProvider(); 26 | 27 | ISOStorePanel table; 28 | 29 | SelectionRemovalLink removal; 30 | 31 | GeoServerDialog dialog; 32 | 33 | public ISOStorePage() { 34 | // the table, and wire up selection change 35 | table = new ISOStorePanel("table", provider, true) { 36 | @Override 37 | protected void onSelectionUpdate(AjaxRequestTarget target) { 38 | removal.setEnabled(table.getSelection().size() > 0); 39 | target.add(removal); 40 | } 41 | }; 42 | table.setOutputMarkupId(true); 43 | add(table); 44 | 45 | // the confirm dialog 46 | add(dialog = new GeoServerDialog("dialog")); 47 | setHeaderPanel(headerPanel()); 48 | } 49 | 50 | protected Component headerPanel() { 51 | Fragment header = new Fragment(HEADER_PANEL, "header", this); 52 | 53 | // the add button 54 | header.add(new BookmarkablePageLink("addNew", ISONewDataPage.class)); 55 | 56 | // the removal button 57 | header.add(removal = new SelectionRemovalLink("removeSelected", table, dialog)); 58 | removal.setOutputMarkupId(true); 59 | removal.setEnabled(false); 60 | 61 | return header; 62 | } 63 | 64 | @Override 65 | protected ComponentAuthorizer getPageAuthorizer() { 66 | return ComponentAuthorizer.WORKSPACE_ADMIN; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /gs-web-iso/src/main/java/org/geoserver/web/data/store/ISOStorePanel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 |
9 | 10 | -------------------------------------------------------------------------------- /gs-web-iso/src/main/java/org/geoserver/web/iso/ISOMainPage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | 7 | -------------------------------------------------------------------------------- /gs-web-iso/src/main/java/org/geoserver/web/iso/ISOMainPage.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.geoserver.web.iso; 5 | 6 | import org.apache.wicket.markup.html.basic.Label; 7 | import org.geoserver.web.GeoServerBasePage; 8 | 9 | /** 10 | * @author hgryoo 11 | * 12 | */ 13 | public class ISOMainPage extends GeoServerBasePage { 14 | public ISOMainPage() { 15 | add( new Label( "hellolabel", "Hello World!") ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /gs-web-iso/src/main/java/org/geoserver/wfs/web/WFSAdminPage$GMLPanel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
    4 |
  • 5 | 6 | 7 |
  • 8 |
  • 9 | 12 | 13 |
  • 14 |
15 |
16 | 17 | -------------------------------------------------------------------------------- /gs-web-iso/src/main/java/org/geoserver/wfs/web/WFSAdminPage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
  • 5 |
    6 | Features 7 |
      8 |
    • 9 | 10 | 11 |
    • 12 |
    • 13 | 14 | 15 |
    • 16 |
    • 17 | 18 | 19 |
    • 20 |
    • 21 | 22 | 23 |
    • 24 |
    25 |
    26 |
  • 27 |
  • 28 |
    29 | 30 | otherSRS 31 | 32 | 33 |
      34 |
    • 35 | 36 |
    • 37 |
    38 |
    39 |
  • 40 |
  • 41 |
    42 | Service Level 43 |
    44 |
      45 |
    • 46 | 47 | 48 |
    • 49 |
    • 50 | 51 | 52 |
    • 53 |
    • 54 | 55 | 56 |
    • 57 |
    58 |
    59 |
    60 |
  • 61 |
  • 62 |
    63 | GML2 64 |
    65 |
    66 |
  • 67 |
  • 68 |
    69 | GML3 70 |
    71 |
    72 |
  • 73 |
  • 74 |
    75 | GML32 76 |
    77 |
    78 |
  • 79 |
  • 80 |
    81 | Conformance 82 |
      83 |
    • 84 | 85 | 86 |
    • 87 |
    88 |
    89 |
  • 90 |
  • 91 |
    92 | Encode response with 93 |
    94 |
      95 |
    • 96 | 97 | 98 |
    • 99 |
    • 100 | 101 | 102 |
    • 103 |
    104 |
    105 |
    106 |
  • 107 |
  • 108 |
    109 | SHAPE-ZIP output format 110 |
      111 |
    • 112 | 113 | 114 |
    • 115 |
    116 |
    117 |
  • 118 |
    119 | 120 | 121 | -------------------------------------------------------------------------------- /gs-web-iso/src/main/java/org/geoserver/wfs/web/publish/WFSLayerConfig.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
    5 | 6 |

    WFS Settings

    7 |
      8 |
    • 9 |
      10 | Feature Settings 11 |
        12 |
      • 13 | 14 |
        15 | 16 |
        17 | 18 |
        19 | 20 |
        21 |
      • 22 |
      23 |
      24 |
    • 25 |
    • 26 |
      27 | 28 | otherSRS 29 | 30 | 31 |
        32 |
      • 33 | 34 | 35 |
      • 36 |
      37 |
      38 |
    • 39 |
    • 40 |
      41 | 42 | otherSRS 43 | 44 | 45 |
        46 |
      • 47 | 48 | 49 |
      • 50 |
          51 |
        • 52 | 53 |
        • 54 |
        55 |
      56 |
      57 |
    • 58 |
    59 |
    60 |
    61 |
    62 | 63 | 64 | -------------------------------------------------------------------------------- /gs-web-iso/src/main/java/org/geoserver/wfs/web/publish/WFSLayerConfig.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 - 2016 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.web.publish; 7 | 8 | import java.util.List; 9 | 10 | import org.apache.wicket.ajax.AjaxRequestTarget; 11 | import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; 12 | import org.apache.wicket.ajax.markup.html.AjaxLink; 13 | import org.apache.wicket.markup.html.WebMarkupContainer; 14 | import org.apache.wicket.markup.html.border.Border; 15 | import org.apache.wicket.markup.html.form.CheckBox; 16 | import org.apache.wicket.markup.html.form.TextArea; 17 | import org.apache.wicket.markup.html.form.TextField; 18 | import org.apache.wicket.markup.html.form.validation.FormComponentFeedbackBorder; 19 | import org.apache.wicket.model.IModel; 20 | import org.apache.wicket.model.PropertyModel; 21 | import org.apache.wicket.model.StringResourceModel; 22 | import org.apache.wicket.validation.validator.RangeValidator; 23 | import org.geoserver.catalog.LayerInfo; 24 | import org.geoserver.web.publish.PublishedConfigurationPanel; 25 | import org.geoserver.web.wicket.GeoServerDialog; 26 | import org.geoserver.web.wicket.LiveCollectionModel; 27 | import org.geoserver.web.wicket.SRSListTextArea; 28 | 29 | public class WFSLayerConfig extends PublishedConfigurationPanel { 30 | 31 | private static final long serialVersionUID = 4264296611272179367L; 32 | 33 | protected GeoServerDialog dialog; 34 | 35 | public WFSLayerConfig(String id, IModel model){ 36 | super(id, model); 37 | 38 | TextField maxFeatures = new TextField("perReqFeatureLimit", 39 | new PropertyModel(model, "resource.maxFeatures")); 40 | maxFeatures.add(RangeValidator.minimum(0)); 41 | Border mfb = new FormComponentFeedbackBorder("perReqFeaturesBorder"); 42 | mfb.add(maxFeatures); 43 | add(mfb); 44 | TextField maxDecimals = new TextField("maxDecimals", new PropertyModel(model, "resource.numDecimals")); 45 | maxFeatures.add(RangeValidator.minimum(0)); 46 | Border mdb = new FormComponentFeedbackBorder("maxDecimalsBorder"); 47 | mdb.add(maxDecimals); 48 | add(mdb); 49 | CheckBox skipNumberMatched = new CheckBox("skipNumberMatched", new PropertyModel(model, "resource.skipNumberMatched")); 50 | add(skipNumberMatched); 51 | 52 | // other srs list 53 | dialog = new GeoServerDialog("wfsDialog"); 54 | add(dialog); 55 | PropertyModel overrideServiceSRSModel = new PropertyModel(model, "resource.overridingServiceSRS"); 56 | final CheckBox overrideServiceSRS = new CheckBox("overridingServiceSRS", overrideServiceSRSModel); 57 | add(overrideServiceSRS); 58 | final WebMarkupContainer otherSrsContainer = new WebMarkupContainer("otherSRSContainer"); 59 | otherSrsContainer.setOutputMarkupId(true); 60 | add(otherSrsContainer); 61 | final TextArea> srsList = new SRSListTextArea("srs", LiveCollectionModel.list( 62 | new PropertyModel>(model, "resource.responseSRS"))); 63 | srsList.setOutputMarkupId(true); 64 | srsList.setVisible(Boolean.TRUE.equals(overrideServiceSRSModel.getObject())); 65 | otherSrsContainer.add(srsList); 66 | overrideServiceSRS.add(new AjaxFormComponentUpdatingBehavior("change") { 67 | private static final long serialVersionUID = -6590810763209350915L; 68 | 69 | @Override 70 | protected void onUpdate(AjaxRequestTarget target) { 71 | Boolean visible = overrideServiceSRS.getConvertedInput(); 72 | srsList.setVisible(visible); 73 | target.add(otherSrsContainer); 74 | } 75 | }); 76 | add(new AjaxLink("skipNumberMatchedHelp") { 77 | private static final long serialVersionUID = 9222171216768726057L; 78 | 79 | @Override 80 | public void onClick(AjaxRequestTarget target) { 81 | dialog.showInfo(target, 82 | new StringResourceModel("skipNumberMatched", WFSLayerConfig.this, null), 83 | new StringResourceModel("skipNumberMatched.message", WFSLayerConfig.this, null)); 84 | } 85 | }); 86 | add(new AjaxLink("otherSRSHelp") { 87 | private static final long serialVersionUID = -1239179491855142211L; 88 | 89 | @Override 90 | public void onClick(AjaxRequestTarget target) { 91 | dialog.showInfo(target, 92 | new StringResourceModel("otherSRS", WFSLayerConfig.this, null), 93 | new StringResourceModel("otherSRS.message", WFSLayerConfig.this, null)); 94 | } 95 | }); 96 | 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /gs-web-iso/src/main/java/org/geoserver/wfs/web/server_vector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/STEMLab/geoserver-3d-extension/213660deaa9c246dad5c7488f4dc88179b27dfe4/gs-web-iso/src/main/java/org/geoserver/wfs/web/server_vector.png -------------------------------------------------------------------------------- /gs-web-iso/src/main/resources/GeoServerApplication.properties: -------------------------------------------------------------------------------- 1 | category.data3d = Data 3D 2 | 3 | ISOStorePage.title = 3D Stores 4 | ISOStorePage.description = Manage the stores providing 3d data to GeoServer 5 | ISOStorePage.addNew = Add new 3D Store 6 | ISOStorePage.removeSelected = Remove selected Stores 7 | ISOStorePage.th.enabled = Enabled? 8 | ISOStorePage.th.name = Store Name 9 | ISOStorePage.th.datatype = Data Type 10 | ISOStorePage.th.type = Type 11 | ISOStorePage.th.workspace = Workspace 12 | 13 | ISOLayerPage.addNew = Add a new layer 14 | ISOLayerPage.description = Manage the layers being published by GeoServer 15 | ISOLayerPage.layerList = Layer List 16 | ISOLayerPage.removeSelected = Remove selected layers 17 | ISOLayerPage.th.SRS = Native SRS 18 | ISOLayerPage.th.enabled = Enabled 19 | ISOLayerPage.th.name = Name 20 | ISOLayerPage.th.remove = Remove 21 | ISOLayerPage.th.store = Store 22 | ISOLayerPage.th.title = Title 23 | ISOLayerPage.th.type = Type 24 | ISOLayerPage.th.workspace = Workspace 25 | ISOLayerPage.title = 3D Layers 26 | 27 | # WFS ================================================================================ 28 | wfs.description=Web Feature Service 3D 29 | wfs.title=3D WFS 30 | 31 | WFSAdminPage.basic=Basic 32 | WFSAdminPage.canonicalSchemaLocation=Encode canonical WFS schema location 33 | WFSAdminPage.complete=Complete 34 | WFSAdminPage.conformance=Conformance 35 | WFSAdminPage.description=Manage the publishing of feature data. 36 | WFSAdminPage.encodeFeatureMember=Encode response with 37 | WFSAdminPage.featureBounding=Return bounding box with every feature 38 | WFSAdminPage.featureMembers=One "featureMembers" element 39 | WFSAdminPage.featureMember=Multiple "featureMember" elements 40 | WFSAdminPage.features=Features 41 | WFSAdminPage.gml2.title=GML 2 42 | WFSAdminPage.gml3.title=GML 3 43 | WFSAdminPage.gml32.title=GML 3.2 44 | WFSAdminPage.hitsIgnoreMaxFeatures=Ignore maximum number of features when calculating hits 45 | WFSAdminPage.maxNumberOfFeatures=Maximum number of features 46 | WFSAdminPage.maxNumberOfFeaturesForPreview=Maximum number of features for preview (Values <= 0 use the maximum number of features) 47 | WFSAdminPage.title=Web Feature Service 48 | WFSAdminPage.transactional=Transactional 49 | WFSAdminPage.serviceLevel=Service Level 50 | WFSAdminPage.shapeOutputFormat=SHAPE\u002DZIP output format 51 | WFSAdminPage.shapeZipPrjFormat=Use ESRI WKT format for SHAPE\u002DZIP generated .prj files 52 | 53 | otherSRS=Extra SRS codes for WFS capabilities generation 54 | 55 | WFSAdminPage$GMLPanel.srsStyle=SRS Style 56 | WFSAdminPage$GMLPanel.overrideGMLAttributes=Override GML Attributes 57 | WFSAdminPage.otherSRS.message=A comma separated list of EPSG codes, e.g. 4326,3857,3003. The \ 58 | corresponding codes will be added to each FeatureType declaration in the GetCapabilities \ 59 | response. 60 | 61 | WFSLayerConfig.maxDecimals=Maximum number of decimals 62 | WFSLayerConfig.perReqFeatureLimit=Per-Request Feature Limit 63 | WFSLayerConfig.wfsSettings=WFS Settings 64 | WFSLayerConfig.featureSettings=Feature Settings 65 | WFSLayerConfig.overridingServiceSRS=Override WFS wide SRS list 66 | WFSLayerConfig.skipNumberMatched=Skip the counting of the numberMatched attribute 67 | WFSLayerConfig.skipNumberMatchedTitle=NumberMatched skip 68 | WFSLayerConfig.skipNumberMatched.message=To enhance the performance of large queries, it is possible to skip the counting \ 69 | of the numberMatched attribute in a GetFeature WFS request. Although enabling this can minimize the query time, it can \ 70 | also break pagination for client applications, since numberMatched will always evaluate to 'unknown'. 71 | WFSLayerConfig.otherSRS.message=A comma separated list of EPSG codes, e.g. 4326,3857,3003. The \ 72 | corresponding codes will be added to each FeatureType declaration in the GetCapabilities \ 73 | response. The list can be left empty to have no extra SRS declared for this specific type, in \ 74 | override to a list of values specified in the WFS service configuration. 75 | 76 | 77 | SrsNameStyle.NORMAL=EPSG Code 78 | SrsNameStyle.XML=OGC HTTP URL 79 | SrsNameStyle.URN=OGC Experimental URN 80 | SrsNameStyle.URN2=OGC URN 81 | SrsNameStyle.URL=OGC HTTP URI 82 | -------------------------------------------------------------------------------- /gs-wfs-iso/.gitignore: -------------------------------------------------------------------------------- 1 | /.classpath 2 | /.project 3 | -------------------------------------------------------------------------------- /gs-wfs-iso/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | -------------------------------------------------------------------------------- /gs-wfs-iso/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.geoserver 7 | geoserver-iso 8 | 2.9-SNAPSHOT 9 | ../ 10 | 11 | gs-wfs-iso 12 | 13 | 14 | 15 | 16 | org.geoserver 17 | gs-ows 18 | 2.9-SNAPSHOT 19 | 20 | 21 | org.geoserver 22 | gs-wfs 23 | 2.9-SNAPSHOT 24 | 25 | 26 | org.geoserver 27 | gs-platform 28 | 2.9-SNAPSHOT 29 | 30 | 31 | 32 | org.geotools 33 | gt-main-iso 34 | 15-SNAPSHOT 35 | 36 | 37 | 38 | org.geotools.xsd 39 | gt-xsd-filter-iso 40 | 15-SNAPSHOT 41 | 42 | 43 | 44 | org.geotools.xsd 45 | gt-xsd-gml3-iso 46 | 15-SNAPSHOT 47 | 48 | 49 | 50 | org.geoserver 51 | gs-main-iso 52 | 2.9-SNAPSHOT 53 | 54 | 55 | 56 | 57 | javax.servlet 58 | javax.servlet-api 59 | ${servlet-api.version} 60 | provided 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/META-INF/services/org.geotools.filter.ExtendedOperatorFactory: -------------------------------------------------------------------------------- 1 | org.geoserver.wfs.WFSExtendedOperatorFactory -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/META-INF/services/org.vfny.geoserver.wfs.FeatureResponseDelegateProducerSpi: -------------------------------------------------------------------------------- 1 | org.vfny.geoserver.wfs.responses.GML2FeatureResponseDelegateFactory 2 | org.vfny.geoserver.wfs.responses.ShapefileFeatureResponseDelegateFactory 3 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/GetCapabilities3D.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs; 7 | 8 | import java.nio.charset.Charset; 9 | import java.util.ArrayList; 10 | import java.util.Collection; 11 | import java.util.List; 12 | 13 | import org.geoserver.catalog.Catalog; 14 | import org.geoserver.ows.util.RequestUtils; 15 | import org.geoserver.wfs.request.GetCapabilitiesRequest3D; 16 | 17 | /** 18 | * Web Feature Service GetCapabilities operation. 19 | *

    20 | * This operation returns a {@link org.geotools.xml.transform.TransformerBase} instance 21 | * which will serialize the wfs capabilities document. This class uses ows version negotiation 22 | * to determine which version of the wfs capabilities document to return. 23 | *

    24 | * 25 | * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org 26 | * 27 | */ 28 | public class GetCapabilities3D { 29 | /** 30 | * WFS service configuration 31 | */ 32 | WFSInfo wfs; 33 | 34 | /** 35 | * The catalog 36 | */ 37 | Catalog catalog; 38 | 39 | private final Collection extendedCapabilitiesProviders; 40 | 41 | /** 42 | * Creates a new wfs 1.0/1.1 GetCapabilitis operation. 43 | * 44 | * @param wfs The wfs configuration 45 | * @param catalog The geoserver catalog. 46 | * @param extendedCapabilitiesProviders the providers for adding extra metadata to the capabilities documents 47 | */ 48 | public GetCapabilities3D(WFSInfo wfs, Catalog catalog, Collection extendedCapabilitiesProviders) { 49 | this.wfs = wfs; 50 | this.catalog = catalog; 51 | this.extendedCapabilitiesProviders = extendedCapabilitiesProviders; 52 | } 53 | 54 | public CapabilitiesTransformer3D run(GetCapabilitiesRequest3D request) 55 | throws WFSException { 56 | //cite requires that we fail when we see an "invalid" update sequence, 57 | // since we dont support update sequences, all are invalid, but we take 58 | // our more lax approach and just ignore it when not doint the cite thing 59 | if (wfs.isCiteCompliant()) { 60 | if (request.getUpdateSequence() != null) { 61 | throw new WFSException(request, "Invalid update sequence", "InvalidUpdateSequence"); 62 | } 63 | } 64 | 65 | //TODO: the rest of this routine should be done by the dispatcher 66 | //make sure service is set, cite conformance thing 67 | //JD - We wrap this in a cite conformance check because cite stricly 68 | // tests that every request includes the 'service=WFS' key value pair. 69 | // However often the the context of the request is good enough to 70 | // determine what the service is, like in 'geoserver/wfs?request=GetCapabilities' 71 | if (wfs.isCiteCompliant()) { 72 | if (!request.isSetService()) { 73 | //give up 74 | throw new WFSException("Service not set", "MissingParameterValue", "service"); 75 | } 76 | } 77 | 78 | String version = version(request); 79 | 80 | String baseUrl = request.getBaseUrl(); 81 | final CapabilitiesTransformer3D capsTransformer; 82 | if ("1.0.0".equals(version)) { 83 | capsTransformer = new CapabilitiesTransformer3D.WFS1_0(wfs, catalog); 84 | } else { 85 | if ("1.1.0".equals(version)) { 86 | capsTransformer = new CapabilitiesTransformer3D.WFS1_1(wfs, baseUrl, catalog, 87 | extendedCapabilitiesProviders); 88 | } else if ("2.0.0".equals(version)) { 89 | capsTransformer = new CapabilitiesTransformer3D.WFS2_0(wfs, baseUrl, catalog, 90 | extendedCapabilitiesProviders); 91 | } else { 92 | throw new WFSException(request, "Could not understand version:" + version); 93 | } 94 | } 95 | capsTransformer.setEncoding(Charset.forName(wfs.getGeoServer().getSettings().getCharset())); 96 | return capsTransformer; 97 | } 98 | 99 | public static String version(GetCapabilitiesRequest3D request) { 100 | // do the version negotiation dance 101 | List provided = new ArrayList(); 102 | provided.add("1.0.0"); 103 | provided.add("1.1.0"); 104 | 105 | if (request instanceof GetCapabilitiesRequest3D.WFS20) { 106 | provided.add("2.0.0"); 107 | } 108 | 109 | List accepted = request.getAcceptVersions(); 110 | 111 | String version = RequestUtils.getVersionPreOws(provided, accepted); 112 | return version; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/ISOAbstractTransactionElementHandler.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs; 7 | 8 | import org.geoserver.config.GeoServer; 9 | 10 | /** 11 | * Base class for transaction element handlers. 12 | * 13 | * @author Justin Deoliveira, OpenGeo 14 | * 15 | */ 16 | public abstract class ISOAbstractTransactionElementHandler implements ISOTransactionElementHandler { 17 | 18 | protected GeoServer geoServer; 19 | 20 | protected ISOAbstractTransactionElementHandler(GeoServer geoServer) { 21 | this.geoServer = geoServer; 22 | } 23 | 24 | protected WFSInfo getInfo() { 25 | return geoServer.getService(WFSInfo.class); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/ISONativeElementHandler.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs; 7 | 8 | import java.util.Map; 9 | import java.util.logging.Logger; 10 | 11 | import javax.xml.namespace.QName; 12 | 13 | import net.opengis.wfs.NativeType; 14 | import net.opengis.wfs.TransactionResponseType; 15 | import net.opengis.wfs.TransactionType; 16 | 17 | import org.eclipse.emf.ecore.EObject; 18 | import org.geoserver.catalog.FeatureTypeInfo; 19 | import org.geotools.data.FeatureStore; 20 | import org.geoserver.wfs.request.Native; 21 | import org.geoserver.wfs.request.TransactionElement; 22 | import org.geoserver.wfs.request.TransactionRequest; 23 | import org.geoserver.wfs.request.TransactionRequest3D; 24 | import org.geoserver.wfs.request.TransactionResponse; 25 | 26 | /** 27 | * Processes native elements as unrecognized ones, and checks wheter they can be 28 | * safely ignored on not. 29 | * 30 | * @author Andrea Aime - TOPP 31 | */ 32 | public class ISONativeElementHandler implements ISOTransactionElementHandler { 33 | /** 34 | * logger 35 | */ 36 | static Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geoserver.wfs"); 37 | 38 | /** 39 | * Empty array of QNames 40 | */ 41 | protected static final QName[] EMPTY_QNAMES = new QName[0]; 42 | 43 | public ISONativeElementHandler() { 44 | } 45 | 46 | public void checkValidity(TransactionElement element, Map featureTypeInfos) 47 | throws WFSTransactionException { 48 | 49 | Native nativ = (Native) element; 50 | if (!nativ.isSafeToIgnore()) { 51 | throw new WFSTransactionException("Native element:" + nativ.getVendorId() 52 | + " unsupported but marked as" + " unsafe to ignore", "InvalidParameterValue"); 53 | } 54 | } 55 | 56 | public void execute(TransactionElement element, TransactionRequest3D request, Map featureSources, 57 | TransactionResponse response, ISOTransactionListener listener) throws WFSTransactionException { 58 | // nothing to do, we just ignore if possible 59 | } 60 | 61 | public Class getElementClass() { 62 | return Native.class; 63 | } 64 | 65 | /** 66 | * @return an empty array. 67 | * @see org.geoserver.wfs.ISOTransactionElementHandler#getTypeNames(TransactionElement) 68 | */ 69 | public QName[] getTypeNames(TransactionElement element) throws WFSTransactionException { 70 | // we don't handle this 71 | return EMPTY_QNAMES; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/ISOTransactionElementHandler.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs; 7 | 8 | import java.util.Map; 9 | 10 | import javax.xml.namespace.QName; 11 | 12 | import net.opengis.wfs.TransactionResponseType; 13 | import net.opengis.wfs.TransactionType; 14 | 15 | import org.eclipse.emf.ecore.EObject; 16 | import org.geoserver.catalog.FeatureTypeInfo; 17 | import org.geoserver.wfs.request.TransactionElement; 18 | import org.geoserver.wfs.request.TransactionRequest; 19 | import org.geoserver.wfs.request.TransactionRequest3D; 20 | import org.geoserver.wfs.request.TransactionResponse; 21 | import org.geotools.data.FeatureStore; 22 | 23 | 24 | /** 25 | * Transaction elements are an open ended set, both thanks to the Native element 26 | * type, and to the XSD sustitution group concept (xsd inheritance). Element 27 | * handlers know how to process a certain element in a wfs transaction request. 28 | * 29 | * @author Andrea Aime - TOPP 30 | * 31 | */ 32 | public interface ISOTransactionElementHandler { 33 | /** 34 | * Returns the element class this handler can proces 35 | */ 36 | Class getElementClass(); 37 | 38 | /** 39 | * Returns the qualified names of feature types needed to handle this 40 | * element 41 | */ 42 | QName[] getTypeNames(TransactionElement element) throws WFSTransactionException; 43 | 44 | /** 45 | * Checks the element content is valid, throws an exception otherwise 46 | * 47 | * @param element 48 | * the transaction element we're checking 49 | * @param featureTypeInfos 50 | * a map from {@link QName} to {@link FeatureTypeInfo}, where 51 | * the keys contain all the feature type names reported by 52 | * {@link #getTypeNames(EObject)} 53 | */ 54 | void checkValidity(TransactionElement element, Map featureTypeInfos) throws WFSTransactionException; 55 | 56 | /** 57 | * Executes the element against the provided feature sources 58 | * 59 | * @param element 60 | * the tranaction element to be executed 61 | * @param request 62 | * the transaction request 63 | * @param featureStores 64 | * map from {@link QName} to {@link FeatureStore}, where the 65 | * keys do contain all the feature type names reported by 66 | * {@link #getTypeNames(EObject)} 67 | * @param response 68 | * the transaction response, that the element will update 69 | * according to the processing done 70 | * @param listener 71 | * a transaction listener that will be called before and after 72 | * each change performed against the data stores 73 | */ 74 | @SuppressWarnings("rawtypes") 75 | void execute(TransactionElement element, TransactionRequest3D request, Map featureStores, 76 | TransactionResponse response, ISOTransactionListener listener) throws WFSTransactionException; 77 | } 78 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/ISOTransactionEvent.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs; 7 | 8 | import javax.xml.namespace.QName; 9 | 10 | import org.geoserver.wfs.request.TransactionRequest; 11 | import org.geoserver.wfs.request.TransactionRequest3D; 12 | import org.geotools.data.Transaction; 13 | import org.geotools.data.simple.SimpleFeatureCollection; 14 | 15 | import net.opengis.wfs.DeleteElementType; 16 | import net.opengis.wfs.InsertElementType; 17 | import net.opengis.wfs.TransactionType; 18 | import net.opengis.wfs.UpdateElementType; 19 | 20 | 21 | /** 22 | * Event carrying information about a change that happened/that is about to 23 | * occur. 24 | *

    25 | * The feature collection may be an in-memory one, or may be based on a 26 | * real data store with a filter. 27 | *

    28 | *

    29 | * Note that care should be taken when relying on feature identifiers from a 30 | * {@link TransactionEventType#POST_INSERT} event. Depending on the type of store those identifiers 31 | * may be reliable. Essentially they can only be relied upon in the case of a spatial dbms (such 32 | * as PostGIS) is being used. 33 | *

    34 | */ 35 | public class ISOTransactionEvent { 36 | private TransactionEventType type; 37 | private SimpleFeatureCollection affectedFeatures; 38 | private QName layerName; 39 | private Object source; 40 | private final TransactionRequest3D request; 41 | 42 | public ISOTransactionEvent(TransactionEventType type, TransactionRequest3D request, QName layerName, 43 | SimpleFeatureCollection affectedFeatures) { 44 | this( type, request, layerName, affectedFeatures, null ); 45 | } 46 | 47 | public ISOTransactionEvent(TransactionEventType type, TransactionRequest3D request, QName layerName, 48 | SimpleFeatureCollection affectedFeatures, Object source) { 49 | this.type = type; 50 | this.request = request; 51 | this.layerName = layerName; 52 | this.affectedFeatures = affectedFeatures; 53 | this.source = source; 54 | } 55 | 56 | /** 57 | * The type of change occurring 58 | */ 59 | public TransactionEventType getType() { 60 | return type; 61 | } 62 | 63 | /** 64 | * A collection of the features that are being manipulated. Accessible and usable only 65 | * when the event is being thrown, if you store the event and try to access the collection later 66 | * there is no guarantee it will still be usable. 67 | */ 68 | public SimpleFeatureCollection getAffectedFeatures() { 69 | return affectedFeatures; 70 | } 71 | 72 | /** 73 | * The name of the layer / feature type that this transaction effects. 74 | */ 75 | public QName getLayerName() { 76 | return layerName; 77 | } 78 | 79 | /** 80 | * Sets the source of the transction. 81 | */ 82 | public void setSource(Object source) { 83 | this.source = source; 84 | } 85 | 86 | /** 87 | * Returns the source of the transaction. 88 | *

    89 | * One of: 90 | *

      91 | *
    • {@link InsertElementType} 92 | *
    • {@link UpdateElementType} 93 | *
    • {@link DeleteElementType} 94 | *
    95 | *

    96 | */ 97 | public Object getSource() { 98 | return source; 99 | } 100 | 101 | public TransactionType getRequest() { 102 | return TransactionRequest3D.WFS11.unadapt(request); 103 | } 104 | 105 | /** 106 | * Returns the current GeoTools Data {@link Transaction} associated with this event. May be {@code null} 107 | * for post-commit events. 108 | */ 109 | public Transaction getTransaction() { 110 | return request.getTransaction(); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/ISOTransactionListener.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs; 7 | 8 | 9 | /** 10 | * Implemented by classes needing to listen to datastore change events during a 11 | * WFS Transaction 12 | */ 13 | public interface ISOTransactionListener { 14 | /** 15 | * Check/alter feature collections and filters before a change hits the 16 | * datastores 17 | *

    18 | * Note that caution should be exercised when relying on feature identifiers from a 19 | * {@link TransactionEventType#POST_INSERT} event. Depending on the type of store those identifiers 20 | * may be reliable. Essentially they can only be relied upon in the case of a spatial dbms (such 21 | * as PostGIS) is being used. 22 | *

    23 | */ 24 | void dataStoreChange(ISOTransactionEvent event) throws WFSException; 25 | } 26 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/WFSDescribeFeatureTypeOutputFormat_ISO.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs; 7 | 8 | import java.io.IOException; 9 | import java.io.OutputStream; 10 | import java.util.Set; 11 | 12 | import org.geoserver.catalog.FeatureTypeInfo; 13 | import org.geoserver.config.GeoServer; 14 | import org.geoserver.ows.SOAPAwareResponse; 15 | import org.geoserver.platform.Operation; 16 | import org.geoserver.platform.ServiceException; 17 | import org.geoserver.wfs.response.WFSResponse; 18 | 19 | import net.opengis.wfs.FeatureCollectionType; 20 | 21 | 22 | /** 23 | * Base class for a response to a WFS DescribeFeatureType operation. 24 | *

    25 | * The result of a DescribeFeatureType operation is an array of 26 | * {@link FeatureTypeInfo}. Subclasses are responsible for serializing these 27 | * instances. See {@link #write(FeatureCollectionType, OutputStream, Operation)}. 28 | *

    29 | *

    30 | * Subclasses also need declare the mime-type in which the format is encoded. 31 | *

    32 | * @author Justin Deoliveira, The Open Planning Project 33 | * 34 | */ 35 | public abstract class WFSDescribeFeatureTypeOutputFormat_ISO extends WFSResponse implements SOAPAwareResponse { 36 | /** 37 | * Constructor which sets the outputFormat. 38 | * 39 | * @param outputFormat The well-known name of the format, not null 40 | */ 41 | public WFSDescribeFeatureTypeOutputFormat_ISO(GeoServer gs, String outputFormat) { 42 | super(gs, FeatureTypeInfo[].class, outputFormat); 43 | } 44 | 45 | /** 46 | * Constructor which sets multiple outputFormats. 47 | * 48 | * @param outputFormat The well-known name of the format, not null 49 | */ 50 | public WFSDescribeFeatureTypeOutputFormat_ISO(GeoServer gs, Set outputFormats) { 51 | super(gs, FeatureTypeInfo[].class, outputFormats); 52 | } 53 | 54 | /** 55 | * Ensures that the operation being executed is a DescribeFeatureType operation. 56 | *

    57 | * This method may be extended to add additional checks, it should not be 58 | * overriden. 59 | *

    60 | */ 61 | public boolean canHandle(Operation operation) { 62 | if ("DescribeFeatureType".equalsIgnoreCase(operation.getId())) { 63 | return true; 64 | } 65 | 66 | return false; 67 | } 68 | 69 | public String getBodyType() { 70 | return "xsd:base64"; 71 | } 72 | 73 | /** 74 | * Calls through to {@link #write(FeatureTypeInfo[], OutputStream, Operation)}. 75 | */ 76 | public final void write(Object value, OutputStream output, Operation operation) 77 | throws IOException, ServiceException { 78 | 79 | write((FeatureTypeInfo[]) value, output, operation); 80 | } 81 | 82 | /** 83 | * Serializes the collection of feature type metadata objects in the format 84 | * declared. 85 | * 86 | * @param featureTypeInfos The feature type metadata objects to serialize 87 | * @param output The output stream to serialize to. 88 | * @param getFeature The DescribeFeatureType operation descriptor. 89 | */ 90 | protected abstract void write(FeatureTypeInfo[] featureTypeInfos, OutputStream output, 91 | Operation describeFeatureType) throws IOException; 92 | } 93 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/WFSFactoryExtension_ISO.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs; 7 | 8 | import org.geoserver.config.ServiceFactoryExtension; 9 | 10 | public class WFSFactoryExtension_ISO extends ServiceFactoryExtension { 11 | 12 | protected WFSFactoryExtension_ISO() { 13 | super(WFSInfo.class); 14 | } 15 | 16 | public T create(Class clazz) { 17 | return (T) new WFSInfoImpl_ISO(); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/WFSLoader_ISO.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs; 7 | 8 | import java.util.Map; 9 | 10 | import org.geoserver.config.GeoServer; 11 | import org.geoserver.config.util.LegacyServiceLoader; 12 | import org.geoserver.config.util.LegacyServicesReader; 13 | import org.geoserver.wfs.GMLInfo.SrsNameStyle; 14 | import org.geotools.util.Version; 15 | 16 | public class WFSLoader_ISO extends LegacyServiceLoader { 17 | 18 | public Class getServiceClass() { 19 | return WFSInfo.class; 20 | } 21 | 22 | public WFSInfo load(LegacyServicesReader reader, GeoServer geoServer) 23 | throws Exception { 24 | 25 | WFSInfoImpl_ISO wfs = new WFSInfoImpl_ISO(); 26 | wfs.setId( "wfs-3d" ); 27 | 28 | Map properties = reader.wfs(); 29 | readCommon( wfs, properties, geoServer ); 30 | 31 | //service level 32 | wfs.setServiceLevel( WFSInfo.ServiceLevel.get( (Integer) properties.get( "serviceLevel") ) ); 33 | 34 | //max features 35 | Integer maxFeatures = (Integer) reader.global().get( "maxFeatures" ); 36 | if ( maxFeatures == null ) { 37 | maxFeatures = Integer.MAX_VALUE; 38 | } 39 | wfs.setMaxFeatures( maxFeatures ); 40 | 41 | Boolean featureBounding = (Boolean) properties.get( "featureBounding"); 42 | if ( featureBounding != null ) { 43 | wfs.setFeatureBounding( featureBounding ); 44 | } 45 | 46 | Boolean hitsIgnoreMaxFeatures = (Boolean) properties.get( "hitsIgnoreMaxFeatures"); 47 | if (hitsIgnoreMaxFeatures != null) { 48 | wfs.setHitsIgnoreMaxFeatures( hitsIgnoreMaxFeatures ); 49 | } 50 | 51 | //gml2 52 | GMLInfo gml = new GMLInfoImpl(); 53 | gml.setOverrideGMLAttributes(true); 54 | 55 | Boolean srsXmlStyle = (Boolean) properties.get( "srsXmlStyle" ); 56 | if( srsXmlStyle ) { 57 | gml.setSrsNameStyle( SrsNameStyle.XML ); 58 | } 59 | else { 60 | gml.setSrsNameStyle( SrsNameStyle.NORMAL ); 61 | } 62 | wfs.getGML().put( WFSInfo.Version.V_10 , gml ); 63 | 64 | //gml3 65 | gml = new GMLInfoImpl(); 66 | gml.setSrsNameStyle(SrsNameStyle.URN); 67 | gml.setOverrideGMLAttributes(false); 68 | wfs.getGML().put( WFSInfo.Version.V_11 , gml ); 69 | 70 | //gml32 71 | gml = new GMLInfoImpl(); 72 | gml.setSrsNameStyle(SrsNameStyle.URN2); 73 | gml.setOverrideGMLAttributes(false); 74 | wfs.getGML().put( WFSInfo.Version.V_20 , gml ); 75 | 76 | wfs.getVersions().add( new Version( "1.0.0" ) ); 77 | wfs.getVersions().add( new Version( "1.1.0" ) ); 78 | wfs.getVersions().add( new Version( "2.0.0" ) ); 79 | 80 | return wfs; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/WFSReprojectionUtil_ISO.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs; 7 | 8 | import org.geotools.filter.ISOFilterFactoryImpl; 9 | import org.geotools.filter.spatial.DefaultCRSFilterVisitor; 10 | import org.geotools.filter.spatial.ISOReprojectingFilterVisitor; 11 | import org.geotools.filter.spatial.ReprojectingFilterVisitor; 12 | import org.geotools.gml2.iso.bindings.GML2EncodingUtils; 13 | import org.geotools.referencing.CRS; 14 | import org.opengis.feature.simple.SimpleFeatureType; 15 | import org.opengis.feature.type.FeatureType; 16 | import org.opengis.filter.Filter; 17 | import org.opengis.filter.FilterFactory2; 18 | import org.opengis.referencing.crs.CoordinateReferenceSystem; 19 | 20 | /** 21 | * Utility class used to handle common WFS reprojection issues 22 | * 23 | * @author Andrea Aime, TOPP 24 | * 25 | */ 26 | class WFSReprojectionUtil_ISO { 27 | 28 | static FilterFactory2 ff = new ISOFilterFactoryImpl(); 29 | 30 | /** 31 | * Returns the declared CRS given the native CRS and the request WFS version 32 | * 33 | * @param nativeCRS 34 | * @param wfsVersion 35 | * 36 | */ 37 | public static CoordinateReferenceSystem getDeclaredCrs(CoordinateReferenceSystem nativeCRS, 38 | String wfsVersion) { 39 | try { 40 | if(nativeCRS == null) 41 | return null; 42 | 43 | if (wfsVersion.equals("1.0.0")) { 44 | return nativeCRS; 45 | } else { 46 | String code = GML2EncodingUtils.epsgCode(nativeCRS); 47 | //it's possible that we can't do the CRS -> code -> CRS conversion...so we'll just return what we have 48 | if (code == null) return nativeCRS; 49 | return CRS.decode("urn:x-ogc:def:crs:EPSG:6.11.2:" + code); 50 | } 51 | } catch (Exception e) { 52 | throw new WFSException("We have had issues trying to flip axis of " + nativeCRS, e); 53 | } 54 | } 55 | 56 | /** 57 | * Returns the declared CRS given a feature type and the request WFS version 58 | * 59 | * @param nativeCRS 60 | * @param wfsVersion 61 | * 62 | */ 63 | public static CoordinateReferenceSystem getDeclaredCrs(FeatureType schema, String wfsVersion) { 64 | if (schema == null) 65 | return null; 66 | 67 | CoordinateReferenceSystem crs = (schema.getGeometryDescriptor() != null) ? schema 68 | .getGeometryDescriptor().getCoordinateReferenceSystem() : null; 69 | 70 | return getDeclaredCrs(crs, wfsVersion); 71 | } 72 | 73 | /** 74 | * Applies a default CRS to all geometric filter elements that do not 75 | * already have one 76 | * 77 | * @param nativeCRS 78 | * @param wfsVersion 79 | * 80 | */ 81 | public static Filter applyDefaultCRS(Filter filter, CoordinateReferenceSystem defaultCRS) { 82 | DefaultCRSFilterVisitor defaultVisitor = new DefaultCRSFilterVisitor(ff, defaultCRS); 83 | return (Filter) filter.accept(defaultVisitor, null); 84 | } 85 | 86 | /** 87 | * Reprojects all geometric filter elements to the native CRS of the 88 | * provided schema 89 | * 90 | * @param filter 91 | * @param schema 92 | * 93 | */ 94 | public static Filter reprojectFilter(Filter filter, FeatureType schema) { 95 | ISOReprojectingFilterVisitor visitor = new ISOReprojectingFilterVisitor(ff, schema); 96 | return (Filter) filter.accept(visitor, null); 97 | } 98 | 99 | /** 100 | * Convenience method, same as calling {@link #applyDefaultCRS} and then 101 | * {@link #reprojectFilter(Filter, SimpleFeatureType)} in a row 102 | * 103 | * @param filter 104 | * @param schema 105 | * @param defaultCRS 106 | * 107 | */ 108 | public static Filter normalizeFilterCRS(Filter filter, FeatureType schema, 109 | CoordinateReferenceSystem defaultCRS) { 110 | Filter defaulted = applyDefaultCRS(filter, defaultCRS); 111 | return reprojectFilter(defaulted, schema); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/WFSXStreamLoader_ISO.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 - 2015 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs; 7 | 8 | import java.util.ArrayList; 9 | import java.util.HashMap; 10 | 11 | import org.geoserver.config.GeoServer; 12 | import org.geoserver.config.util.XStreamPersister; 13 | import org.geoserver.config.util.XStreamServiceLoader; 14 | import org.geoserver.platform.GeoServerResourceLoader; 15 | import org.geoserver.wfs.GMLInfo.SrsNameStyle; 16 | 17 | import com.thoughtworks.xstream.XStream; 18 | 19 | /** 20 | * Loads and persist the {@link WFSInfo} object to and from xstream 21 | * persistence. 22 | * 23 | * @author Justin Deoliveira, The Open Planning Project 24 | * 25 | */ 26 | public class WFSXStreamLoader_ISO extends XStreamServiceLoader { 27 | 28 | public WFSXStreamLoader_ISO(GeoServerResourceLoader resourceLoader) { 29 | super(resourceLoader, "wfs3d"); 30 | } 31 | 32 | @Override 33 | public void initXStreamPersister(XStreamPersister xp, GeoServer gs) { 34 | super.initXStreamPersister(xp, gs); 35 | initXStreamPersister(xp); 36 | } 37 | 38 | /** 39 | * Sets up aliases and allowed types for the xstream persister 40 | * @param xs 41 | */ 42 | public static void initXStreamPersister(XStreamPersister xp) { 43 | XStream xs = xp.getXStream(); 44 | xs.alias( "wfs3d", WFSInfo.class, WFSInfoImpl_ISO.class ); 45 | xs.alias( "version", WFSInfo.Version.class); 46 | xs.alias( "gml", GMLInfo.class, GMLInfoImpl.class ); 47 | // modify the WFSSettingsResource when 48 | xs.allowTypes(new Class[] { WFSInfo.Version.class, GMLInfo.class, GMLInfoImpl.class }); 49 | } 50 | 51 | protected WFSInfo createServiceFromScratch(GeoServer gs) { 52 | WFSInfoImpl_ISO wfs = new WFSInfoImpl_ISO(); 53 | wfs.setName("WFS"); 54 | wfs.setMaxFeatures(1000000); 55 | 56 | //gml2 57 | addGml(wfs, WFSInfo.Version.V_10, GMLInfo.SrsNameStyle.XML, true); 58 | 59 | //gml3 60 | addGml(wfs, WFSInfo.Version.V_11, GMLInfo.SrsNameStyle.URN, false); 61 | 62 | //gml3.2 63 | addGml(wfs, WFSInfo.Version.V_20, SrsNameStyle.URN2, false); 64 | return wfs; 65 | } 66 | 67 | public Class getServiceClass() { 68 | return WFSInfo.class; 69 | } 70 | 71 | @Override 72 | protected WFSInfo initialize(WFSInfo service) { 73 | super.initialize(service); 74 | if ( service.getVersions().isEmpty() ) { 75 | service.getVersions().add(WFSInfo.Version.V_10.getVersion()); 76 | service.getVersions().add(WFSInfo.Version.V_11.getVersion()); 77 | } 78 | 79 | if (!service.getVersions().contains(WFSInfo.Version.V_20.getVersion())) { 80 | service.getVersions().add(WFSInfo.Version.V_20.getVersion()); 81 | } 82 | 83 | //set the defaults for GMLInfo if they are not set 84 | if(service.getGML() == null) { 85 | ((WFSInfoImpl_ISO) service).setGML(new HashMap()); 86 | } 87 | GMLInfo gml = service.getGML().get(WFSInfo.Version.V_10); 88 | if(gml == null) { 89 | addGml(service, WFSInfo.Version.V_10, SrsNameStyle.URL, false); 90 | } else if (gml.getOverrideGMLAttributes() == null) { 91 | gml.setOverrideGMLAttributes(true); 92 | } 93 | gml = service.getGML().get(WFSInfo.Version.V_11); 94 | if(gml == null) { 95 | addGml(service, WFSInfo.Version.V_11, SrsNameStyle.URN, false); 96 | } else if (gml.getOverrideGMLAttributes() == null) { 97 | gml.setOverrideGMLAttributes(false); 98 | } 99 | gml = service.getGML().get(WFSInfo.Version.V_20); 100 | if (gml == null) { 101 | addGml(service, WFSInfo.Version.V_20, SrsNameStyle.URN2, false); 102 | } 103 | if (service.getSRS() == null) { 104 | ((WFSInfoImpl_ISO) service).setSRS(new ArrayList()); 105 | } 106 | return service; 107 | } 108 | 109 | void addGml(WFSInfo info, WFSInfo.Version ver, SrsNameStyle srs, boolean overrideGmlAtts) { 110 | GMLInfo gml = new GMLInfoImpl(); 111 | gml.setSrsNameStyle(srs); 112 | gml.setOverrideGMLAttributes(overrideGmlAtts); 113 | info.getGML().put(ver, gml); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/AcceptFormatsKvpParser.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import net.opengis.ows10.AcceptFormatsType; 9 | import net.opengis.ows10.Ows10Factory; 10 | 11 | import org.eclipse.emf.ecore.EObject; 12 | import org.geoserver.wfs.WFSInfo; 13 | 14 | 15 | /** 16 | * Parses a kvp of the form "acceptFormats=format1,format2,...,formatN" into 17 | * an instance of {@link net.opengis.ows.v1_0_0.AcceptFormatsType}. 18 | * 19 | * @author Justin Deoliveira, The Open Planning Project 20 | * 21 | */ 22 | public class AcceptFormatsKvpParser extends org.geoserver.ows.kvp.AcceptFormatsKvpParser { 23 | 24 | public AcceptFormatsKvpParser() { 25 | super(AcceptFormatsType.class); 26 | setVersion(WFSInfo.Version.V_11.getVersion()); 27 | } 28 | 29 | protected EObject createObject() { 30 | return Ows10Factory.eINSTANCE.createAcceptFormatsType(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/AcceptVersionsKvpParser.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import net.opengis.ows10.AcceptVersionsType; 9 | import net.opengis.ows10.Ows10Factory; 10 | 11 | import org.eclipse.emf.ecore.EObject; 12 | import org.geoserver.wfs.WFSInfo; 13 | 14 | 15 | /** 16 | * Parses a kvp of the form "acceptVersions=version1,version2,...,versionN" into 17 | * an instance of {@link net.opengis.ows.v1_0_0.AcceptVersionsType}. 18 | * 19 | * @author Justin Deoliveira, The Open Planning Project 20 | * 21 | */ 22 | public class AcceptVersionsKvpParser extends org.geoserver.ows.kvp.AcceptVersionsKvpParser { 23 | 24 | public AcceptVersionsKvpParser() { 25 | super(AcceptVersionsType.class); 26 | setVersion(WFSInfo.Version.V_11.getVersion()); 27 | } 28 | 29 | protected EObject createObject() { 30 | return Ows10Factory.eINSTANCE.createAcceptVersionsType(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/BBoxKvpParser.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import java.util.List; 9 | 10 | import org.geoserver.ows.KvpParser; 11 | import org.geoserver.ows.util.KvpUtils; 12 | import org.geoserver.platform.ServiceException; 13 | import org.geoserver.wfs.WFSException; 14 | import org.geotools.geometry.jts.ReferencedEnvelope; 15 | import org.geotools.geometry.jts.ReferencedEnvelope3D; 16 | import org.geotools.referencing.CRS; 17 | import org.opengis.referencing.crs.CoordinateReferenceSystem; 18 | import org.opengis.referencing.crs.SingleCRS; 19 | 20 | import com.vividsolutions.jts.geom.Envelope; 21 | 22 | /** 23 | * 24 | * @author Niels Charlier : added 3D BBOX support 25 | * 26 | */ 27 | public class BBoxKvpParser extends KvpParser { 28 | public BBoxKvpParser() { 29 | super("bbox", Envelope.class); 30 | } 31 | 32 | public Object parse(String value) throws Exception { 33 | List unparsed = KvpUtils.readFlat(value, KvpUtils.INNER_DELIMETER); 34 | 35 | // check to make sure that the bounding box has 4 coordinates 36 | if (unparsed.size() < 4) { 37 | throw new IllegalArgumentException("Requested bounding box contains wrong" 38 | + "number of coordinates (should have " + "4): " + unparsed.size()); 39 | } 40 | 41 | int countco = 4; 42 | if (unparsed.size() == 6 || unparsed.size() == 7) { // 3d-coordinates 43 | countco = 6; 44 | } 45 | 46 | //if it does, store them in an array of doubles 47 | double[] bbox = new double[countco]; 48 | 49 | for (int i = 0; i < countco; i++) { 50 | try { 51 | bbox[i] = Double.parseDouble((String) unparsed.get(i)); 52 | } catch (NumberFormatException e) { 53 | throw new IllegalArgumentException("Bounding box coordinate " + i 54 | + " is not parsable:" + unparsed.get(i)); 55 | } 56 | } 57 | 58 | //ensure the values are sane 59 | double minx = bbox[0]; 60 | double miny = bbox[1]; 61 | double minz=0, maxx=0, maxy=0, maxz=0; 62 | if (countco == 6) { 63 | minz = bbox[2]; 64 | maxx = bbox[3]; 65 | maxy = bbox[4]; 66 | maxz = bbox[5]; 67 | } else { 68 | maxx = bbox[2]; 69 | maxy = bbox[3]; 70 | } 71 | 72 | if (minx > maxx) { 73 | throw new ServiceException("illegal bbox, minX: " + minx + " is " 74 | + "greater than maxX: " + maxx); 75 | } 76 | 77 | if (miny > maxy) { 78 | throw new ServiceException("illegal bbox, minY: " + miny + " is " 79 | + "greater than maxY: " + maxy); 80 | } 81 | 82 | if (minz > maxz) { 83 | throw new ServiceException("illegal bbox, minZ: " + minz + " is " 84 | + "greater than maxZ: " + maxz); 85 | } 86 | 87 | // check for srs 88 | String srs = null; 89 | if (unparsed.size() > countco) { 90 | // merge back the CRS definition, in case it is an AUTO one 91 | StringBuilder sb = new StringBuilder(); 92 | for (int i = countco; i < unparsed.size(); i++) { 93 | sb.append(unparsed.get(i)); 94 | if(i < (unparsed.size() - 1)) { 95 | sb.append(","); 96 | } 97 | } 98 | srs = sb.toString(); 99 | } 100 | 101 | if (countco == 6) { 102 | CoordinateReferenceSystem crs = srs != null ? CRS.decode(srs) : null; 103 | return new ReferencedEnvelope3D(minx, maxx, miny, maxy, minz, maxz, crs); 104 | } else { 105 | CoordinateReferenceSystem crs = srs != null ? CRS.decode(srs) : null; 106 | if(crs == null || crs.getCoordinateSystem().getDimension() == 2) { 107 | return new SRSEnvelope(minx, maxx, miny, maxy, srs); 108 | } else if(crs.getCoordinateSystem().getDimension() == 3) { 109 | return new ReferencedEnvelope3D(minx, maxx, miny, maxy, -Double.MAX_VALUE, Double.MAX_VALUE, crs); 110 | } else { 111 | throw new WFSException("Unexpected BBOX, can only handle 2D or 3D ones", "bbox", "InvalidParameterValue"); 112 | } 113 | 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/DescribeFeatureTypeKvpRequestReader.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | import javax.xml.XMLConstants; 13 | import javax.xml.namespace.QName; 14 | 15 | import net.opengis.wfs.DescribeFeatureTypeType; 16 | import net.opengis.wfs.WfsFactory; 17 | 18 | import org.eclipse.emf.ecore.EFactory; 19 | import org.geoserver.catalog.Catalog; 20 | import org.geoserver.wfs.WFSInfo; 21 | import org.geoserver.wfs.request.DescribeFeatureTypeRequest; 22 | import org.xml.sax.helpers.NamespaceSupport; 23 | 24 | 25 | public class DescribeFeatureTypeKvpRequestReader extends WFSKvpRequestReader { 26 | 27 | private final Catalog catalog; 28 | 29 | public DescribeFeatureTypeKvpRequestReader(final Catalog catalog) { 30 | super(DescribeFeatureTypeType.class, WfsFactory.eINSTANCE); 31 | this.catalog = catalog; 32 | } 33 | public DescribeFeatureTypeKvpRequestReader(final Catalog catalog, Class requestBean, EFactory factory) { 34 | super(requestBean, factory); 35 | this.catalog = catalog; 36 | } 37 | 38 | @SuppressWarnings("unchecked") 39 | public Object read(Object request, Map kvp, Map rawKvp) throws Exception { 40 | //let super do its thing 41 | request = super.read(request, kvp, rawKvp); 42 | 43 | //do an additional check for outputFormat, because the default 44 | // in wfs 1.1 is not the default for wfs 1.0 45 | DescribeFeatureTypeRequest req = DescribeFeatureTypeRequest.adapt(request); 46 | 47 | if (!req.isSetOutputFormat()) { 48 | switch(WFSInfo.Version.negotiate(req.getVersion())) { 49 | case V_10: 50 | req.setOutputFormat("XMLSCHEMA"); break; 51 | case V_11: 52 | req.setOutputFormat("text/xml; subtype=gml/3.1.1"); break; 53 | case V_20: 54 | default: 55 | req.setOutputFormat("text/xml; subtype=gml/3.2"); 56 | } 57 | } 58 | 59 | // did the user supply alternate namespace prefixes? 60 | NamespaceSupport namespaces = null; 61 | if (kvp.containsKey("NAMESPACE")) { 62 | if (kvp.get("NAMESPACE") instanceof NamespaceSupport) { 63 | namespaces = (NamespaceSupport) kvp.get("namespace"); 64 | } else { 65 | LOGGER.warning("There's a namespace parameter but it seems it wasn't parsed to a " 66 | + NamespaceSupport.class.getName() + ": " + kvp.get("namespace")); 67 | } 68 | } 69 | if (namespaces != null) { 70 | List typeNames = req.getTypeNames(); 71 | List newList = new ArrayList(typeNames.size()); 72 | for(QName name : typeNames){ 73 | String localPart = name.getLocalPart(); 74 | String prefix = name.getPrefix(); 75 | String namespaceURI = name.getNamespaceURI(); 76 | if (XMLConstants.DEFAULT_NS_PREFIX.equals(prefix)) { 77 | //no prefix specified, did the request specify a default namespace? 78 | namespaceURI = namespaces.getURI(XMLConstants.DEFAULT_NS_PREFIX); 79 | } else if (XMLConstants.NULL_NS_URI.equals(namespaceURI)) { 80 | //prefix specified, does a namespace mapping were declared for it? 81 | if(namespaces.getURI(prefix) != null){ 82 | namespaceURI = namespaces.getURI(prefix); 83 | } 84 | } 85 | if(catalog.getNamespaceByURI(namespaceURI) != null){ 86 | prefix = catalog.getNamespaceByURI(namespaceURI).getPrefix(); 87 | } 88 | newList.add(new QName(namespaceURI, localPart, prefix)); 89 | } 90 | req.setTypeNames(newList); 91 | } 92 | return request; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/Filter_1_0_0_KvpParser.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 - 2015 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import org.geoserver.config.GeoServer; 9 | import org.geotools.xml.Configuration; 10 | 11 | /** 12 | * Parses a {@code FILTER} parameter assuming the filters sent are encoded as 13 | * per the OGC Filter Encoding v1.0.0 specification. 14 | *

    15 | * This kvp parser is meant to be configured in the spring context to parse 16 | * filters when a GetFeature request is sent conforming to the WFS 1.0 spec. 17 | *

    18 | * 19 | * @author Gabriel Roldan 20 | */ 21 | public class Filter_1_0_0_KvpParser extends FilterKvpParser { 22 | 23 | public Filter_1_0_0_KvpParser(GeoServer geoServer) { 24 | super(geoServer); 25 | } 26 | 27 | /** 28 | * Provides the 1.0 filter configuration for the superclass to perform the 29 | * parameter parsing. 30 | */ 31 | @Override 32 | protected Configuration getParserConfiguration() { 33 | return new org.geotools.filter.v1_0.OGCConfiguration(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/Filter_1_1_0_KvpParser.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 - 2015 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import org.geoserver.config.GeoServer; 9 | import org.geotools.xml.Configuration; 10 | 11 | /** 12 | * Parses a {@code FILTER} parameter assuming the filters sent are encoded as 13 | * per the OGC Filter Encoding v1.0.0 specification. 14 | *

    15 | * This kvp parser is meant to be configured in the spring context to parse 16 | * filters when a GetFeature request is sent conforming to the WFS 1.1 spec. 17 | *

    18 | * 19 | * @author Gabriel Roldan 20 | */ 21 | public class Filter_1_1_0_KvpParser extends FilterKvpParser { 22 | 23 | public Filter_1_1_0_KvpParser(GeoServer geoServer) { 24 | super(geoServer); 25 | } 26 | 27 | @Override 28 | protected Configuration getParserConfiguration() { 29 | return new org.geotools.filter.v1_1.OGCConfiguration(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/Filter_2_0_0_KvpParser.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 - 2015 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import org.geoserver.config.GeoServer; 9 | import org.geotools.xml.Configuration; 10 | 11 | /** 12 | * Parses a {@code FILTER} parameter assuming the filters sent are encoded as 13 | * per the OGC Filter Encoding v2.0.0 specification. 14 | *

    15 | * This kvp parser is meant to be configured in the spring context to parse 16 | * filters when a GetFeature request is sent conforming to the WFS 2.0 spec. 17 | *

    18 | * 19 | * @author Justin Deoliveira 20 | */ 21 | public class Filter_2_0_0_KvpParser extends FilterKvpParser { 22 | 23 | public Filter_2_0_0_KvpParser(GeoServer geoServer) { 24 | super(geoServer); 25 | } 26 | 27 | @Override 28 | protected Configuration getParserConfiguration() { 29 | return new org.geotools.filter.v2_0.FESConfiguration(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/GetCapabilitiesKvpRequestReader.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import java.util.Map; 9 | 10 | import net.opengis.wfs.GetCapabilitiesType; 11 | import net.opengis.wfs.WfsFactory; 12 | 13 | import org.eclipse.emf.ecore.EFactory; 14 | import org.geoserver.wfs.request.GetCapabilitiesRequest3D; 15 | 16 | public class GetCapabilitiesKvpRequestReader extends WFSKvpRequestReader { 17 | 18 | public GetCapabilitiesKvpRequestReader() { 19 | this(GetCapabilitiesType.class, WfsFactory.eINSTANCE); 20 | } 21 | 22 | public GetCapabilitiesKvpRequestReader(Class requestBean, EFactory factory) { 23 | super(requestBean, factory); 24 | } 25 | 26 | @Override 27 | public Object read(Object request, Map kvp, Map rawKvp) throws Exception { 28 | request = super.read(request, kvp, rawKvp); 29 | 30 | //set the version attribute on the request 31 | if (kvp.containsKey("version")) { 32 | GetCapabilitiesRequest3D req = GetCapabilitiesRequest3D.adapt(request); 33 | //TODO: put this check in a cite hack 34 | if (req.getAcceptVersions() == null || req.getAcceptVersions().isEmpty()) { 35 | req.setAcceptVersions((String)kvp.get("version")); 36 | } 37 | } 38 | 39 | return request; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/QNameKvpParser.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import javax.xml.namespace.QName; 9 | 10 | import org.geoserver.catalog.Catalog; 11 | import org.geoserver.catalog.NamespaceInfo; 12 | import org.geoserver.ows.FlatKvpParser; 13 | import org.geoserver.wfs.WFSException; 14 | 15 | 16 | /** 17 | * Abstract kvp parser for parsing qualified names of the form "([prefix:]local)+". 18 | *

    19 | * This parser will parse strings of the above format into a list of 20 | * {@link javax.xml.namespace.QName} 21 | *

    22 | * @author Justin Deoliveira, The Open Planning Project 23 | * 24 | */ 25 | public class QNameKvpParser extends FlatKvpParser { 26 | /** 27 | * catalog for namespace lookups. 28 | */ 29 | protected Catalog catalog; 30 | 31 | private final boolean strict; 32 | 33 | public QNameKvpParser(String key, Catalog catalog) { 34 | this(key, catalog, true); 35 | } 36 | 37 | /** 38 | * 39 | * @param key 40 | * the key this kvp parser parses the value for 41 | * @param catalog 42 | * the catalog where to check if the namespace given by the qualified name prefix 43 | * exists 44 | * @param strict 45 | * if {@code true} and the qname being parsed contains a namespace prefix that does 46 | * not match a namespace from {@code catalog}, an exception will be thrown, otherwise a {@code QName} 47 | * with prefix and localName but without namespace will be returned. 48 | */ 49 | protected QNameKvpParser(String key, Catalog catalog, boolean strict) { 50 | super(key, QName.class); 51 | this.catalog = catalog; 52 | this.strict = strict; 53 | } 54 | 55 | /** 56 | * Parses the token representing a type name, ( :, or ) 57 | * into a {@link QName }. 58 | *

    59 | * If the latter form is supplied the QName is given the default namespace 60 | * as specified in the catalog. 61 | *

    62 | */ 63 | protected Object parseToken(String token) throws Exception { 64 | int i = token.indexOf(':'); 65 | 66 | if (i != -1) { 67 | String prefix = token.substring(0, i); 68 | String local = token.substring(i + 1); 69 | 70 | String uri = null; 71 | if(prefix != null && !"".equals(prefix)) { 72 | final NamespaceInfo namespace = catalog.getNamespaceByPrefix(prefix); 73 | if(strict && namespace == null){ 74 | throw new WFSException("Unknown namespace [" + prefix + "]"); 75 | } 76 | uri = namespace == null? null : namespace.getURI(); 77 | } 78 | 79 | return new QName(uri, local, prefix); 80 | } else { 81 | /* 82 | String uri = catalog.getDefaultNamespace().getURI(); 83 | String prefix = catalog.getDefaultNamespace().getPrefix(); 84 | String local = token; 85 | 86 | return new QName(uri, local, prefix); 87 | */ 88 | return new QName(token); 89 | } 90 | } 91 | 92 | 93 | } 94 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/QNameNestedKvpParser.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import javax.xml.namespace.QName; 9 | 10 | import org.geoserver.catalog.Catalog; 11 | import org.geoserver.ows.NestedKvpParser; 12 | 13 | public class QNameNestedKvpParser extends NestedKvpParser { 14 | 15 | QNameKvpParser delegate; 16 | 17 | public QNameNestedKvpParser(String key, Catalog catalog) { 18 | super(key, QName.class); 19 | delegate = new QNameKvpParser(key, catalog); 20 | } 21 | 22 | @Override 23 | protected Object parseToken(String token) throws Exception { 24 | return delegate.parseToken(token); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/ReleaseLockKvpRequestReader.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import java.util.Map; 9 | 10 | import org.geoserver.ows.KvpRequestReader; 11 | 12 | 13 | public class ReleaseLockKvpRequestReader extends KvpRequestReader { 14 | public ReleaseLockKvpRequestReader() { 15 | super(String.class); 16 | } 17 | 18 | public Object createRequest() throws Exception { 19 | return new String(); 20 | } 21 | 22 | public Object read(Object request, Map kvp, Map rawKvp) throws Exception { 23 | return kvp.get("lockId"); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/ResultTypeKvpParser.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import net.opengis.wfs.ResultTypeType; 9 | 10 | import org.geoserver.ows.KvpParser; 11 | 12 | 13 | /** 14 | * Parses a kvp of the form resultType=. 15 | *

    16 | * Allowable values are "hits", and "results", which get parsed into 17 | * the following respectivley. 18 | *

      19 | *
    • {@link net.opengis.wfs.ResultTypeType#HITS_LITERAL} 20 | *
    • {@link net.opengis.wfs.ResultTypeType#RESULTS_LITERAL} 21 | *
    22 | *

    23 | * @author Justin Deoliveira, The Open Planning Project 24 | * 25 | */ 26 | public class ResultTypeKvpParser extends KvpParser { 27 | public ResultTypeKvpParser() { 28 | super("resultType", ResultTypeType.class); 29 | } 30 | 31 | public Object parse(String value) throws Exception { 32 | if ("hits".equalsIgnoreCase(value)) { 33 | return ResultTypeType.HITS_LITERAL; 34 | } 35 | 36 | if ("results".equalsIgnoreCase(value)) { 37 | return ResultTypeType.RESULTS_LITERAL; 38 | } 39 | 40 | return null; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/SRSEnvelope.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import org.geotools.geometry.jts.ReferencedEnvelope; 9 | import org.geotools.referencing.CRS; 10 | import org.opengis.geometry.MismatchedDimensionException; 11 | import org.opengis.referencing.FactoryException; 12 | import org.opengis.referencing.NoSuchAuthorityCodeException; 13 | 14 | /** 15 | * A {@link ReferencedEnvelope} subclass that keeps the original SRS after the KVP parse, to ensure 16 | * we are true to the original SRS when building a BBOX filter 17 | * 18 | * @author Andrea Aime - GeoSolutions 19 | * 20 | */ 21 | class SRSEnvelope extends ReferencedEnvelope { 22 | private static final long serialVersionUID = 4510785331988235178L; 23 | String srs; 24 | 25 | public SRSEnvelope(double x1, double x2, double y1, double y2, String srs) 26 | throws MismatchedDimensionException, NoSuchAuthorityCodeException, FactoryException { 27 | super(x1, x2, y1, y2, srs != null ? CRS.decode(srs) : null); 28 | this.srs = srs; 29 | } 30 | 31 | public String getSrs() { 32 | return srs; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/SortByKvpParser.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import org.geoserver.ows.NestedKvpParser; 9 | import org.opengis.filter.FilterFactory; 10 | import org.opengis.filter.sort.SortBy; 11 | import org.opengis.filter.sort.SortOrder; 12 | 13 | 14 | /** 15 | * Parses kvp of the form 'sortBy=Field1 {A|D},Field2 {A|D}...' into a 16 | * list of {@link org.opengis.filter.sort.SortBy}. 17 | * 18 | * @author Justin Deoliveira, The Open Planning Project 19 | * 20 | */ 21 | public class SortByKvpParser extends NestedKvpParser { 22 | FilterFactory filterFactory; 23 | 24 | public SortByKvpParser(FilterFactory filterFactory) { 25 | super("sortBy", SortBy.class); 26 | this.filterFactory = filterFactory; 27 | } 28 | 29 | /** 30 | * Parses a token of the form 'Field1 {A|D}' into an instnace of 31 | * {@link SortBy}. 32 | */ 33 | protected Object parseToken(String token) throws Exception { 34 | String[] nameOrder = token.split(" "); 35 | String propertyName = nameOrder[0]; 36 | 37 | SortOrder order = SortOrder.ASCENDING; 38 | 39 | if (nameOrder.length > 1) { 40 | if ("D".equalsIgnoreCase(nameOrder[1]) || "DESC".equalsIgnoreCase(nameOrder[1])) { 41 | order = SortOrder.DESCENDING; 42 | } 43 | } 44 | 45 | return filterFactory.sort(propertyName, order); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/SrsNameKvpParser.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import java.net.URI; 9 | 10 | import org.geoserver.ows.FlatKvpParser; 11 | import org.geoserver.ows.KvpParser; 12 | 13 | /** 14 | * Kvp Parser which parses srsName strings like "epsg:4326" into a URI. 15 | * 16 | * @author Justin Deoliveira, The Open Planning Project 17 | * 18 | */ 19 | public class SrsNameKvpParser extends KvpParser { 20 | 21 | public SrsNameKvpParser() { 22 | super("srsName", URI.class); 23 | 24 | } 25 | 26 | public Object parse(String token) throws Exception { 27 | return new URI(token); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/TypeNameKvpParser.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import javax.xml.namespace.QName; 9 | 10 | import org.geoserver.catalog.Catalog; 11 | import org.geoserver.catalog.FeatureTypeInfo; 12 | import org.geoserver.config.GeoServer; 13 | import org.geoserver.wfs.WFSInfo; 14 | import org.opengis.feature.type.Name; 15 | 16 | /** 17 | * Parses a {@code typeName} GetFeature parameter the form "([prefix:]local)+". 18 | *

    19 | * This parser will parse strings of the above format into a list of 20 | * {@link javax.xml.namespace.QName} 21 | *

    22 | * 23 | * @author Justin Deoliveira, The Open Planning Project 24 | * @author groldan 25 | */ 26 | public class TypeNameKvpParser extends QNameKvpParser { 27 | 28 | GeoServer geoserver; 29 | 30 | public TypeNameKvpParser(String key, GeoServer geoserver, Catalog catalog) { 31 | super(key, catalog, false); 32 | this.geoserver = geoserver; 33 | } 34 | 35 | protected Object parseToken(String token) throws Exception { 36 | int i = token.indexOf(':'); 37 | 38 | if (i != -1 || geoserver.getService(WFSInfo.class).isCiteCompliant()) { 39 | return super.parseToken(token); 40 | } else { 41 | // we don't have the namespace, use the catalog to lookup the feature type 42 | // mind, this is lenient behavior so we use it only if the server is not runnig in cite mode 43 | FeatureTypeInfo ftInfo = catalog.getFeatureTypeByName(token); 44 | if(ftInfo == null) { 45 | return new QName(null, token); 46 | } else { 47 | final Name name = ftInfo.getFeatureType().getName(); 48 | return new QName(name.getNamespaceURI(), name.getLocalPart()); 49 | } 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/TypeNamesKvpParser.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import org.geoserver.config.GeoServer; 9 | 10 | public class TypeNamesKvpParser extends QNameNestedKvpParser { 11 | 12 | TypeNameKvpParser delegate; 13 | 14 | public TypeNamesKvpParser(String key, GeoServer gs) { 15 | super(key, gs.getCatalog()); 16 | delegate = new TypeNameKvpParser(key, gs, gs.getCatalog()); 17 | } 18 | 19 | @Override 20 | protected Object parseToken(String token) throws Exception { 21 | return delegate.parseToken(token); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/URIKvpParser.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import java.net.URI; 9 | 10 | import org.geoserver.ows.FlatKvpParser; 11 | 12 | /** 13 | * Kvp parser that parses to URI. 14 | * 15 | * @author Justin Deoliveira, OpenGeo 16 | */ 17 | public class URIKvpParser extends FlatKvpParser { 18 | 19 | public URIKvpParser(String key) { 20 | super(key, URI.class); 21 | } 22 | 23 | @Override 24 | protected Object parseToken(String token) throws Exception { 25 | return new URI(token); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/kvp/WFSKvpRequestReader.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.kvp; 7 | 8 | import net.opengis.wfs.WfsFactory; 9 | 10 | import org.eclipse.emf.ecore.EFactory; 11 | import org.geoserver.ows.kvp.EMFKvpRequestReader; 12 | 13 | 14 | /** 15 | * Web Feature Service Key Value Pair Request reader. 16 | *

    17 | * This request reader makes use of the Eclipse Modelling Framework 18 | * reflection api. 19 | *

    20 | * @author Justin Deoliveira, The Open Planning Project 21 | * 22 | */ 23 | public class WFSKvpRequestReader extends EMFKvpRequestReader { 24 | 25 | /** 26 | * Creates the Wfs Kvp Request reader. 27 | * 28 | * @param requestBean The request class, which must be an emf class. 29 | */ 30 | public WFSKvpRequestReader(Class requestBean) { 31 | this(requestBean, WfsFactory.eINSTANCE); 32 | } 33 | 34 | /** 35 | * Creates the Wfs Kvp Request reader specifying the factory. 36 | * 37 | * @param requestBean The request class, which must be an emf class. 38 | * @param factory The emf factory for the request bean. 39 | */ 40 | public WFSKvpRequestReader(Class requestBean, EFactory factory) { 41 | super(requestBean, factory); 42 | } 43 | 44 | protected EFactory getFactory() { 45 | return factory; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/request/Delete3D.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.request; 7 | 8 | import net.opengis.wfs.DeleteElementType; 9 | import net.opengis.wfs.WfsFactory; 10 | 11 | import org.eclipse.emf.ecore.EObject; 12 | import org.geoserver.wfs.request.Insert.WFS11; 13 | 14 | /** 15 | * Delete element in a Transaction request. 16 | * 17 | * @author Justin Deoliveira, OpenGeo 18 | */ 19 | public abstract class Delete3D extends TransactionElement { 20 | 21 | protected Delete3D(EObject adaptee) { 22 | super(adaptee); 23 | } 24 | 25 | public static class WFS11 extends Delete3D { 26 | public WFS11(EObject adaptee) { 27 | super(adaptee); 28 | } 29 | 30 | public static DeleteElementType unadapt(Delete3D delete) { 31 | DeleteElementType de = WfsFactory.eINSTANCE.createDeleteElementType(); 32 | de.setHandle(delete.getHandle()); 33 | de.setTypeName(delete.getTypeName()); 34 | de.setFilter(delete.getFilter()); 35 | return de; 36 | } 37 | } 38 | 39 | public static class WFS20 extends Delete3D { 40 | public WFS20(EObject adaptee) { 41 | super(adaptee); 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/request/GetCapabilitiesRequest3D.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.request; 7 | 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | import net.opengis.ows10.Ows10Factory; 12 | import net.opengis.ows11.Ows11Factory; 13 | import net.opengis.wfs.GetCapabilitiesType; 14 | 15 | import org.eclipse.emf.ecore.EObject; 16 | 17 | /** 18 | * WFS GetCapabilities request. 19 | * 20 | * @author Justin Deoliveira, OpenGeo 21 | */ 22 | public abstract class GetCapabilitiesRequest3D extends GetCapabilitiesRequest { 23 | 24 | public static GetCapabilitiesRequest3D adapt(Object request) { 25 | if (request instanceof GetCapabilitiesType) { 26 | return new WFS11((EObject) request); 27 | } 28 | else if (request instanceof net.opengis.wfs20.GetCapabilitiesType) { 29 | return new WFS20((EObject) request); 30 | } 31 | return null; 32 | } 33 | 34 | protected GetCapabilitiesRequest3D(EObject adaptee) { 35 | super(adaptee); 36 | } 37 | 38 | public String getUpdateSequence() { 39 | return eGet(adaptee, "updateSequence", String.class); 40 | } 41 | 42 | public List getAcceptVersions() { 43 | return eGet(adaptee, "acceptVersions.version", List.class); 44 | } 45 | 46 | public List getAcceptFormats() { 47 | return eGet(adaptee, "acceptFormats.outputFormat", List.class); 48 | } 49 | 50 | public void setAcceptVersions(String... versions) { 51 | Object acceptedVersions = createAcceptedVersions(); 52 | eAdd(acceptedVersions, "version", Arrays.asList(versions)); 53 | eSet(adaptee, "acceptVersions", acceptedVersions); 54 | } 55 | 56 | public String getNamespace() { 57 | return eGet(adaptee, "namespace", String.class); 58 | } 59 | 60 | public void setNamespace(String namespace) { 61 | eSet(adaptee, "namespace", namespace); 62 | } 63 | 64 | protected abstract Object createAcceptedVersions(); 65 | 66 | public static class WFS11 extends GetCapabilitiesRequest3D { 67 | 68 | public WFS11(EObject adaptee) { 69 | super(adaptee); 70 | } 71 | 72 | @Override 73 | protected Object createAcceptedVersions() { 74 | return Ows10Factory.eINSTANCE.createAcceptVersionsType(); 75 | } 76 | } 77 | 78 | public static class WFS20 extends GetCapabilitiesRequest3D { 79 | 80 | public WFS20(EObject adaptee) { 81 | super(adaptee); 82 | } 83 | 84 | @Override 85 | protected Object createAcceptedVersions() { 86 | return Ows11Factory.eINSTANCE.createAcceptVersionsType(); 87 | } 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/request/Insert3D.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.request; 7 | 8 | import java.util.List; 9 | 10 | import net.opengis.wfs.IdentifierGenerationOptionType; 11 | import net.opengis.wfs.InsertElementType; 12 | import net.opengis.wfs.WfsFactory; 13 | import net.opengis.wfs20.InsertType; 14 | 15 | import org.eclipse.emf.ecore.EObject; 16 | 17 | /** 18 | * Insert element in a Transaction request. 19 | * 20 | * @author Justin Deoliveira, OpenGeo 21 | */ 22 | public abstract class Insert3D extends TransactionElement { 23 | 24 | protected Insert3D(EObject adaptee) { 25 | super(adaptee); 26 | } 27 | 28 | public abstract List getFeatures(); 29 | 30 | public boolean isIdGenUseExisting() { 31 | return false; 32 | } 33 | 34 | public static class WFS11 extends Insert3D { 35 | 36 | public WFS11(EObject adaptee) { 37 | super(adaptee); 38 | } 39 | 40 | @Override 41 | public List getFeatures() { 42 | return eGet(adaptee, "feature", List.class); 43 | } 44 | 45 | @Override 46 | public boolean isIdGenUseExisting() { 47 | return ((InsertElementType)adaptee).getIdgen() 48 | == IdentifierGenerationOptionType.USE_EXISTING_LITERAL; 49 | } 50 | 51 | public static InsertElementType unadapt(Insert3D insert) { 52 | if (insert instanceof WFS11) { 53 | return (InsertElementType) insert.getAdaptee(); 54 | } 55 | 56 | InsertElementType ie = WfsFactory.eINSTANCE.createInsertElementType(); 57 | ie.setHandle(insert.getHandle()); 58 | ie.getFeature().addAll(insert.getFeatures()); 59 | 60 | return ie; 61 | } 62 | } 63 | 64 | public static class WFS20 extends Insert3D { 65 | 66 | public WFS20(EObject adaptee) { 67 | super(adaptee); 68 | } 69 | 70 | @Override 71 | public List getFeatures() { 72 | return eGet(adaptee, "any", List.class); 73 | } 74 | 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/request/Native3D.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.request; 7 | 8 | import net.opengis.wfs.NativeType; 9 | import net.opengis.wfs.WfsFactory; 10 | 11 | import org.eclipse.emf.ecore.EObject; 12 | import org.geoserver.wfs.request.Insert.WFS11; 13 | 14 | /** 15 | * Native element in a Transaction request. 16 | * 17 | * @author Justin Deoliveira, OpenGeo 18 | */ 19 | public abstract class Native3D extends TransactionElement { 20 | 21 | protected Native3D(EObject adaptee) { 22 | super(adaptee); 23 | } 24 | 25 | public boolean isSafeToIgnore() { 26 | return eGet(adaptee, "safeToIgnore", Boolean.class); 27 | } 28 | 29 | public String getVendorId() { 30 | return eGet(adaptee, "vendorId", String.class); 31 | } 32 | 33 | public static class WFS11 extends Native3D { 34 | public WFS11(EObject adaptee) { 35 | super(adaptee); 36 | } 37 | 38 | public static NativeType unadapt(Native3D nativ) { 39 | NativeType n = WfsFactory.eINSTANCE.createNativeType(); 40 | n.setSafeToIgnore(nativ.isSafeToIgnore()); 41 | n.setVendorId(nativ.getVendorId()); 42 | //TODO: value 43 | return n; 44 | } 45 | } 46 | 47 | public static class WFS20 extends Native3D { 48 | public WFS20(EObject adaptee) { 49 | super(adaptee); 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/request/Update3D.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.request; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | import net.opengis.wfs.InsertElementType; 12 | import net.opengis.wfs.UpdateElementType; 13 | import net.opengis.wfs.WfsFactory; 14 | 15 | import org.eclipse.emf.ecore.EObject; 16 | import org.geoserver.wfs.UpdateElementHandler; 17 | import org.geoserver.wfs.request.Insert.WFS11; 18 | 19 | /** 20 | * Update element in a Transaction request. 21 | * 22 | * @author Justin Deoliveira, OpenGeo 23 | */ 24 | public abstract class Update3D extends TransactionElement { 25 | 26 | protected Update3D(EObject adaptee) { 27 | super(adaptee); 28 | } 29 | 30 | public abstract List getUpdateProperties(); 31 | 32 | public static class WFS11 extends Update3D { 33 | public WFS11(EObject adaptee) { 34 | super(adaptee); 35 | } 36 | 37 | @Override 38 | public List getUpdateProperties() { 39 | List list = new ArrayList(); 40 | for (Object o : eGet(adaptee, "property", List.class)) { 41 | list.add(new Property.WFS11((EObject) o)); 42 | } 43 | return list; 44 | } 45 | 46 | public static UpdateElementType unadapt(Update3D update) { 47 | if (update instanceof WFS11) { 48 | return (UpdateElementType) update.getAdaptee(); 49 | } 50 | 51 | UpdateElementType ue = WfsFactory.eINSTANCE.createUpdateElementType(); 52 | ue.setHandle(update.getHandle()); 53 | ue.setTypeName(update.getTypeName()); 54 | ue.setFilter(update.getFilter()); 55 | 56 | for (Property p : update.getUpdateProperties()) { 57 | ue.getProperty().add(Property.WFS11.unadapt(p)); 58 | } 59 | return ue; 60 | } 61 | } 62 | 63 | public static class WFS20 extends Update3D { 64 | public WFS20(EObject adaptee) { 65 | super(adaptee); 66 | } 67 | 68 | @Override 69 | public List getUpdateProperties() { 70 | List list = new ArrayList(); 71 | for (Object o : eGet(adaptee, "property", List.class)) { 72 | list.add(new Property.WFS20((EObject) o)); 73 | } 74 | return list; 75 | } 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/response/GetCapabilitiesResponse3D.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.response; 7 | 8 | import java.io.IOException; 9 | import java.io.OutputStream; 10 | import java.util.Iterator; 11 | import java.util.List; 12 | 13 | import javax.xml.transform.TransformerException; 14 | 15 | import org.geoserver.ows.Response; 16 | import org.geoserver.platform.Operation; 17 | import org.geoserver.wfs.request.GetCapabilitiesRequest; 18 | import org.geoserver.wfs.request.GetCapabilitiesRequest3D; 19 | import org.geotools.xml.transform.TransformerBase; 20 | 21 | 22 | public class GetCapabilitiesResponse3D extends Response { 23 | public GetCapabilitiesResponse3D() { 24 | super(TransformerBase.class); 25 | } 26 | 27 | /** 28 | * Makes sure this triggers only 29 | *

    30 | */ 31 | public boolean canHandle(Operation operation) { 32 | // is this a wfs capabilities request? 33 | return "GetCapabilities".equalsIgnoreCase(operation.getId()) && 34 | operation.getService().getId().equals("wfs-3d"); 35 | } 36 | 37 | public String getMimeType(Object value, Operation operation) { 38 | GetCapabilitiesRequest3D request = GetCapabilitiesRequest3D.adapt(operation.getParameters()[0]); 39 | 40 | if ((request != null) && (request.getAcceptFormats() != null)) { 41 | //look for an accepted format 42 | List formats = request.getAcceptFormats(); 43 | 44 | for (Iterator f = formats.iterator(); f.hasNext();) { 45 | String format = (String) f.next(); 46 | 47 | if (format.endsWith("/xml")) { 48 | return format; 49 | } 50 | } 51 | } 52 | 53 | //default 54 | return "application/xml"; 55 | } 56 | 57 | public void write(Object value, OutputStream output, Operation operation) 58 | throws IOException { 59 | TransformerBase tx = (TransformerBase) value; 60 | 61 | try { 62 | tx.transform(operation.getParameters()[0], output); 63 | } catch (TransformerException e) { 64 | throw (IOException) new IOException().initCause(e); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/xml/GML2Profile_ISO.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.xml; 7 | 8 | import java.util.HashSet; 9 | import java.util.Set; 10 | 11 | import org.geotools.feature.NameImpl; 12 | import org.geotools.feature.type.ProfileImpl; 13 | import org.geotools.gml2.GML; 14 | import org.geotools.gml2.iso.GMLSchema; 15 | 16 | 17 | public class GML2Profile_ISO extends TypeMappingProfile { 18 | static Set profiles = new HashSet(); 19 | 20 | static { 21 | //profile.add(new Name(GML.NAMESPACE, GML.POINTTYPE.getLocalPart())); 22 | Set profile = new HashSet(); 23 | profile.add(new NameImpl(GML.NAMESPACE, GML.PointPropertyType.getLocalPart())); 24 | //profile.add(new Name(GML.NAMESPACE, GML.MULTIPOINTTYPE.getLocalPart())); 25 | profile.add(new NameImpl(GML.NAMESPACE, GML.MultiPointPropertyType.getLocalPart())); 26 | 27 | //profile.add(new Name(GML.NAMESPACE, GML.LINESTRINGTYPE.getLocalPart())); 28 | profile.add(new NameImpl(GML.NAMESPACE, GML.LineStringPropertyType.getLocalPart())); 29 | //profile.add(new Name(GML.NAMESPACE, GML.MULTILINESTRINGTYPE.getLocalPart())); 30 | profile.add(new NameImpl(GML.NAMESPACE, GML.MultiLineStringPropertyType.getLocalPart())); 31 | 32 | //profile.add(new Name(GML.NAMESPACE, GML.POLYGONTYPE.getLocalPart())); 33 | profile.add(new NameImpl(GML.NAMESPACE, GML.PolygonPropertyType.getLocalPart())); 34 | //profile.add(new Name(GML.NAMESPACE, GML.MULTIPOLYGONTYPE.getLocalPart())); 35 | profile.add(new NameImpl(GML.NAMESPACE, GML.MultiPolygonPropertyType.getLocalPart())); 36 | 37 | profile.add(new NameImpl(GML.NAMESPACE, GML.GeometryPropertyType.getLocalPart())); 38 | profiles.add( new ProfileImpl( new GMLSchema(), profile ) ); 39 | } 40 | 41 | public GML2Profile_ISO() { 42 | super(profiles); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/xml/GML3FeatureTransformer.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.xml; 7 | 8 | import java.util.Set; 9 | 10 | import org.geotools.gml.producer.FeatureTransformer; 11 | import org.geotools.gml.producer.GeometryTransformer.GeometryTranslator; 12 | import org.geotools.gml3.GML; 13 | import org.opengis.feature.simple.SimpleFeature; 14 | import org.xml.sax.Attributes; 15 | import org.xml.sax.ContentHandler; 16 | import org.xml.sax.helpers.AttributesImpl; 17 | 18 | 19 | public class GML3FeatureTransformer extends FeatureTransformer { 20 | protected FeatureTranslator createTranslator(ContentHandler handler, String prefix, String ns, 21 | FeatureTypeNamespaces featureTypeNamespaces, SchemaLocationSupport schemaLocationSupport) { 22 | return new GML3FeatureTranslator(handler, prefix, ns, featureTypeNamespaces, 23 | schemaLocationSupport); 24 | } 25 | 26 | protected void loadGmlAttributes(Set set) { 27 | set.add("name"); 28 | set.add("description"); 29 | } 30 | 31 | public static class GML3FeatureTranslator extends FeatureTranslator { 32 | public GML3FeatureTranslator(ContentHandler handler, String prefix, String ns, 33 | FeatureTypeNamespaces featureTypeNamespaces, SchemaLocationSupport schemaLocationSupport) { 34 | super(handler, prefix, ns, featureTypeNamespaces, schemaLocationSupport); 35 | } 36 | 37 | protected GeometryTranslator createGeometryTranslator(ContentHandler handler) { 38 | return new GML3GeometryTranslator(handler); 39 | } 40 | 41 | protected GeometryTranslator createGeometryTranslator(ContentHandler handler, 42 | int numDecimals) { 43 | return new GML3GeometryTranslator(handler, numDecimals); 44 | } 45 | 46 | protected GeometryTranslator createGeometryTranslator(ContentHandler handler, 47 | int numDecimals, boolean useDummyZ) { 48 | return new GML3GeometryTranslator(handler, numDecimals, useDummyZ); 49 | } 50 | 51 | protected Attributes encodeFeatureId(SimpleFeature f) { 52 | AttributesImpl atts = new AttributesImpl(); 53 | 54 | if (f.getID() != null) { 55 | atts.addAttribute(GML.NAMESPACE, "id", "gml:id", null, f.getID()); 56 | } 57 | 58 | return atts; 59 | } 60 | 61 | protected String boxElement() { 62 | return "Envelope"; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/xml/GML3GeometryTranslator.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.xml; 7 | 8 | import org.geotools.gml.producer.GeometryTransformer.GeometryTranslator; 9 | import org.xml.sax.ContentHandler; 10 | 11 | 12 | public class GML3GeometryTranslator extends GeometryTranslator { 13 | public GML3GeometryTranslator(ContentHandler handler) { 14 | super(handler); 15 | } 16 | 17 | public GML3GeometryTranslator(ContentHandler handler, int numDecimals, boolean useDummyZ) { 18 | super(handler, numDecimals, useDummyZ); 19 | } 20 | 21 | public GML3GeometryTranslator(ContentHandler handler, int numDecimals) { 22 | super(handler, numDecimals); 23 | } 24 | 25 | protected String boxName() { 26 | return "Envelope"; 27 | } 28 | 29 | protected void encodeNullBounds() { 30 | element("Null", null); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/xml/GML3Profile_ISO.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.xml; 7 | 8 | import java.util.HashSet; 9 | import java.util.LinkedHashSet; 10 | import java.util.Set; 11 | 12 | import org.geotools.feature.NameImpl; 13 | import org.geotools.feature.type.ProfileImpl; 14 | import org.geotools.gml3.iso.GML; 15 | import org.geotools.gml3.iso.GMLSchema; 16 | 17 | 18 | public class GML3Profile_ISO extends TypeMappingProfile { 19 | static Set profiles = new HashSet(); 20 | 21 | static { 22 | // set with guaranteed iteration order, so that we can put deprecated elements only 23 | // after the ones that replaced them 24 | Set profile = new LinkedHashSet(); 25 | 26 | //basic 27 | profile.add(new NameImpl(GML.NAMESPACE, GML.MeasureType.getLocalPart())); 28 | 29 | //geomtetries 30 | //profile.add( new NameImpl( GML.NAMESPACE, GML.PointType.getLocalPart() ) ); 31 | profile.add(new NameImpl(GML.NAMESPACE, GML.PointPropertyType.getLocalPart())); 32 | //profile.add( new NameImpl( GML.NAMESPACE, GML.MultiPointType.getLocalPart() ) ); 33 | profile.add(new NameImpl(GML.NAMESPACE, GML.MultiPointPropertyType.getLocalPart())); 34 | 35 | //profile.add( new NameImpl( GML.NAMESPACE, GML.LineStringType.getLocalPart() ) ); 36 | profile.add(new NameImpl(GML.NAMESPACE, GML.LineStringPropertyType.getLocalPart())); 37 | //profile.add( new NameImpl( GML.NAMESPACE, GML.MultiLineStringType.getLocalPart() ) ); 38 | profile.add(new NameImpl(GML.NAMESPACE, GML.MultiLineStringPropertyType.getLocalPart())); 39 | 40 | //profile.add( new NameImpl( GML.NAMESPACE, GML.CurveType.getLocalPart() ) ); 41 | profile.add(new NameImpl(GML.NAMESPACE, GML.CurvePropertyType.getLocalPart())); 42 | //profile.add( new NameImpl( GML.NAMESPACE, GML.MultiCurveType.getLocalPart() ) ); 43 | profile.add(new NameImpl(GML.NAMESPACE, GML.MultiCurvePropertyType.getLocalPart())); 44 | 45 | profile.add(new NameImpl(GML.NAMESPACE, GML.SurfacePropertyType.getLocalPart())); 46 | //profile.add( new NameImpl( GML.NAMESPACE, GML.MultiSurfaceType.getLocalPart() ) ); 47 | profile.add(new NameImpl(GML.NAMESPACE, GML.MultiSurfacePropertyType.getLocalPart())); 48 | 49 | // register polygon and multipolygon only after surface, the iteration order 50 | // will make sure surface is found before in any encoding attempt, this way we 51 | // are still able to handle polygons, but we don't use them by default 52 | //profile.add( new NameImpl( GML.NAMESPACE, GML.PolygonType.getLocalPart() ) ); 53 | profile.add(new NameImpl(GML.NAMESPACE, GML.PolygonPropertyType.getLocalPart())); 54 | //profile.add( new NameImpl( GML.NAMESPACE, GML.MultiPolygonType.getLocalPart() ) ); 55 | profile.add(new NameImpl(GML.NAMESPACE, GML.MultiPolygonPropertyType.getLocalPart())); 56 | 57 | //profile.add( new NameImpl( GML.NAMESPACE, GML.SolidType.getLocalPart() ) ); 58 | profile.add(new NameImpl(GML.NAMESPACE, GML.SolidPropertyType.getLocalPart())); 59 | 60 | //profile.add( new NameImpl( GML.NAMESPACE, GML.AbstractGeometryType.getLocalPart() ) ); 61 | profile.add(new NameImpl(GML.NAMESPACE, GML.GeometryPropertyType.getLocalPart())); 62 | profile.add(new NameImpl(GML.NAMESPACE, GML.MultiGeometryPropertyType.getLocalPart())); 63 | 64 | profiles.add( new ProfileImpl( new GMLSchema(), profile ) ); 65 | } 66 | 67 | public GML3Profile_ISO() { 68 | super(profiles); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/xml/ISOWFSHandlerFactory.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.xml; 7 | 8 | import java.io.IOException; 9 | import java.util.Iterator; 10 | import java.util.logging.Level; 11 | import java.util.logging.Logger; 12 | 13 | import javax.xml.namespace.QName; 14 | 15 | import org.eclipse.xsd.XSDAttributeDeclaration; 16 | import org.eclipse.xsd.XSDElementDeclaration; 17 | import org.eclipse.xsd.XSDSchema; 18 | import org.geoserver.catalog.Catalog; 19 | import org.geoserver.catalog.FeatureTypeInfo; 20 | import org.geotools.xml.impl.AttributeHandler; 21 | import org.geotools.xml.impl.DocumentHandler; 22 | import org.geotools.xml.impl.ElementHandler; 23 | import org.geotools.xml.impl.ElementHandlerImpl; 24 | import org.geotools.xml.impl.Handler; 25 | import org.geotools.xml.impl.HandlerFactory; 26 | import org.geotools.xml.impl.ParserHandler; 27 | 28 | 29 | /** 30 | * Special handler factory which creates handlers for elements which are 31 | * defined as wfs feature types. 32 | * 33 | * @author Justin Deoliveira, The Open Planning Project 34 | * 35 | */ 36 | public class ISOWFSHandlerFactory implements HandlerFactory { 37 | static Logger logger = org.geotools.util.logging.Logging.getLogger("org.geoserver.wfs"); 38 | 39 | /** 40 | * Catalog reference 41 | */ 42 | Catalog catalog; 43 | 44 | /** 45 | * Schema Builder 46 | */ 47 | ISOFeatureTypeSchemaBuilder schemaBuilder; 48 | 49 | public ISOWFSHandlerFactory(Catalog catalog, ISOFeatureTypeSchemaBuilder schemaBuilder) { 50 | this.catalog = catalog; 51 | this.schemaBuilder = schemaBuilder; 52 | } 53 | 54 | public DocumentHandler createDocumentHandler(ParserHandler parser) { 55 | return null; 56 | } 57 | 58 | public ElementHandler createElementHandler(QName name, Handler parent, ParserHandler parser) { 59 | String namespaceURI = name.getNamespaceURI(); 60 | 61 | if (namespaceURI == null) { 62 | //assume default 63 | namespaceURI = catalog.getDefaultNamespace().getURI(); 64 | } 65 | 66 | try { 67 | //look for a FeatureType 68 | FeatureTypeInfo meta = catalog.getFeatureTypeByName( namespaceURI, name.getLocalPart() ); 69 | 70 | if (meta != null) { 71 | //found it 72 | XSDSchema schema = schemaBuilder.build(meta, null); 73 | 74 | for (Iterator e = schema.getElementDeclarations().iterator(); e.hasNext();) { 75 | XSDElementDeclaration element = (XSDElementDeclaration) e.next(); 76 | 77 | if (name.getLocalPart().equals(element.getName())) { 78 | return new ElementHandlerImpl(element, parent, parser); 79 | } 80 | } 81 | } 82 | } catch (IOException e) { 83 | logger.log(Level.WARNING, "Error building schema", e); 84 | } 85 | 86 | return null; 87 | } 88 | 89 | public ElementHandler createElementHandler(XSDElementDeclaration e, Handler parent, 90 | ParserHandler parser) { 91 | return null; 92 | } 93 | 94 | public AttributeHandler createAttributeHandler(XSDAttributeDeclaration a, Handler parent, 95 | ParserHandler parser) { 96 | return null; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/xml/gml2/GMLBoxTypeBinding_ISO.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.xml.gml2; 7 | 8 | import java.net.URI; 9 | 10 | import org.geotools.geometry.jts.ReferencedEnvelope; 11 | import org.geotools.referencing.CRS; 12 | import org.geotools.referencing.crs.DefaultGeographicCRS; 13 | import org.geotools.xml.ElementInstance; 14 | import org.geotools.xml.Node; 15 | import org.opengis.geometry.Envelope; 16 | import org.opengis.geometry.ISOGeometryBuilder; 17 | import org.opengis.referencing.crs.CoordinateReferenceSystem; 18 | 19 | /** 20 | * Subclass of {@link GMLBoxTypeBinding_ISO} that parses srsName and 21 | * can inherit the CRS from the containing elements 22 | * 23 | * @author Andrea Aime 24 | */ 25 | public class GMLBoxTypeBinding_ISO extends org.geotools.gml2.iso.bindings.GMLBoxTypeBinding { 26 | 27 | public GMLBoxTypeBinding_ISO(ISOGeometryBuilder gBuilder) { 28 | super(gBuilder); 29 | // TODO Auto-generated constructor stub 30 | } 31 | 32 | public GMLBoxTypeBinding_ISO() { 33 | super(new ISOGeometryBuilder(DefaultGeographicCRS.WGS84_3D)); 34 | // TODO Auto-generated constructor stub 35 | } 36 | 37 | CoordinateReferenceSystem crs; 38 | 39 | public void setCRS(CoordinateReferenceSystem crs) { 40 | this.crs = crs; 41 | } 42 | 43 | @Override 44 | public Object parse(ElementInstance instance, Node node, Object value) throws Exception { 45 | Envelope envelope = (Envelope) super.parse(instance, node, value); 46 | 47 | // handle the box CRS 48 | CoordinateReferenceSystem crs = this.crs; 49 | if (node.hasAttribute("srsName")) { 50 | URI srs = (URI) node.getAttributeValue("srsName"); 51 | crs = CRS.decode(srs.toString()); 52 | } 53 | 54 | if(crs != null) { 55 | return ReferencedEnvelope.create(envelope, crs); 56 | } else { 57 | return envelope; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/xml/v1_0_0/GMLAbstractFeatureTypeBinding.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.xml.v1_0_0; 7 | 8 | import org.geoserver.catalog.Catalog; 9 | import org.geoserver.catalog.FeatureTypeInfo; 10 | import org.geotools.geometry.GeometryBuilder; 11 | import org.geotools.gml2.iso.FeatureTypeCache; 12 | import org.geotools.xml.BindingWalkerFactory; 13 | import org.geotools.xml.Configuration; 14 | import org.geotools.xml.ElementInstance; 15 | import org.geotools.xml.Node; 16 | import org.geotools.xml.SchemaIndex; 17 | import org.opengis.feature.type.AttributeDescriptor; 18 | import org.opengis.feature.type.FeatureType; 19 | import org.opengis.feature.type.PropertyDescriptor; 20 | import org.opengis.geometry.Envelope; 21 | import org.opengis.geometry.primitive.Surface; 22 | 23 | 24 | public final class GMLAbstractFeatureTypeBinding extends org.geotools.gml2.iso.bindings.GMLAbstractFeatureTypeBinding { 25 | GeometryBuilder geometryBuilder; 26 | Catalog catalog; 27 | //SchemaIndex schemaIndex; 28 | public GMLAbstractFeatureTypeBinding(FeatureTypeCache featureTypeCache, 29 | BindingWalkerFactory bwFactory, SchemaIndex schemaIndex, GeometryBuilder geometryBuilder, Catalog catalog, Configuration configuration) { 30 | super(featureTypeCache, bwFactory, schemaIndex, configuration); 31 | this.geometryBuilder = geometryBuilder; 32 | this.catalog = catalog; 33 | } 34 | 35 | public Object parse(ElementInstance instance, Node node, Object value) 36 | throws Exception { 37 | //pre process parsee tree to make sure types match up 38 | FeatureTypeInfo meta = catalog.getFeatureTypeByName(instance.getNamespace(), instance.getName()); 39 | if (meta != null) { 40 | FeatureType featureType = meta.getFeatureType(); 41 | 42 | //go through each attribute, performing various hacks to make make sure things 43 | // cocher 44 | for (PropertyDescriptor pd : featureType.getDescriptors()) { 45 | if (pd instanceof AttributeDescriptor) { 46 | AttributeDescriptor attributeType = (AttributeDescriptor) pd; 47 | String name = attributeType.getLocalName(); 48 | Class type = attributeType.getType().getBinding(); 49 | 50 | if ("boundedBy".equals(name)) { 51 | Node boundedByNode = node.getChild("boundedBy"); 52 | 53 | //hack 1: if boundedBy is in the parse tree has a bounding box and the attribute 54 | // needs a polygon, convert 55 | if (boundedByNode.getValue() instanceof Envelope) { 56 | Envelope bounds = (Envelope) boundedByNode.getValue(); 57 | 58 | /*if (type.isAssignableFrom(Surface.class)) { 59 | Polygon polygon = polygon(bounds); 60 | boundedByNode.setValue(polygon); 61 | } else if (type.isAssignableFrom(MultiPolygon.class)) { 62 | MultiPolygon multiPolygon = geometryFactory.createMultiPolygon(new Polygon[] { 63 | polygon(bounds) 64 | }); 65 | boundedByNode.setValue(multiPolygon); 66 | }*/ 67 | } 68 | } 69 | 70 | } 71 | } 72 | } 73 | 74 | return super.parse(instance, node, value); 75 | } 76 | 77 | /*Polygon polygon(Envelope bounds) { 78 | return geometryFactory.createPolygon(geometryFactory.createLinearRing( 79 | new Coordinate[] { 80 | new Coordinate(bounds.getMinX(), bounds.getMinY()), 81 | new Coordinate(bounds.getMinX(), bounds.getMaxY()), 82 | new Coordinate(bounds.getMaxX(), bounds.getMaxY()), 83 | new Coordinate(bounds.getMaxX(), bounds.getMinY()), 84 | new Coordinate(bounds.getMinX(), bounds.getMinY()) 85 | }), null); 86 | }*/ 87 | } 88 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/xml/v1_0_0/WfsXmlReader_ISO.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 - 2015 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.xml.v1_0_0; 7 | 8 | import java.io.Reader; 9 | import java.util.Iterator; 10 | import java.util.Map; 11 | 12 | import javax.xml.namespace.QName; 13 | 14 | import org.geoserver.catalog.Catalog; 15 | import org.geoserver.config.GeoServer; 16 | import org.geoserver.ows.XmlRequestReader; 17 | import org.geoserver.util.EntityResolverProvider; 18 | import org.geoserver.wfs.CatalogNamespaceSupport; 19 | import org.geoserver.wfs.WFSException; 20 | import org.geoserver.wfs.xml.WFSURIHandler; 21 | import org.geotools.util.Version; 22 | import org.geotools.xml.Configuration; 23 | import org.geotools.xml.Parser; 24 | 25 | /** 26 | * Xml reader for wfs 1.0.0 xml requests. 27 | * 28 | * @author Justin Deoliveira, The Open Planning Project 29 | * 30 | * TODO: there is too much duplication with the 1.1.0 reader, factor it out. 31 | */ 32 | public class WfsXmlReader_ISO extends XmlRequestReader { 33 | /** 34 | * Xml Configuration 35 | */ 36 | Configuration configuration; 37 | /** 38 | * geoserver configuration 39 | */ 40 | GeoServer geoServer; 41 | 42 | EntityResolverProvider entityResolverProvider; 43 | 44 | public WfsXmlReader_ISO(String element, Configuration configuration, GeoServer geoServer) { 45 | this(element, configuration, geoServer, "wfs3d"); 46 | } 47 | 48 | protected WfsXmlReader_ISO(String element, Configuration configuration, GeoServer geoServer, String serviceId) { 49 | super(new QName(WFS.NAMESPACE, element), new Version("1.0.0"), serviceId); 50 | this.configuration = configuration; 51 | this.geoServer = geoServer; 52 | this.entityResolverProvider = new EntityResolverProvider(geoServer); 53 | } 54 | 55 | public Object read(Object request, Reader reader, Map kvp) throws Exception { 56 | //TODO: refactor this method to use WFSXmlUtils 57 | Catalog catalog = geoServer.getCatalog(); 58 | 59 | //check the strict flag to determine if we should validate or not 60 | Boolean strict = (Boolean) kvp.get("strict"); 61 | if ( strict == null ) { 62 | strict = Boolean.FALSE; 63 | } 64 | 65 | //create the parser instance 66 | Parser parser = new Parser(configuration); 67 | parser.setEntityResolver(entityResolverProvider.getEntityResolver()); 68 | 69 | //"inject" namespace mappings 70 | parser.getNamespaces().add(new CatalogNamespaceSupport(catalog)); 71 | 72 | //set validation based on strict or not 73 | parser.setValidating(strict.booleanValue()); 74 | WFSURIHandler.addToParser(geoServer, parser); 75 | 76 | //parse 77 | Object parsed = parser.parse(reader); 78 | 79 | //if strict was set, check for validation errors and throw an exception 80 | if (strict.booleanValue() && !parser.getValidationErrors().isEmpty()) { 81 | WFSException exception = new WFSException("Invalid request", "InvalidParameterValue"); 82 | 83 | for (Iterator e = parser.getValidationErrors().iterator(); e.hasNext();) { 84 | Exception error = (Exception) e.next(); 85 | exception.getExceptionText().add(error.getLocalizedMessage()); 86 | } 87 | 88 | throw exception; 89 | } 90 | 91 | return parsed; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/xml/v1_1_0/WfsXmlReader_ISO.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 - 2015 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.xml.v1_1_0; 7 | 8 | import java.io.Reader; 9 | import java.util.Map; 10 | 11 | import javax.xml.namespace.QName; 12 | 13 | import org.geoserver.config.GeoServer; 14 | import org.geoserver.ows.XmlRequestReader; 15 | import org.geoserver.wfs.WFSInfo; 16 | import org.geoserver.wfs.xml.WFSURIHandler; 17 | import org.geoserver.wfs.xml.WFSXmlUtils; 18 | import org.geoserver.util.EntityResolverProvider; 19 | import org.geotools.util.Version; 20 | import org.geotools.xml.Configuration; 21 | import org.geotools.xml.Parser; 22 | 23 | /** 24 | * Xml reader for wfs 1.1.0 xml requests. 25 | * 26 | * @author Justin Deoliveira, The Open Planning Project 27 | * 28 | * TODO: there is too much duplication with the 1.0.0 reader, factor it out. 29 | */ 30 | public class WfsXmlReader_ISO extends XmlRequestReader { 31 | /** 32 | * WFs configuration 33 | */ 34 | WFSInfo wfs; 35 | 36 | /** 37 | * Xml Configuration 38 | */ 39 | Configuration configuration; 40 | 41 | /** 42 | * geoserver configuartion 43 | */ 44 | GeoServer geoServer; 45 | 46 | EntityResolverProvider entityResolverProvider; 47 | 48 | public WfsXmlReader_ISO(String element, GeoServer gs, Configuration configuration) { 49 | this(element, gs, configuration, "wfs3d"); 50 | } 51 | 52 | protected WfsXmlReader_ISO(String element, GeoServer gs, Configuration configuration, String serviceId) { 53 | super(new QName(org.geoserver.wfs.xml.v1_1_0.WFS.NAMESPACE, element), new Version("1.1.0"), 54 | serviceId); 55 | this.geoServer = gs; 56 | this.wfs = gs.getService( WFSInfo.class ); 57 | this.configuration = configuration; 58 | this.entityResolverProvider = new EntityResolverProvider(geoServer); 59 | } 60 | 61 | public Object read(Object request, Reader reader, Map kvp) throws Exception { 62 | //TODO: make this configurable? 63 | configuration.getProperties().add(Parser.Properties.PARSE_UNKNOWN_ELEMENTS); 64 | 65 | Parser parser = new Parser(configuration); 66 | parser.setEntityResolver(entityResolverProvider.getEntityResolver()); 67 | 68 | WFSXmlUtils.initRequestParser(parser, wfs, geoServer, kvp); 69 | Object parsed = WFSXmlUtils.parseRequest(parser, reader, wfs); 70 | 71 | WFSXmlUtils.checkValidationErrors(parser, this); 72 | 73 | return parsed; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/xml/v2_0/GetFeatureTypeBinding.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.xml.v2_0; 7 | 8 | import javax.xml.namespace.NamespaceContext; 9 | import javax.xml.namespace.QName; 10 | import net.opengis.wfs20.Wfs20Factory; 11 | import org.geoserver.wfs.xml.SqlViewParamsExtractor; 12 | import org.geotools.xml.ElementInstance; 13 | import org.geotools.xml.Node; 14 | import org.geotools.wfs.v2_0.WFS; 15 | import org.geotools.xml.ComplexEMFBinding; 16 | 17 | /** 18 | * Custom binding class to support viewParams attribute in GetFeatureType requests 19 | */ 20 | public class GetFeatureTypeBinding extends ComplexEMFBinding { 21 | 22 | NamespaceContext namespaceContext; 23 | 24 | public GetFeatureTypeBinding(NamespaceContext namespaceContext) { 25 | super(Wfs20Factory.eINSTANCE, WFS.QueryType); 26 | this.namespaceContext = namespaceContext; 27 | } 28 | 29 | public QName getTarget() { 30 | return WFS.GetFeatureType; 31 | } 32 | 33 | public Object parse(ElementInstance instance, Node node, Object value) throws Exception { 34 | SqlViewParamsExtractor.fixNodeObject(node); 35 | return super.parse(instance, node, value); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/xml/v2_0/WFSConfiguration_ISO.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 - 2015 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.xml.v2_0; 7 | 8 | import java.util.Map; 9 | 10 | import org.geotools.geometry.jts.CurvedGeometryFactory; 11 | import org.geotools.gml3.iso.v3_2.GMLConfiguration_ISO; 12 | import org.geotools.referencing.crs.DefaultGeographicCRS; 13 | import org.geotools.wfs.v2_0.WFS; 14 | import org.opengis.geometry.ISOGeometryBuilder; 15 | 16 | /** 17 | * Extend GeoTools WFSConfiguration to provide a custom binding class for GetFeatureType 18 | */ 19 | public class WFSConfiguration_ISO extends org.geotools.wfs.v2_0.WFSConfiguration { 20 | 21 | WFSConfiguration_ISO() { 22 | // OGC and OWS add two extra GML configurations in the mix, make sure to configure them 23 | // all with a geomtetry factory supporting curves 24 | ISOGeometryBuilder gb = new ISOGeometryBuilder(DefaultGeographicCRS.WGS84_3D); 25 | for (Object configuration : allDependencies()) { 26 | if (configuration instanceof GMLConfiguration_ISO) { 27 | GMLConfiguration_ISO gml = (GMLConfiguration_ISO) configuration; 28 | gml.setGeometryFactory(gb); 29 | } 30 | } 31 | } 32 | 33 | @Override 34 | protected void registerBindings(Map bindings) { 35 | super.registerBindings(bindings); 36 | bindings.put(WFS.GetFeatureType,org.geoserver.wfs.xml.v2_0.GetFeatureTypeBinding.class); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /gs-wfs-iso/src/main/java/org/geoserver/wfs/xml/v2_0/WfsXmlReader.java: -------------------------------------------------------------------------------- 1 | /* (c) 2014 - 2015 Open Source Geospatial Foundation - all rights reserved 2 | * (c) 2001 - 2013 OpenPlans 3 | * This code is licensed under the GPL 2.0 license, available at the root 4 | * application directory. 5 | */ 6 | package org.geoserver.wfs.xml.v2_0; 7 | 8 | import java.io.Reader; 9 | import java.util.Map; 10 | 11 | import javax.xml.namespace.QName; 12 | 13 | import org.geoserver.config.GeoServer; 14 | import org.geoserver.ows.XmlRequestReader; 15 | import org.geoserver.platform.ServiceException; 16 | import org.geoserver.wfs.WFSException; 17 | import org.geoserver.wfs.WFSInfo; 18 | import org.geoserver.wfs.xml.ISOFeatureTypeSchemaBuilder; 19 | import org.geoserver.wfs.xml.WFSURIHandler; 20 | import org.geoserver.wfs.xml.WFSXmlUtils_ISO; 21 | import org.geoserver.util.EntityResolverProvider; 22 | import org.geotools.util.Version; 23 | import org.geotools.wfs.v2_0.WFS; 24 | import org.geotools.xml.Parser; 25 | 26 | /** 27 | * Xml reader for wfs 2.0 xml requests. 28 | * 29 | * @author Justin Deoliveira, OpenGeo 30 | * 31 | */ 32 | public class WfsXmlReader extends XmlRequestReader { 33 | 34 | GeoServer gs; 35 | EntityResolverProvider entityResolverProvider; 36 | 37 | public WfsXmlReader(String element, GeoServer gs) { 38 | super(new QName(WFS.NAMESPACE, element), new Version("2.0.0"), "wfs"); 39 | this.gs = gs; 40 | this.entityResolverProvider = new EntityResolverProvider(gs); 41 | } 42 | 43 | @Override 44 | public Object read(Object request, Reader reader, Map kvp) throws Exception { 45 | WFSConfiguration_ISO config = new WFSConfiguration_ISO(); 46 | WFSXmlUtils_ISO.initWfsConfiguration(config, gs, new ISOFeatureTypeSchemaBuilder.GML32(gs)); 47 | 48 | Parser parser = new Parser(config); 49 | parser.setEntityResolver(entityResolverProvider.getEntityResolver()); 50 | 51 | WFSInfo wfs = wfs(); 52 | 53 | WFSXmlUtils_ISO.initRequestParser(parser, wfs, gs, kvp); 54 | Object parsed = null; 55 | try { 56 | parsed = WFSXmlUtils_ISO.parseRequest(parser, reader, wfs); 57 | } 58 | catch(Exception e) { 59 | //check the exception, and set code to OperationParsingFailed if code not set 60 | if (!(e instanceof ServiceException) || ((ServiceException)e).getCode() == null) { 61 | e = new WFSException("Request parsing failed", e, "OperationParsingFailed"); 62 | } 63 | throw e; 64 | } 65 | 66 | WFSXmlUtils_ISO.checkValidationErrors(parser, this); 67 | 68 | return parsed; 69 | } 70 | 71 | WFSInfo wfs() { 72 | return gs.getService(WFSInfo.class); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | org.geoserver 6 | geoserver-iso 7 | 2.9-SNAPSHOT 8 | GeoServer 3D Extension 9 | 10 | 11 | gs-wfs-iso 12 | gs-main-iso 13 | gs-web-iso 14 | 15 | 16 | pom 17 | 18 | 19 | 20 | boundless 21 | Boundless Maven Repository 22 | https://repo.boundlessgeo.com/main/ 23 | 24 | 25 | 26 | 27 | true 28 | 29 | 30 | true 31 | 32 | 33 | 34 | 35 | osgeo 36 | Open Source Geospatial Foundation Repository 37 | http://download.osgeo.org/webdav/geotools/ 38 | 39 | 40 | 41 | 42 | geosolutions 43 | geosolutions repository 44 | http://maven.geo-solutions.it/ 45 | 46 | true 47 | 48 | 49 | true 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | org.apache.maven.plugins 59 | maven-compiler-plugin 60 | 2.3.2 61 | 62 | 1.8 63 | 1.8 64 | true 65 | UTF-8 66 | ${fork.javac} 67 | ${javac.maxHeapSize} 68 | 69 | 70 | 71 | 72 | 73 | 74 | org.geoserver 75 | community 76 | 2.9-SNAPSHOT 77 | 78 | --------------------------------------------------------------------------------