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;
006:
007: import net.opengis.wfs.FeatureCollectionType;
008: import net.opengis.wfs.GetFeatureType;
009: import net.opengis.wfs.ResultTypeType;
010: import org.geoserver.ows.Response;
011: import org.geoserver.ows.util.OwsUtils;
012: import org.geoserver.platform.Operation;
013: import org.geoserver.platform.ServiceException;
014: import java.io.IOException;
015: import java.io.OutputStream;
016: import java.util.Set;
017: import java.util.logging.Logger;
018:
019: /**
020: * Base class for a response to a WFS GetFeature operation.
021: * <p>
022: * The result of a GetFeature operation is an instance of
023: * {@link FeatureCollectionType}. Subclasses are responsible for serializing
024: * an instance of this type in {@link #write(FeatureCollectionType, OutputStream, Operation)}.
025: * </p>
026: * <p>
027: * Subclasses also need declare the mime-type in which the format is encoded.
028: * </p>
029: *
030: * @author Gabriel Rold?n, Axios Engineering
031: * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
032: *
033: */
034: public abstract class WFSGetFeatureOutputFormat extends Response {
035:
036: /**
037: * logger
038: */
039: protected static Logger LOGGER = org.geotools.util.logging.Logging
040: .getLogger("org.geoserver.wfs");
041:
042: /**
043: * Constructor which sets the outputFormat.
044: *
045: * @param outputFormat The well-known name of the format, not <code>null</code>
046: */
047: public WFSGetFeatureOutputFormat(String outputFormat) {
048: super (FeatureCollectionType.class, outputFormat);
049: }
050:
051: /**
052: * Constructor which sets the outputFormats.
053: *
054: * @param outputFormats Set of well-known name of the format, not <code>null</code>
055: */
056: public WFSGetFeatureOutputFormat(Set outputFormats) {
057: super (FeatureCollectionType.class, outputFormats);
058: }
059:
060: /**
061: * Returns the mime type <code>text/xml</code>.
062: * <p>
063: * Subclasses should override this method to provide a diffent output
064: * format.
065: * </p>
066: */
067: public String getMimeType(Object value, Operation operation)
068: throws ServiceException {
069: return "text/xml";
070: }
071:
072: /**
073: * Ensures that the operation being executed is a GetFeature operation.
074: * <p>
075: * Subclasses may implement
076: * </p>
077: */
078: public boolean canHandle(Operation operation) {
079: //GetFeature operation?
080: if ("GetFeature".equalsIgnoreCase(operation.getId())
081: || "GetFeatureWithLock".equalsIgnoreCase(operation
082: .getId())) {
083: //also check that the resultType is "results"
084: GetFeatureType request = (GetFeatureType) OwsUtils
085: .parameter(operation.getParameters(),
086: GetFeatureType.class);
087:
088: if (request.getResultType() == ResultTypeType.RESULTS_LITERAL) {
089: //call subclass hook
090: return canHandleInternal(operation);
091: }
092: }
093:
094: return false;
095: }
096:
097: /**
098: * capabilities output format string. Something that's a valid XML element name.
099: * This should be overriden in each outputformat subclass, and if it's not a warning will be
100: * issued.
101: */
102: public/*abstract*/String getCapabilitiesElementName() {
103: LOGGER
104: .severe("ERROR IN "
105: + this .getClass()
106: + " IMPLEMENTATION. getCapabilitiesElementName() should return a"
107: + "valid XML element name string for use in the WFS 1.0.0 capabilities document.");
108: String of = getOutputFormat();
109:
110: //wfs 1.1 form is not a valid xml element, do a check
111: if (of.matches("(\\w)+")) {
112: return getOutputFormat();
113: } else {
114: String name = this .getClass().getName();
115: if (name.indexOf('.') != -1) {
116: name = name.substring(name.lastIndexOf('.') + 1);
117: }
118:
119: return name;
120: }
121: }
122:
123: /**
124: * Hook for subclasses to add addtional checks to {@link #canHandle(Operation)}.
125: * <p>
126: * Subclasses may override this method if need be, the default impelementation
127: * returns <code>true</code>
128: * </p>
129: * @param operation The operation being performed.
130: *
131: * @return <code>true</code> if the output format can handle the operation,
132: * otherwise <code>false</code>
133: */
134: protected boolean canHandleInternal(Operation operation) {
135: return true;
136: }
137:
138: /**
139: * Calls through to {@link #write(FeatureCollectionType, OutputStream, Operation)}.
140: */
141: public final void write(Object value, OutputStream output,
142: Operation operation) throws IOException, ServiceException {
143: write((FeatureCollectionType) value, output, operation);
144: }
145:
146: /**
147: * Serializes the feature collection in the format declared.
148: *
149: * @param featureCollection The feature collection.
150: * @param output The output stream to serialize to.
151: * @param getFeature The GetFeature operation descriptor.
152: */
153: protected abstract void write(
154: FeatureCollectionType featureCollection,
155: OutputStream output, Operation getFeature)
156: throws IOException, ServiceException;
157: }
|