001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/portal/standard/sos/control/DescribeSensorListener.java $
002    /*----------------------------------------------------------------------------
003     This file is part of deegree, http://deegree.org/
004     Copyright (C) 2001-2009 by:
005       Department of Geography, University of Bonn
006     and
007       lat/lon GmbH
008    
009     This library is free software; you can redistribute it and/or modify it under
010     the terms of the GNU Lesser General Public License as published by the Free
011     Software Foundation; either version 2.1 of the License, or (at your option)
012     any later version.
013     This library is distributed in the hope that it will be useful, but WITHOUT
014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016     details.
017     You should have received a copy of the GNU Lesser General Public License
018     along with this library; if not, write to the Free Software Foundation, Inc.,
019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020    
021     Contact information:
022    
023     lat/lon GmbH
024     Aennchenstr. 19, 53177 Bonn
025     Germany
026     http://lat-lon.de/
027    
028     Department of Geography, University of Bonn
029     Prof. Dr. Klaus Greve
030     Postfach 1147, 53001 Bonn
031     Germany
032     http://www.geographie.uni-bonn.de/deegree/
033    
034     e-mail: info@deegree.org
035    ----------------------------------------------------------------------------*/
036    package org.deegree.portal.standard.sos.control;
037    
038    import java.util.HashMap;
039    import java.util.Iterator;
040    
041    import org.deegree.enterprise.control.RPCMethodCall;
042    import org.deegree.enterprise.control.RPCParameter;
043    import org.deegree.enterprise.control.RPCStruct;
044    import org.deegree.framework.log.ILogger;
045    import org.deegree.framework.log.LoggerFactory;
046    import org.deegree.framework.xml.ElementList;
047    import org.deegree.framework.xml.NamespaceContext;
048    import org.deegree.framework.xml.XMLTools;
049    import org.deegree.ogcbase.CommonNamespaces;
050    import org.deegree.ogcwebservices.sos.describesensor.SensorMetadata;
051    import org.deegree.ogcwebservices.sos.sensorml.Classifier;
052    import org.deegree.ogcwebservices.sos.sensorml.ComponentDescription;
053    import org.deegree.ogcwebservices.sos.sensorml.Discussion;
054    import org.deegree.ogcwebservices.sos.sensorml.EngineeringCRS;
055    import org.deegree.ogcwebservices.sos.sensorml.GeoPositionModel;
056    import org.deegree.ogcwebservices.sos.sensorml.GeographicCRS;
057    import org.deegree.ogcwebservices.sos.sensorml.Identifier;
058    import org.deegree.ogcwebservices.sos.sensorml.LocationModel;
059    import org.deegree.ogcwebservices.sos.sensorml.Phenomenon;
060    import org.deegree.ogcwebservices.sos.sensorml.Product;
061    import org.deegree.ogcwebservices.sos.sensorml.ResponseModel;
062    import org.deegree.portal.standard.sos.Constants;
063    import org.deegree.portal.standard.sos.SOSClientException;
064    import org.w3c.dom.Document;
065    import org.w3c.dom.Element;
066    
067    /**
068     * Listener for performing DescribeSensor requests against Sensor Observation Services.
069     *
070     * @author <a href="mailto:che@wupperverband.de.de">Christian Heier</a>
071     * @version 1.0
072     */
073    public class DescribeSensorListener extends AbstractSOSListener {
074    
075        private static final NamespaceContext nsContext = CommonNamespaces.getNamespaceContext();
076    
077        private static final ILogger LOG = LoggerFactory.getLogger( DescribeSensorListener.class );
078    
079        /**
080         * validates the request to be performed.
081         *
082         * @param mc
083         *            RPCMethodCall containing the request to be performed
084         * @throws SOSClientException
085         *             if request is not valid
086         */
087        @Override
088        protected void validateRequest( RPCMethodCall mc )
089                                throws SOSClientException {
090            RPCParameter[] params = mc.getParameters();
091            if ( params == null || params.length != 1 ) {
092                throw new SOSClientException( "one rpc parameter containing a struct "
093                                              + "with requiered parameters must be set" );
094            }
095            RPCStruct struct = (RPCStruct) params[0].getValue();
096            if ( struct.getMember( Constants.TYPENAME ) == null || "".equals( Constants.TYPENAME ) ) {
097                throw new SOSClientException( "TypeName parameter must be set "
098                                              + "to perform a Sensor Observation Service "
099                                              + "DescribeSensor request" );
100            }
101    
102        }
103    
104        /**
105         * creates a SOS DescribeSensor request from the parameters contained in the passed
106         * <tt>RPCMethodeCall</tt>.
107         *
108         * @param mc
109         *            the RPCMethodCall
110         * @return SOS DescribeSensor request as String
111         * @throws SOSClientException
112         */
113        @Override
114        protected String createRequest( RPCMethodCall mc )
115                                throws SOSClientException {
116    
117            RPCParameter[] params = mc.getParameters();
118            RPCStruct struct = (RPCStruct) params[0].getValue();
119    
120            StringBuffer sb = new StringBuffer( 1000 );
121            sb.append( "<sos:DescribeSensor " );
122            sb.append( "xmlns:sos='http://www.opengis.net/sos' " );
123            sb.append( "outputFormat='SensorML' " );
124            sb.append( "service='SOS' " );
125            sb.append( "version='0.8.0'>" );
126            sb.append( "<sos:TypeName>" );
127            sb.append( struct.getMember( Constants.TYPENAME ).getValue() );
128            sb.append( "</sos:TypeName>" );
129            sb.append( "</sos:DescribeSensor>" );
130            return sb.toString();
131        }
132    
133        /**
134         * creates the result object to send to the next page from the parameters contained in the
135         * passed <tt>RPCMethodeCall</tt> and the <tt>Document</tt> array.
136         *
137         * @param mc
138         *            the RPCMethodCall
139         * @param map
140         *            the Document array
141         * @return the result object
142         * @throws SOSClientException
143         */
144        @Override
145        protected Object createData( RPCMethodCall mc, HashMap<String, Document> map )
146                                throws SOSClientException {
147    
148            Identifier[] identifiedAs = null;
149            Classifier[] classifiedAs = null;
150            EngineeringCRS hasCRS = null;
151            LocationModel[] locatedUsing = null;
152            ComponentDescription describedBy = null;
153            String attachedTo = null;
154            Product[] measures = null;
155    
156            SensorMetadata[] sensorDescriptions = new SensorMetadata[map.size()];
157    
158            int i = 0;
159            try {
160                Iterator<String> iterator = map.keySet().iterator();
161                while ( iterator.hasNext() ) {
162    
163                    String key = iterator.next();
164                    Element e = map.get( key ).getDocumentElement();
165    
166                    String[] ids = XMLTools.getNodesAsStrings(
167                                                               e,
168                                                               "/sml:Sensors/sml:Sensor/sml:identifiedAs/sml:Identifier",
169                                                               nsContext );
170    
171                    identifiedAs = new Identifier[ids.length];
172                    for ( int j = 0; j < ids.length; j++ ) {
173                        identifiedAs[j] = new Identifier( ids[j] );
174                    }
175    
176                    String srcSRS = XMLTools.getNodeAsString(
177                                                              e,
178                                                              "/sml:Sensors/sml:Sensor/sml:locatedUsing/sml:GeoPositionModel/sml:sourceCRS/gml:EngineeringCRS/gml:srsName",
179                                                              nsContext, null );
180    
181                    String refSRS = XMLTools.getNodeAsString(
182                                                              e,
183                                                              "/sml:Sensors/sml:Sensor/sml:locatedUsing/sml:GeoPositionModel/sml:sourceCRS/gml:GeographicCRS/gml:srsName",
184                                                              nsContext, null );
185    
186                    locatedUsing = new LocationModel[1];
187                    locatedUsing[0] = new GeoPositionModel( null, null, null, null,
188                                                            new EngineeringCRS( srcSRS ),
189                                                            new GeographicCRS( refSRS ), new Object[0] );
190    
191                    // TODO What about the coordinates?? (sml:GeoLocation)
192    
193                    // TODO ComponentDescription describedBy
194    
195                    attachedTo = XMLTools.getNodeAsString( e, "/sml:Sensors/sml:Sensor/sml:attachedTo",
196                                                           nsContext, null );
197    
198                    // preparing the values for the product[]
199                    Identifier[] productIdentifiedAs = null;
200                    Classifier[] productClassifiedAs = null;
201                    Discussion[] productDescription = null;
202                    LocationModel[] productLocatedUsing = null;
203                    EngineeringCRS productHasCRS = null;
204                    Phenomenon productObservable = null;
205                    ResponseModel[] productDerivedFrom = null;
206                    String productId = null;
207    
208                    ElementList productList = XMLTools.getChildElements( "Product",
209                                                                         CommonNamespaces.SMLNS, e );
210    
211                    measures = new Product[productList.getLength()];
212    
213                    for ( int l = 0; l < productList.getLength(); l++ ) {
214    
215                        String[] prodIds = XMLTools.getNodesAsStrings(
216                                                                       e,
217                                                                       "/sml:Sensors/sml:Sensor/sml:measures/sml:Product/sml:identifiedAs/sml:Identifier",
218                                                                       nsContext );
219    
220                        productIdentifiedAs = new Identifier[prodIds.length];
221                        for ( int k = 0; k < ids.length; k++ ) {
222                            productIdentifiedAs[k] = new Identifier( prodIds[k] );
223                        }
224    
225                        // TODO productClassifiedAs
226    
227                        // TODO productDescription
228    
229                        // TODO productLocatedUsing
230    
231                        // TODO productHasCRS
232    
233                        // TODO productDerivedFrom
234    
235                        // TODO productId
236    
237                        String observableName = XMLTools.getNodeAsString(
238                                                                          e,
239                                                                          "/sml:Sensors/sml:Sensor/sml:measures/sml:Product/sml:observable/sml:Phenomenon/sml:name",
240                                                                          nsContext, null );
241    
242                        // TODO observableDescription
243    
244                        // TODO observableId
245    
246                        productObservable = new Phenomenon( observableName, null, null );
247    
248                        measures[l] = new Product( productIdentifiedAs, productClassifiedAs,
249                                                   productDescription, productLocatedUsing,
250                                                   productDerivedFrom, productHasCRS,
251                                                   productObservable, productId );
252    
253                    }
254    
255                    sensorDescriptions[i] = new SensorMetadata( identifiedAs, classifiedAs, hasCRS,
256                                                                locatedUsing, describedBy, attachedTo,
257                                                                measures );
258                    i++;
259                }
260    
261            } catch ( Exception e ) {
262                LOG.logError( "Error creating sensor descriptions: " + e.getMessage() );
263                throw new SOSClientException( "Couldn't create sensor descriptions", e );
264            }
265            return sensorDescriptions;
266        }
267    
268        @Override
269        protected void setNextPageData( Object o ) {
270            this.getRequest().setAttribute( Constants.SENSORDESCRIPTION, o );
271        }
272    
273    }