001: /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
002: * This code is licensed under the GPL 2.0 license, availible at the root
003: * application directory.
004: */
005: package org.geoserver.wfs.response;
006:
007: import net.opengis.wfs.ActionType;
008: import net.opengis.wfs.GetFeatureType;
009: import net.opengis.wfs.InsertResultsType;
010: import net.opengis.wfs.InsertedFeatureType;
011: import net.opengis.wfs.TransactionResponseType;
012: import net.opengis.wfs.TransactionResultsType;
013: import net.opengis.wfs.TransactionType;
014:
015: import org.geoserver.ows.Response;
016: import org.geoserver.ows.util.RequestUtils;
017: import org.geoserver.ows.util.ResponseUtils;
018: import org.geoserver.platform.Operation;
019: import org.geoserver.platform.ServiceException;
020: import org.geoserver.wfs.WFS;
021: import org.geoserver.wfs.WFSException;
022: import org.geoserver.wfs.xml.v1_1_0.WFSConfiguration;
023: import org.geotools.util.Version;
024: import org.geotools.xml.Encoder;
025: import org.opengis.filter.identity.FeatureId;
026: import org.vfny.geoserver.global.Data;
027: import org.xml.sax.SAXException;
028: import java.io.BufferedWriter;
029: import java.io.IOException;
030: import java.io.OutputStream;
031: import java.io.OutputStreamWriter;
032: import java.io.Writer;
033: import java.util.Iterator;
034:
035: public class TransactionResponse extends Response {
036: private boolean verbose = false;
037: private String indent = " ";
038: private String offset = "";
039: WFS wfs;
040: Data catalog;
041: WFSConfiguration configuration;
042:
043: public TransactionResponse(WFS wfs, Data catalog,
044: WFSConfiguration configuration) {
045: super (TransactionResponseType.class);
046: this .wfs = wfs;
047: this .catalog = catalog;
048: this .configuration = configuration;
049: }
050:
051: public String getMimeType(Object value, Operation operation)
052: throws ServiceException {
053: return "text/xml";
054: }
055:
056: public void write(Object value, OutputStream output,
057: Operation operation) throws IOException, ServiceException {
058: TransactionResponseType response = (TransactionResponseType) value;
059:
060: if (new Version("1.0.0").equals(operation.getService()
061: .getVersion())) {
062: v_1_0(response, output, operation);
063: } else {
064: v_1_1(response, output, operation);
065: }
066: }
067:
068: public void v_1_0(TransactionResponseType response,
069: OutputStream output, Operation operation)
070: throws IOException, ServiceException {
071: TransactionResultsType result = response
072: .getTransactionResults();
073:
074: Writer writer = new OutputStreamWriter(output);
075: writer = new BufferedWriter(writer);
076:
077: //boolean verbose = ConfigInfo.getInstance().formatOutput();
078: //String indent = ((verbose) ? "\n" + OFFSET : " ");
079: String encoding = wfs.getCharSet().name();
080: String xmlHeader = "<?xml version=\"1.0\" encoding=\""
081: + encoding + "\"?>";
082: writer.write(xmlHeader);
083:
084: if (verbose) {
085: writer.write("\n");
086: }
087:
088: writer.write("<wfs:WFS_TransactionResponse");
089: writer.write(indent + "version=\"1.0.0\"");
090: writer.write(indent
091: + "xmlns:wfs=\"http://www.opengis.net/wfs\"");
092:
093: writer.write(indent
094: + "xmlns:ogc=\"http://www.opengis.net/ogc\"");
095:
096: writer
097: .write(indent
098: + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
099: writer.write(indent);
100: writer
101: .write("xsi:schemaLocation=\"http://www.opengis.net/wfs ");
102:
103: TransactionType req = (TransactionType) operation
104: .getParameters()[0];
105: String proxifiedBaseUrl = RequestUtils.proxifiedBaseURL(req
106: .getBaseUrl(), wfs.getGeoServer().getProxyBaseUrl());
107:
108: String baseUrl = ResponseUtils.appendPath(proxifiedBaseUrl,
109: "schemas/wfs/1.0.0/WFS-transaction.xsd");
110:
111: writer.write(baseUrl);
112: writer.write("\">");
113:
114: InsertResultsType insertResults = response.getInsertResults();
115:
116: //JD: make sure we group insert results by handle, this is wfs 1.0 cite
117: // thing that conflicts with wfs 1.1 cite, i am pretty sure its just a
118: // problem with the 1.0 tests
119: String lastHandle = null;
120: boolean first = true;
121:
122: if (insertResults != null) {
123: for (Iterator i = insertResults.getFeature().iterator(); i
124: .hasNext();) {
125: InsertedFeatureType insertedFeature = (InsertedFeatureType) i
126: .next();
127: String handle = insertedFeature.getHandle();
128:
129: if (first
130: || ((lastHandle == null) && (handle != null))
131: || ((lastHandle != null) && (handle != null) && handle
132: .equals(lastHandle))) {
133: if (!first) {
134: //close last one, if not the first time through
135: writer.write("</wfs:InsertResult>");
136: }
137:
138: writer.write("<wfs:InsertResult");
139:
140: if (insertedFeature.getHandle() != null) {
141: writer.write(" handle=\""
142: + insertedFeature.getHandle() + "\"");
143: }
144:
145: writer.write(">");
146: }
147:
148: for (Iterator id = insertedFeature.getFeatureId()
149: .iterator(); id.hasNext();) {
150: FeatureId featureId = (FeatureId) id.next();
151: writer.write("<ogc:FeatureId fid=\""
152: + featureId.toString() + "\"/>");
153: }
154:
155: first = false;
156: lastHandle = handle;
157: }
158:
159: writer.write("</wfs:InsertResult>");
160: }
161:
162: writer.write(indent + "<wfs:TransactionResult");
163:
164: if (result.getHandle() != null) {
165: writer.write(" handle=\"" + result.getHandle() + "\"");
166: }
167:
168: writer.write(">");
169: writer.write(indent + offset + "<wfs:Status>");
170: writer.write(indent + offset + offset);
171:
172: //if there is an actino, that means we failed
173: if (!result.getAction().isEmpty()) {
174: writer.write("<wfs:FAILED/>");
175: } else {
176: writer.write("<wfs:SUCCESS/>");
177: }
178:
179: writer.write(indent + offset + "</wfs:Status>");
180:
181: if (!result.getAction().isEmpty()) {
182: ActionType action = (ActionType) result.getAction().get(0);
183:
184: if (action.getLocator() != null) {
185: writer.write(indent + offset + "<wfs:Locator>");
186: writer.write(action.getLocator() + "</wfs:Locator>");
187: }
188:
189: if (action.getMessage() != null) {
190: writer.write(indent + offset + "<wfs:Message>");
191: ResponseUtils.writeEscapedString(writer, action
192: .getMessage());
193: writer.write("</wfs:Message>");
194: }
195: }
196:
197: writer.write(indent + "</wfs:TransactionResult>");
198:
199: if (verbose) {
200: writer.write("\n");
201: }
202:
203: writer.write("</wfs:WFS_TransactionResponse>");
204: writer.flush();
205: }
206:
207: public void v_1_1(TransactionResponseType response,
208: OutputStream output, Operation operation)
209: throws IOException, ServiceException {
210: if (!response.getTransactionResults().getAction().isEmpty()) {
211: //since we do atomic transactions, an action failure means all we rolled back
212: // spec says to throw exception
213: ActionType action = (ActionType) response
214: .getTransactionResults().getAction().iterator()
215: .next();
216: throw new WFSException(action.getMessage(), action
217: .getCode(), action.getLocator());
218: }
219:
220: Encoder encoder = new Encoder(configuration, configuration
221: .schema());
222:
223: TransactionType req = (TransactionType) operation
224: .getParameters()[0];
225: String proxifiedBaseUrl = RequestUtils.proxifiedBaseURL(req
226: .getBaseUrl(), wfs.getGeoServer().getProxyBaseUrl());
227:
228: encoder.setSchemaLocation(
229: org.geoserver.wfs.xml.v1_1_0.WFS.NAMESPACE,
230: ResponseUtils.appendPath(proxifiedBaseUrl,
231: "schemas/wfs/1.1.0/wfs.xsd"));
232:
233: try {
234: encoder
235: .encode(
236: response,
237: org.geoserver.wfs.xml.v1_1_0.WFS.TRANSACTIONRESPONSE,
238: output);
239: } catch (SAXException e) {
240: //SAXException does not sets initCause(). Instead, it holds its own "exception" field.
241: if (e.getException() != null && e.getCause() == null) {
242: e.initCause(e.getException());
243: }
244: throw (IOException) new IOException().initCause(e);
245: }
246: }
247: }
|