001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/portal/standard/csw/control/AddToShoppingCartListener.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    
037    package org.deegree.portal.standard.csw.control;
038    
039    import java.util.ArrayList;
040    import java.util.HashMap;
041    import java.util.Iterator;
042    import java.util.List;
043    import java.util.Map;
044    
045    import javax.servlet.http.HttpServletRequest;
046    import javax.servlet.http.HttpSession;
047    
048    import org.deegree.enterprise.control.FormEvent;
049    import org.deegree.enterprise.control.RPCException;
050    import org.deegree.enterprise.control.RPCParameter;
051    import org.deegree.enterprise.control.RPCStruct;
052    import org.deegree.enterprise.control.RPCWebEvent;
053    import org.deegree.framework.log.ILogger;
054    import org.deegree.framework.log.LoggerFactory;
055    import org.deegree.i18n.Messages;
056    import org.deegree.ogcbase.CommonNamespaces;
057    import org.deegree.portal.standard.csw.CatalogClientException;
058    import org.deegree.portal.standard.csw.configuration.CSWClientConfiguration;
059    import org.deegree.portal.standard.csw.model.DataSessionRecord;
060    import org.deegree.portal.standard.csw.model.ServiceSessionRecord;
061    import org.deegree.portal.standard.csw.model.ShoppingCart;
062    import org.w3c.dom.Document;
063    import org.w3c.dom.Element;
064    import org.w3c.dom.Node;
065    
066    /**
067     * A <code>${type_name}</code> class.<br/> TODO class description
068     *
069     * @author <a href="mailto:mays@lat-lon.de">Judit Mays</a>
070     * @author last edited by: $Author: mschneider $
071     *
072     * @version 2.0, $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
073     *
074     * @since 2.0
075     * @deprecated Shopping cart will not be supported at the moment. update: new changes in deegree1_fork will not be
076     *             carried here, since this class is still not used. Remove when this status changes
077     */
078    @Deprecated
079    public class AddToShoppingCartListener extends SimpleSearchListener {
080    
081        private static final ILogger LOG = LoggerFactory.getLogger( AddToShoppingCartListener.class );
082    
083        static final String RPC_TITLE = "RPC_TITLE";
084    
085        /*
086         * (non-Javadoc)
087         *
088         * @see org.deegree.enterprise.control.WebListener#actionPerformed(org.deegree.enterprise.control.FormEvent)
089         */
090        @Override
091        public void actionPerformed( FormEvent event ) {
092    
093            RPCWebEvent rpcEvent = (RPCWebEvent) event;
094            HttpSession session = ( (HttpServletRequest) this.getRequest() ).getSession( true );
095            config = (CSWClientConfiguration) session.getAttribute( Constants.CSW_CLIENT_CONFIGURATION );
096    
097            nsContext = CommonNamespaces.getNamespaceContext();
098    
099            try {
100                validateRequest( rpcEvent );
101            } catch ( Exception e ) {
102                gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_INVALID_RPC_EVENT", e.getMessage() ) );
103                LOG.logError( e.getMessage(), e );
104                return;
105            }
106    
107            String dataId = null;
108            String dataCatalog = null;
109            String dataTitle = null;
110            try {
111                RPCStruct struct = extractRPCStruct( rpcEvent, 0 );
112                dataId = (String) extractRPCMember( struct, Constants.RPC_IDENTIFIER );
113                dataCatalog = (String) extractRPCMember( struct, RPC_CATALOG );
114                dataTitle = (String) extractRPCMember( struct, RPC_TITLE );
115            } catch ( Exception e ) {
116                gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_INVALID_RPC_EVENT", e.getMessage() ) );
117                LOG.logError( e.getMessage(), e );
118                return;
119            }
120    
121            String serviceReq = null;
122            try {
123                serviceReq = createServiceRequest( dataTitle );
124            } catch ( Exception e ) {
125                gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_INVALID_SERVICE_REQ", e.getMessage() ) );
126                LOG.logError( e.getMessage(), e );
127                return;
128            }
129    
130            HashMap serviceResult = null;
131            try {
132                serviceResult = performServiceRequest( dataTitle, serviceReq );
133            } catch ( Exception e ) {
134                gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_SERVER_ERROR", e.getMessage() ) );
135                LOG.logError( e.getMessage(), e );
136                return;
137            }
138    
139            // create ssr's ...
140            ServiceSessionRecord[] ssrArray = null;
141            try {
142                ssrArray = createServiceSessionRecords( serviceResult );
143            } catch ( CatalogClientException e ) {
144                gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_FAIL_CREATE_SSR", e.getMessage() ) );
145                LOG.logError( e.getMessage(), e );
146                return;
147            }
148    
149            // ... add the ssr's to the corresponding dsr in the session ...
150            List dsrList = (ArrayList) session.getAttribute( SESSION_DATARECORDS );
151            dsrList = addServiceSessionRecords( dsrList, dataId, dataCatalog, dataTitle, ssrArray );
152            session.setAttribute( SESSION_DATARECORDS, dsrList );
153    
154            // ... and add this dsr to the shopping cart.
155            ShoppingCart cart = (ShoppingCart) session.getAttribute( Constants.SESSION_SHOPPINGCART );
156            if ( cart == null ) {
157                cart = new ShoppingCart();
158            }
159            DataSessionRecord dsr = getDataSessionRecordFromList( dsrList, dataId, dataCatalog, dataTitle );
160            cart.add( dsr );
161            session.setAttribute( Constants.SESSION_SHOPPINGCART, cart );
162    
163            getRequest().setAttribute( Constants.MESSAGE, Messages.getMessage( "IGEO_STD_CSW_SUCCESS_ADD_DATASET" ) );
164    
165        }
166    
167        /*
168         * (non-Javadoc)
169         *
170         * @see org.deegree.portal.standard.csw.control.SimpleSearchListener#validateRequest(org.deegree.enterprise.control.RPCWebEvent)
171         */
172        @Override
173        protected void validateRequest( RPCWebEvent rpcEvent )
174                                throws CatalogClientException {
175    
176            RPCParameter[] params = extractRPCParameters( rpcEvent );
177            if ( params.length != 1 ) {
178                throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_WRONG_PARAMS_NUMBER", "1",
179                                                                       params.length ) );
180    
181            }
182    
183            RPCStruct struct = extractRPCStruct( rpcEvent, 0 );
184            Object member = extractRPCMember( struct, RPC_CATALOG );
185            if ( member == null ) {
186                throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_MISSING_PARAM", RPC_CATALOG ) );
187            }
188            member = extractRPCMember( struct, Constants.RPC_IDENTIFIER );
189            if ( member == null ) {
190                throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_MISSING_PARAM",
191                                                                       Constants.RPC_IDENTIFIER ) );
192            }
193            member = extractRPCMember( struct, RPC_TITLE );
194            if ( member == null ) {
195                throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_MISSING_PARAM", RPC_TITLE ) );
196            }
197        }
198    
199        /**
200         * This method creates a csw:GetRecords request for RESULTS for service metadata, using the paramter values
201         * contained in the struct of the passed rpcEvent.
202         *
203         * @param title
204         * @return Returns the xml encoded request as <code>String</code>.
205         * @throws CatalogClientException
206         * @throws RPCException
207         */
208        private String createServiceRequest( String title )
209                                throws CatalogClientException, RPCException {
210            String format = "ISO19119"; // TODO make usable for other formats, not only "ISO19119"
211            String template = "CSWServiceSearchRPCMethodCallTemplate.xml";
212            RPCStruct serviceStruct = createRpcStructForServiceSearch( template, title );
213    
214            return createRequest( serviceStruct, format, "RESULTS" );
215        }
216    
217        /**
218         * Performs the given service request and returns its result
219         *
220         * @param title
221         * @param serviceReq
222         * @return Returns a <code>HashMap</code>, which contains one key-value-pair for each service catalogue, that has
223         *         been searched. The key is the name of the service catalogue. The value is the xml Document, that contains
224         *         1 to n service metadata entries.
225         * @throws CatalogClientException
226         */
227        private HashMap performServiceRequest( String title, String serviceReq )
228                                throws CatalogClientException {
229    
230            HttpSession session = ( (HttpServletRequest) this.getRequest() ).getSession( true );
231            Map availableServiceCatalogs = (HashMap) session.getAttribute( SESSION_AVAILABLESERVICECATALOGS );
232            List serviceCatalogs = extractAvailableServiceCatalogs( availableServiceCatalogs, title );
233    
234            return performRequest( null, serviceReq, serviceCatalogs );
235        }
236    
237        /**
238         * This method creates a ServiceSessionRecord for each service metadata element in the passed serviceResults and
239         * returns them as Array.
240         *
241         * @param serviceResults
242         *            Map containing service metadata catalogs as keys and metadata-Documents as values.
243         * @return Returns an Array of ServiceSessionRecords.
244         * @throws CatalogClientException
245         */
246        private ServiceSessionRecord[] createServiceSessionRecords( HashMap serviceResults )
247                                throws CatalogClientException {
248    
249            List<ServiceSessionRecord> ssrList = new ArrayList<ServiceSessionRecord>( 10 );
250    
251            Iterator it = serviceResults.keySet().iterator();
252            while ( it.hasNext() ) {
253                // one loop for every available service metadata catalog
254                String catalog = (String) it.next();
255                Document doc = (Document) serviceResults.get( catalog );
256    
257                List mdList;
258                try {
259                    mdList = extractMetadata( doc );
260                } catch ( Exception e ) {
261                    throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_ERROR_EXTRACT_METADATA",
262                                                                           e.getMessage() ) );
263                }
264    
265                for ( int j = 0; j < mdList.size(); j++ ) {
266                    // one loop for every service metadata element for the current catalog
267                    Node mdNode = (Node) mdList.get( j );
268                    if ( !"service".equals( getMetadataType( (Element) mdNode ) ) ) {
269                        // Ignore the node if it is a data metadata type(i.e. dataset or dataseries)
270                        // Or use it if its a service metadata
271                        // TODO handle service metadata properly, also in iGeoPortal xslts
272                        continue;
273                    }
274                    String id = null;
275                    String title = null;
276                    String address = null;
277                    String serviceType = null;
278                    String serviceTypeVersion = null;
279    
280                    try {
281                        id = extractValue( mdNode, config.getXPathToServiceIdentifier() );
282                        title = extractValue( mdNode, config.getXPathToServiceTitle() );
283                        address = extractValue( mdNode, config.getXPathToServiceAddress() );
284                        serviceType = extractValue( mdNode, config.getXPathToServiceType() );
285                        serviceTypeVersion = extractValue( mdNode, config.getXPathToServiceTypeVersion() );
286                    } catch ( Exception e ) {
287                        throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_ERROR_EXTRACT_VAL",
288                                                                               e.getMessage() ) );
289                    }
290    
291                    ServiceSessionRecord ssr = new ServiceSessionRecord( id, catalog, title, address, serviceType,
292                                                                         serviceTypeVersion );
293                    ssrList.add( ssr );
294                }
295            }
296    
297            ServiceSessionRecord[] serviceSessionRecords = ssrList.toArray( new ServiceSessionRecord[ssrList.size()] );
298    
299            return serviceSessionRecords;
300        }
301    
302        /**
303         * This method searches the passed List of DataSessionRecords for the dataSessionRecord that corresponds to the
304         * passed data parameters and adds to it the passed serviceSessionRecords. It returns the List with one
305         * DataSessionRecord changed.
306         *
307         * @param dataSessionRecList
308         *            The List containing the DataSessionRecord to which to add the passed ServiceSessionRecords.
309         * @param dataId
310         *            One of three parameters to identify the DataSessionRecord.
311         * @param dataCatalog
312         *            One of three parameters to identify the DataSessionRecord.
313         * @param dataTitle
314         *            One of three parameters to identify the DataSessionRecord.
315         * @param serviceSessionRecs
316         *            The ServiceSessionRecords to add to the DataSessionRecord.
317         * @return Returns the changed dataSessionRecList.
318         */
319        private List addServiceSessionRecords( List dataSessionRecList, String dataId, String dataCatalog,
320                                               String dataTitle, ServiceSessionRecord[] serviceSessionRecs ) {
321    
322            for ( int i = 0; i < dataSessionRecList.size(); i++ ) {
323    
324                DataSessionRecord dsr = (DataSessionRecord) dataSessionRecList.get( i );
325    
326                if ( dataId.equals( dsr.getIdentifier() ) && dataCatalog.equals( dsr.getCatalogName() )
327                     && dataTitle.equals( dsr.getTitle() ) ) {
328    
329                    ( (DataSessionRecord) dataSessionRecList.get( i ) ).setServices( serviceSessionRecs );
330                }
331            }
332    
333            return dataSessionRecList;
334        }
335    
336        /**
337         * @param dataSessionRecList
338         *            The List containing the DataSessionRecord to return.
339         * @param dataId
340         *            One of three parameters to identify the DataSessionRecord.
341         * @param dataCatalog
342         *            One of three parameters to identify the DataSessionRecord.
343         * @param dataTitle
344         *            One of three parameters to identify the DataSessionRecord.
345         * @return Returns the DataSessionRecord from the passed List, that matches the passed data parameters OR null, if
346         *         no match was found in the passed List.
347         */
348        protected DataSessionRecord getDataSessionRecordFromList( List dataSessionRecList, String dataId,
349                                                                  String dataCatalog, String dataTitle ) {
350    
351            for ( int i = 0; i < dataSessionRecList.size(); i++ ) {
352    
353                DataSessionRecord dsr = (DataSessionRecord) dataSessionRecList.get( i );
354                if ( dataId.equals( dsr.getIdentifier() ) && dataCatalog.equals( dsr.getCatalogName() )
355                     && dataTitle.equals( dsr.getTitle() ) ) {
356    
357                    return dsr;
358                }
359            }
360    
361            return null;
362        }
363    
364        /**
365         * Extracts the List of available service catalogs names for the passed title from the passed Map.
366         *
367         * @param availableServiceCatalogs
368         *            A Map containing the title of a data-metadata object (as key) and a List of names of all available
369         *            service catalogs for this tilte (as value)
370         * @param title
371         *            The title of a data-metadata object.
372         * @return Returns the List of available service catalogs names for the passed title. May be null.
373         */
374        private List extractAvailableServiceCatalogs( Map availableServiceCatalogs, String title ) {
375    
376            List serviceCatalogs = null;
377    
378            if ( availableServiceCatalogs != null && title != null ) {
379                serviceCatalogs = (List) availableServiceCatalogs.get( title );
380            }
381    
382            return serviceCatalogs;
383        }
384    
385    }