/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved. * This code is licensed under the GPL 2.0 license, availible at the root * application directory. */ package org.geoserver.wfsv.response.v1_1_0; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.Charset; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.xml.namespace.QName; import net.opengis.wfs.BaseRequestType; import net.opengis.wfs.TransactionType; import net.opengis.wfsv.GetDiffType; import org.geoserver.catalog.Catalog; import org.geoserver.catalog.FeatureTypeInfo; import org.geoserver.config.GeoServer; import org.geoserver.config.GeoServerInfo; import org.geoserver.ows.Response; import org.geoserver.ows.util.OwsUtils; import org.geoserver.platform.Operation; import org.geoserver.platform.ServiceException; import org.geoserver.wfs.WFSInfo; import org.geoserver.wfsv.VersioningTransactionConverter; import org.geotools.data.FeatureDiffReader; import org.geotools.xml.Configuration; import org.geotools.xml.Encoder; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.filter.FilterFactory; /** * WFS output format for a GetDiff operation whose output format is a WFS 1.1 * transaction * * @author Andrea Aime, TOPP * */ public abstract class AbstractTransactionOutputFormat extends Response { /** * WFS configuration */ WFSInfo wfs; Catalog catalog; GeoServerInfo global; /** * Xml configuration */ Configuration configuration; /** * Filter factory used to build fid filters */ FilterFactory filterFactory; /** * The element to be encoded */ QName element; /** * The mime type for this output format */ String mime; public AbstractTransactionOutputFormat(GeoServer gs, Configuration configuration, FilterFactory filterFactory, QName element, String mime) { super(FeatureDiffReader[].class); this.wfs = gs.getService( WFSInfo.class ); this.global = gs.getGlobal(); this.configuration = configuration; this.catalog = gs.getCatalog(); this.filterFactory = filterFactory; this.element = element; this.mime = mime; } /** * @return "text/xml"; */ public String getMimeType(Object value, Operation operation) throws ServiceException { return "text/xml; subtype=wfs-transaction/1.1.0"; } /** * Checks that the resultType is of type "hits". */ public boolean canHandle(Operation operation) { GetDiffType request = (GetDiffType) OwsUtils.parameter(operation.getParameters(), GetDiffType.class); return (request != null) && request.getOutputFormat().equals(mime); } public void write(Object value, OutputStream output, Operation operation) throws IOException, ServiceException { final FeatureDiffReader[] diffReaders = (FeatureDiffReader[]) value; // create a new feature collcetion type with just the numbers VersioningTransactionConverter converter = new VersioningTransactionConverter(); final TransactionType transaction = converter.convert(diffReaders, TransactionType.class); //declare wfs schema location BaseRequestType gft = (BaseRequestType) operation.getParameters()[0]; Encoder encoder = new Encoder(configuration, configuration.schema()); encodeWfsSchemaLocation(encoder, gft.getBaseUrl()); encoder.setIndenting(true); encoder.setEncoding(Charset.forName( global.getCharset() )); // set up schema locations // round up the info objects for each feature collection HashMap /* <String,Set> */ ns2metas = new HashMap(); for (int i = 0; i < diffReaders.length; i++) { final FeatureDiffReader diffReader = diffReaders[i]; final SimpleFeatureType featureType = diffReader.getSchema(); // load the metadata for the feature type String namespaceURI = featureType.getName().getNamespaceURI(); FeatureTypeInfo meta = catalog.getFeatureTypeByName( namespaceURI, featureType.getName().getLocalPart() ); // add it to the map Set metas = (Set) ns2metas.get(namespaceURI); if (metas == null) { metas = new HashSet(); ns2metas.put(namespaceURI, metas); } metas.add(meta); } // declare application schema namespaces for (Iterator i = ns2metas.entrySet().iterator(); i.hasNext();) { Map.Entry entry = (Map.Entry) i.next(); String namespaceURI = (String) entry.getKey(); Set metas = (Set) entry.getValue(); StringBuffer typeNames = new StringBuffer(); for (Iterator m = metas.iterator(); m.hasNext();) { FeatureTypeInfo meta = (FeatureTypeInfo) m.next(); typeNames.append(meta.getName()); if (m.hasNext()) { typeNames.append(","); } } // set the schema location encodeTypeSchemaLocation(encoder, gft.getBaseUrl(), namespaceURI, typeNames); } try { encoder.encode(transaction, element, output); } finally { for (int i = 0; i < diffReaders.length; i++) { diffReaders[i].close(); } } } protected abstract void encodeTypeSchemaLocation(Encoder encoder, String baseURL, String namespaceURI, StringBuffer typeNames); protected abstract void encodeWfsSchemaLocation(Encoder encoder, String baseURL); }