/* 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.wfs.response;
import static org.geoserver.ows.util.ResponseUtils.buildSchemaURL;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.Iterator;
import net.opengis.wfs.ActionType;
import net.opengis.wfs.InsertResultsType;
import net.opengis.wfs.InsertedFeatureType;
import net.opengis.wfs.TransactionResponseType;
import net.opengis.wfs.TransactionResultsType;
import net.opengis.wfs.TransactionType;
import org.geoserver.catalog.Catalog;
import org.geoserver.config.GeoServer;
import org.geoserver.ows.Response;
import org.geoserver.ows.util.ResponseUtils;
import org.geoserver.platform.Operation;
import org.geoserver.platform.ServiceException;
import org.geoserver.wfs.WFSException;
import org.geoserver.wfs.WFSInfo;
import org.geoserver.wfs.xml.v1_1_0.WFSConfiguration;
import org.geotools.util.Version;
import org.geotools.xml.Encoder;
import org.opengis.filter.identity.FeatureId;
public class TransactionResponse extends WFSResponse {
private boolean verbose = false;
private String indent = " ";
private String offset = "";
Catalog catalog;
WFSConfiguration configuration;
public TransactionResponse(GeoServer gs, WFSConfiguration configuration) {
super(gs, TransactionResponseType.class);
this.catalog = gs.getCatalog();
this.configuration = configuration;
}
public String getMimeType(Object value, Operation operation)
throws ServiceException {
return "text/xml";
}
public void write(Object value, OutputStream output, Operation operation)
throws IOException, ServiceException {
TransactionResponseType response = (TransactionResponseType) value;
if (new Version("1.0.0").equals(operation.getService().getVersion())) {
v_1_0(response, output, operation);
} else {
v_1_1(response, output, operation);
}
}
public void v_1_0(TransactionResponseType response, OutputStream output, Operation operation)
throws IOException, ServiceException {
TransactionResultsType result = response.getTransactionResults();
Charset charset = Charset.forName( getInfo().getGeoServer().getGlobal().getCharset() );
Writer writer = new OutputStreamWriter(output, charset);
writer = new BufferedWriter(writer);
//boolean verbose = ConfigInfo.getInstance().formatOutput();
//String indent = ((verbose) ? "\n" + OFFSET : " ");
String encoding = charset.name();
String xmlHeader = "<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>";
writer.write(xmlHeader);
if (verbose) {
writer.write("\n");
}
writer.write("<wfs:WFS_TransactionResponse");
writer.write(indent + "version=\"1.0.0\"");
writer.write(indent + "xmlns:wfs=\"http://www.opengis.net/wfs\"");
writer.write(indent + "xmlns:ogc=\"http://www.opengis.net/ogc\"");
writer.write(indent + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
writer.write(indent);
writer.write("xsi:schemaLocation=\"http://www.opengis.net/wfs ");
TransactionType req = (TransactionType)operation.getParameters()[0];
String baseUrl = buildSchemaURL(req.getBaseUrl(), "wfs/1.0.0/WFS-transaction.xsd");
writer.write(baseUrl);
writer.write("\">");
InsertResultsType insertResults = response.getInsertResults();
//JD: make sure we group insert results by handle, this is wfs 1.0 cite
// thing that conflicts with wfs 1.1 cite, i am pretty sure its just a
// problem with the 1.0 tests
String lastHandle = null;
boolean first = true;
if (insertResults != null) {
for (Iterator i = insertResults.getFeature().iterator(); i.hasNext();) {
InsertedFeatureType insertedFeature = (InsertedFeatureType) i.next();
String handle = insertedFeature.getHandle();
if (first || ((lastHandle == null) && (handle != null))
|| ((lastHandle != null) && (handle != null) && handle.equals(lastHandle))) {
if (!first) {
//close last one, if not the first time through
writer.write("</wfs:InsertResult>");
}
writer.write("<wfs:InsertResult");
if (insertedFeature.getHandle() != null) {
writer.write(" handle=\"" + insertedFeature.getHandle() + "\"");
}
writer.write(">");
}
for (Iterator id = insertedFeature.getFeatureId().iterator(); id.hasNext();) {
FeatureId featureId = (FeatureId) id.next();
writer.write("<ogc:FeatureId fid=\"" + featureId.toString() + "\"/>");
}
first = false;
lastHandle = handle;
}
writer.write("</wfs:InsertResult>");
}
writer.write(indent + "<wfs:TransactionResult");
if (result.getHandle() != null) {
writer.write(" handle=\"" + result.getHandle() + "\"");
}
writer.write(">");
writer.write(indent + offset + "<wfs:Status>");
writer.write(indent + offset + offset);
//if there is an actino, that means we failed
if (!result.getAction().isEmpty()) {
writer.write("<wfs:FAILED/>");
} else {
writer.write("<wfs:SUCCESS/>");
}
writer.write(indent + offset + "</wfs:Status>");
if (!result.getAction().isEmpty()) {
ActionType action = (ActionType) result.getAction().get(0);
if (action.getLocator() != null) {
writer.write(indent + offset + "<wfs:Locator>");
writer.write(action.getLocator() + "</wfs:Locator>");
}
if (action.getMessage() != null) {
writer.write(indent + offset + "<wfs:Message>");
ResponseUtils.writeEscapedString(writer, action.getMessage());
writer.write("</wfs:Message>");
}
}
writer.write(indent + "</wfs:TransactionResult>");
if (verbose) {
writer.write("\n");
}
writer.write("</wfs:WFS_TransactionResponse>");
writer.flush();
}
public void v_1_1(TransactionResponseType response, OutputStream output, Operation operation)
throws IOException, ServiceException {
if (!response.getTransactionResults().getAction().isEmpty()) {
//since we do atomic transactions, an action failure means all we rolled back
// spec says to throw exception
ActionType action = (ActionType) response.getTransactionResults().getAction().iterator()
.next();
throw new WFSException(action.getMessage(), action.getCode(), action.getLocator());
}
Encoder encoder = new Encoder(configuration, configuration.schema());
encoder.setEncoding(Charset.forName( getInfo().getGeoServer().getGlobal().getCharset()) );
TransactionType req = (TransactionType)operation.getParameters()[0];
encoder.setSchemaLocation(org.geoserver.wfs.xml.v1_1_0.WFS.NAMESPACE,
buildSchemaURL(req.getBaseUrl(), "wfs/1.1.0/wfs.xsd"));
encoder.encode(response, org.geoserver.wfs.xml.v1_1_0.WFS.TRANSACTIONRESPONSE, output);
}
}