001    //$HeadURL: svn+ssh://developername@svn.wald.intevation.org/deegree/base/trunk/resources/eclipse/files_template.xml $
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.cataloguemanager.control;
037    
038    import java.io.ByteArrayOutputStream;
039    import java.io.IOException;
040    import java.net.URI;
041    import java.net.URL;
042    import java.nio.charset.Charset;
043    import java.util.ArrayList;
044    import java.util.Enumeration;
045    import java.util.HashMap;
046    import java.util.List;
047    import java.util.Locale;
048    import java.util.Map;
049    import java.util.UUID;
050    
051    import javax.servlet.http.HttpServletRequest;
052    import javax.xml.transform.dom.DOMSource;
053    import javax.xml.transform.stream.StreamResult;
054    
055    import org.apache.commons.httpclient.HttpMethod;
056    import org.deegree.datatypes.QualifiedName;
057    import org.deegree.enterprise.control.ajax.ResponseHandler;
058    import org.deegree.enterprise.control.ajax.WebEvent;
059    import org.deegree.framework.log.ILogger;
060    import org.deegree.framework.log.LoggerFactory;
061    import org.deegree.framework.util.HttpUtils;
062    import org.deegree.framework.xml.NamespaceContext;
063    import org.deegree.framework.xml.XMLFragment;
064    import org.deegree.framework.xml.XMLTools;
065    import org.deegree.framework.xml.XSLTDocument;
066    import org.deegree.i18n.Messages;
067    import org.deegree.model.filterencoding.ComplexFilter;
068    import org.deegree.model.filterencoding.Filter;
069    import org.deegree.model.filterencoding.Literal;
070    import org.deegree.model.filterencoding.LogicalOperation;
071    import org.deegree.model.filterencoding.Operation;
072    import org.deegree.model.filterencoding.OperationDefines;
073    import org.deegree.model.filterencoding.PropertyIsLikeOperation;
074    import org.deegree.model.filterencoding.PropertyName;
075    import org.deegree.ogcbase.CommonNamespaces;
076    import org.deegree.ogcbase.PropertyPath;
077    import org.deegree.ogcwebservices.csw.discovery.GetRecords;
078    import org.deegree.ogcwebservices.csw.discovery.Query;
079    import org.deegree.ogcwebservices.csw.discovery.XMLFactory;
080    import org.deegree.ogcwebservices.csw.discovery.GetRecords.RESULT_TYPE;
081    import org.deegree.portal.cataloguemanager.model.ExceptionBean;
082    
083    /**
084     * TODO add class documentation here
085     * 
086     * @author <a href="mailto:name@deegree.org">Andreas Poth</a>
087     * @author last edited by: $Author: admin $
088     * 
089     * @version $Revision: $, $Date: $
090     */
091    public class FindServicesListener extends AbstractMetadataListener {
092    
093        private static final ILogger LOG = LoggerFactory.getLogger( FindServicesListener.class );
094    
095        private CatalogueManagerConfiguration config;
096    
097        private Locale loc;
098    
099        /*
100         * (non-Javadoc)
101         * 
102         * @see
103         * org.deegree.enterprise.control.ajax.AbstractListener#actionPerformed(org.deegree.enterprise.control.ajax.WebEvent
104         * , org.deegree.enterprise.control.ajax.ResponseHandler)
105         */
106        @SuppressWarnings("unchecked")
107        public void actionPerformed( WebEvent event, ResponseHandler responseHandler )
108                                throws IOException {
109            loc = getRequest().getLocale();
110    
111            config = getCatalogueManagerConfiguration( event );
112            Map<String, String> param = event.getParameter();
113            String id = param.get( "resourceIdentifier" );
114            String cswAddress = param.get( "CSW" );
115            GetRecords getRecords = createGetRecords( id );
116            GetRecords getRecordsForData = createGetRecordsForData( id );
117            XMLFragment resultXML = null;
118            XMLFragment resultXMLForData = null;
119            try {
120                resultXML = performQuery( getRecords, cswAddress );
121                resultXMLForData = performQuery( getRecordsForData, cswAddress );
122            } catch ( Exception e ) {
123                LOG.logError( e );
124                ExceptionBean bean = new ExceptionBean( this.getClass().getName(), e.getMessage() );
125                responseHandler.writeAndClose( true, bean );
126                return;
127            }
128    
129            writeHTML( responseHandler, cswAddress, resultXML, resultXMLForData, id );
130        }
131    
132        /**
133         * @param id
134         * @return
135         */
136        private GetRecords createGetRecords( String id ) {
137            QualifiedName qn = new QualifiedName( "OperatesOnIdentifier",
138                                                  URI.create( "http://www.opengis.net/cat/csw/apiso/1.0" ) );
139            PropertyName propertyName = new PropertyName( qn );
140            PropertyIsLikeOperation operation = new PropertyIsLikeOperation( propertyName, new Literal( '*' + id + '*' ),
141                                                                             '*', '?', '/' );
142    
143            Filter filter = new ComplexFilter( operation );
144            List<QualifiedName> typeNames = new ArrayList<QualifiedName>();
145            typeNames.add( new QualifiedName( "{http://www.isotc211.org/2005/gmd}:MD_Metadata" ) );
146            Query query = new Query( "full", new ArrayList<QualifiedName>(), new HashMap<String, QualifiedName>(),
147                                     new ArrayList<PropertyPath>(), filter, null, typeNames,
148                                     new HashMap<String, QualifiedName>() );
149            return new GetRecords( UUID.randomUUID().toString(), "2.0.2", null, null, RESULT_TYPE.RESULTS,
150                                   "application/xml", "http://www.isotc211.org/2005/gmd", 1, config.getStepSize() * 2, -1,
151                                   null, query );
152        }
153    
154        /**
155         * @return
156         */
157        private GetRecords createGetRecordsForData( String id ) {
158            QualifiedName qn = new QualifiedName( "ResourceIdentifier",
159                                                  URI.create( "http://www.opengis.net/cat/csw/apiso/1.0" ) );
160            PropertyName propertyName = new PropertyName( qn );
161            PropertyIsLikeOperation operation1 = new PropertyIsLikeOperation( propertyName, new Literal( '*' + id + '*' ),
162                                                                              '*', '?', '/' );
163            qn = new QualifiedName( "Identifier", URI.create( "http://www.opengis.net/cat/csw/apiso/1.0" ) );
164            propertyName = new PropertyName( qn );
165            PropertyIsLikeOperation operation2 = new PropertyIsLikeOperation( propertyName, new Literal( '*' + id + '*' ),
166                                                                              '*', '?', '/' );
167            List<Operation> list = new ArrayList<Operation>();
168            list.add( operation1 );
169            list.add( operation2 );
170            Filter filter = new ComplexFilter( new LogicalOperation( OperationDefines.OR, list ) );
171            List<QualifiedName> typeNames = new ArrayList<QualifiedName>();
172            typeNames.add( new QualifiedName( "{http://www.isotc211.org/2005/gmd}:MD_Metadata" ) );
173            Query query = new Query( "full", new ArrayList<QualifiedName>(), new HashMap<String, QualifiedName>(),
174                                     new ArrayList<PropertyPath>(), filter, null, typeNames,
175                                     new HashMap<String, QualifiedName>() );
176            return new GetRecords( UUID.randomUUID().toString(), "2.0.2", null, null, RESULT_TYPE.RESULTS,
177                                   "application/xml", "http://www.isotc211.org/2005/gmd", 1, config.getStepSize() * 2, -1,
178                                   null, query );
179        }
180    
181        /**
182         * @param cswAddress
183         * @return
184         */
185        @SuppressWarnings("unchecked")
186        private XMLFragment performQuery( GetRecords getRecords, String cswAddress )
187                                throws Exception {
188            XMLFragment gr = XMLFactory.exportWithVersion( getRecords );
189            LOG.logDebug( "GetRecords: ", gr.getAsPrettyString() );
190            Enumeration<String> en = ( (HttpServletRequest) getRequest() ).getHeaderNames();
191            Map<String, String> map = new HashMap<String, String>();
192            while ( en.hasMoreElements() ) {
193                String name = (String) en.nextElement();
194                if ( !name.equalsIgnoreCase( "accept-encoding" ) && !name.equalsIgnoreCase( "content-length" )
195                     && !name.equalsIgnoreCase( "user-agent" ) ) {
196                    map.put( name, ( (HttpServletRequest) getRequest() ).getHeader( name ) );
197                }
198            }
199            HttpMethod method = HttpUtils.performHttpPost( cswAddress, gr, 60000, null, null, map );
200            XMLFragment xml = new XMLFragment();
201            xml.load( method.getResponseBodyAsStream(), cswAddress );
202            if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
203                LOG.logDebug( "GetRecords result: ", xml.getAsPrettyString() );
204            }
205            return xml;
206        }
207    
208        /**
209         * 
210         * @param responseHandler
211         * @param cswAddress
212         * @param resultXML
213         * @param resultXMLForData
214         * @param datasetId
215         * @throws IOException
216         */
217        private void writeHTML( ResponseHandler responseHandler, String cswAddress, XMLFragment resultXML,
218                                XMLFragment resultXMLForData, String datasetId )
219                                throws IOException {
220            String html;
221            try {
222                html = formatResult( resultXML, resultXMLForData, cswAddress, datasetId );
223            } catch ( Exception e ) {
224                LOG.logError( e );
225                ExceptionBean bean = new ExceptionBean( this.getClass().getName(), e.getMessage() );
226                responseHandler.writeAndClose( true, bean );
227                return;
228            }
229            String charEnc = Charset.defaultCharset().displayName();
230            responseHandler.setContentType( "application/json; charset=" + charEnc );
231            responseHandler.writeAndClose( html );
232        }
233    
234        /**
235         * 
236         * @param resultXML
237         * @param resultXMLForData
238         * @param cswAddress
239         * @param datasetId
240         * @return
241         * @throws Exception
242         */
243        private String formatResult( XMLFragment resultXML, XMLFragment resultXMLForData, String cswAddress,
244                                     String datasetId )
245                                throws Exception {
246            URL xslURL = config.getLinkageXSL();
247            XSLTDocument xsl = new XSLTDocument( xslURL );
248            ByteArrayOutputStream bos = new ByteArrayOutputStream( 10000 );
249            DOMSource xmlSource = new DOMSource( resultXML.getRootElement() );
250            DOMSource xslSource = new DOMSource( xsl.getRootElement().getOwnerDocument(),
251                                                 xsl.getSystemId() == null ? null : xsl.getSystemId().toString() );
252            StreamResult sr = new StreamResult( bos );
253            Map<String, String> param = new HashMap<String, String>();
254            param.put( "DATASETID", datasetId );
255            param.put( "TITLE", Messages.get( loc, "CATMANAGE_RESULT_TITLE" ) );
256            param.put( "SERVICETYPE", Messages.get( loc, "CATMANAGE_RESULT_SERVICETYPE" ) );
257            param.put( "ADDTOPORTAL", Messages.get( loc, "CATMANAGE_RESULT_ADDTOPORTAL" ) );
258            param.put( "OPENCAPS", Messages.get( loc, "CATMANAGE_RESULT_OPENCAPS" ) );
259            param.put( "OPENBUTTON", Messages.get( loc, "CATMANAGE_RESULT_OPENBUTTON" ) );
260            param.put( "ADDBUTTON", Messages.get( loc, "CATMANAGE_RESULT_ADDBUTTON" ) );
261            param.put( "CLOSE", Messages.get( loc, "CATMANAGE_RESULT_CLOSE" ) );
262            param.put( "CSW", cswAddress );
263            NamespaceContext nsc = CommonNamespaces.getNamespaceContext();
264            String xpath = "csw202:SearchResults/gmd:MD_Metadata/gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:title/gco:CharacterString";
265            String datasetTitle = XMLTools.getRequiredNodeAsString( resultXMLForData.getRootElement(), xpath, nsc );
266            xpath = "csw202:SearchResults/gmd:MD_Metadata/gmd:identificationInfo/gmd:MD_DataIdentification/gmd:abstract/gco:CharacterString";
267            String abstract_ = XMLTools.getNodeAsString( resultXMLForData.getRootElement(), xpath, nsc, "" );
268            param.put( "DATASETTITLE", datasetTitle );
269            param.put( "DATASETABSTRACT", abstract_ );
270    
271            XSLTDocument.transform( xmlSource, xslSource, sr, null, param );
272            return new String( bos.toByteArray() );
273        }
274    
275    }