001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/csw/manager/Manager_2_0_0.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001-2008 by:
006     EXSE, Department of Geography, University of Bonn
007     http://www.giub.uni-bonn.de/deegree/
008     lat/lon GmbH
009     http://www.lat-lon.de
010    
011     This library is free software; you can redistribute it and/or
012     modify it under the terms of the GNU Lesser General Public
013     License as published by the Free Software Foundation; either
014     version 2.1 of the License, or (at your option) any later version.
015    
016     This library is distributed in the hope that it will be useful,
017     but WITHOUT ANY WARRANTY; without even the implied warranty of
018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019     Lesser General Public License for more details.
020    
021     You should have received a copy of the GNU Lesser General Public
022     License along with this library; if not, write to the Free Software
023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024    
025     Contact:
026    
027     Andreas Poth
028     lat/lon GmbH
029     Aennchenstr. 19
030     53115 Bonn
031     Germany
032     E-Mail: poth@lat-lon.de
033    
034     Prof. Dr. Klaus Greve
035     Department of Geography
036     University of Bonn
037     Meckenheimer Allee 166
038     53115 Bonn
039     Germany
040     E-Mail: greve@giub.uni-bonn.de
041    
042    
043     ---------------------------------------------------------------------------*/
044    package org.deegree.ogcwebservices.csw.manager;
045    
046    import java.io.IOException;
047    import java.io.StringReader;
048    import java.io.StringWriter;
049    import java.net.URISyntaxException;
050    import java.util.ArrayList;
051    import java.util.Collection;
052    import java.util.Iterator;
053    import java.util.List;
054    
055    import javax.xml.transform.TransformerException;
056    
057    import org.deegree.framework.log.ILogger;
058    import org.deegree.framework.log.LoggerFactory;
059    import org.deegree.framework.util.StringTools;
060    import org.deegree.framework.xml.NamespaceContext;
061    import org.deegree.framework.xml.XMLFragment;
062    import org.deegree.framework.xml.XMLParsingException;
063    import org.deegree.framework.xml.XMLTools;
064    import org.deegree.ogcbase.CommonNamespaces;
065    import org.deegree.ogcwebservices.EchoRequest;
066    import org.deegree.ogcwebservices.OGCWebServiceException;
067    import org.deegree.ogcwebservices.wfs.operation.transaction.TransactionResponse;
068    import org.w3c.dom.Element;
069    import org.xml.sax.SAXException;
070    
071    /**
072     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
073     * 
074     * @author last edited by: $Author: apoth $
075     * 
076     * @version 2.0, $Revision: 9361 $, $Date: 2007-12-29 10:15:41 +0100 (Sa, 29 Dez 2007) $
077     */
078    
079    public class Manager_2_0_0 extends AbstractManager {
080    
081        private static final ILogger LOG = LoggerFactory.getLogger( Manager_2_0_0.class );
082    
083       
084        /*
085         * (non-Javadoc)
086         * 
087         * @see org.deegree.ogcwebservices.csw.manager.Manager#harvestRecords(org.deegree.ogcwebservices.csw.manager.Harvest)
088         */
089        public EchoRequest harvestRecords( Harvest request )
090                                throws OGCWebServiceException {
091            try {
092                HarvesterFactory hf = new HarvesterFactory( harvester );
093                AbstractHarvester h = hf.findHarvester( request );
094                h.addRequest( request );
095                if ( !h.isRunning() ) {
096                    h.startHarvesting();
097                }
098                if ( request.getHarvestInterval() == null ) {
099                    // h.removeRequest( request );
100                }
101            } catch ( Exception e ) {
102                LOG.logError( "could not perform harvest operation", e );
103                throw new OGCWebServiceException( getClass().getName(), "could not perform harvest operation"
104                                                                        + e.getMessage() );
105            }
106    
107            return new EchoRequest( request.getId(), null );
108        }
109    
110        /*
111         * (non-Javadoc)
112         * 
113         * @see org.deegree.ogcwebservices.csw.manager.Manager#transaction(org.deegree.ogcwebservices.csw.manager.Transaction)
114         */
115        public TransactionResult transaction( Transaction request )
116                                throws OGCWebServiceException {
117            XMLFragment wfsTransactionDocument = null;
118            try {
119                XMLFragment transactionDocument = new XMLFragment( XMLFactory.export( request ).getRootElement() );
120                StringWriter sww = new StringWriter( 15000 );
121                transactionDocument.write( sww );
122                transactionDocument.load( new StringReader( sww.getBuffer().toString() ), XMLFragment.DEFAULT_URL );
123                wfsTransactionDocument = IN_XSL.transform( transactionDocument );
124                if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
125                    LOG.logDebug( "The (first) resulting wfs:Transaction document: \n "
126                                  + wfsTransactionDocument.getAsPrettyString() );
127                }
128            } catch ( SAXException saxe ) {
129                String msg = org.deegree.i18n.Messages.get( "CSW_CREATE_TRANSACTION_ERROR", saxe.getMessage() );
130                LOG.logError( msg, saxe );
131                throw new OGCWebServiceException( msg );
132            } catch ( IOException ioe ) {
133                String msg = org.deegree.i18n.Messages.get( "CSW_CREATE_TRANSACTION_ERROR", ioe.getMessage() );
134                LOG.logError( msg, ioe );
135                throw new OGCWebServiceException( msg );
136            } catch ( TransformerException te ) {
137                String msg = org.deegree.i18n.Messages.get( "CSW_CREATE_TRANSACTION_ERROR", te.getMessage() );
138                LOG.logError( msg, te );
139                throw new OGCWebServiceException( msg );
140            } catch ( XMLParsingException xmle ) {
141                String msg = org.deegree.i18n.Messages.get( "CSW_CREATE_TRANSACTION_ERROR", xmle.getMessage() );
142                LOG.logError( msg, xmle );
143                throw new OGCWebServiceException( msg );
144            }
145    
146            org.deegree.ogcwebservices.wfs.operation.transaction.Transaction wfstrans = null;
147            try {
148                LOG.logDebug( "Creating a wfs transaction from the document" );
149                wfstrans = org.deegree.ogcwebservices.wfs.operation.transaction.Transaction.create(
150                                                                                                    request.getId(),
151                                                                                                    wfsTransactionDocument.getRootElement() );
152            } catch ( OGCWebServiceException ogcwe ) {
153                LOG.logError( ogcwe.getMessage(), ogcwe );
154                String msg = org.deegree.i18n.Messages.get( "CSW_CREATE_TRANSACTION_ERROR2", ogcwe.getMessage() );
155                throw new OGCWebServiceException( msg );
156            }
157    
158            Object wfsResponse = null;
159            try {
160                LOG.logDebug( "Sending the wfs transaction to the wfservice." );
161                wfsResponse = wfsService.doService( wfstrans );
162            } catch ( OGCWebServiceException e ) {
163                String msg = org.deegree.i18n.Messages.get( "CSW_PERFORMING_TRANSACTION_ERROR", e.getMessage() );
164                LOG.logError( msg, e );
165                throw new OGCWebServiceException( msg );
166            }
167    
168            if ( !( wfsResponse instanceof org.deegree.ogcwebservices.wfs.operation.transaction.TransactionResponse ) ) {
169                String msg = org.deegree.i18n.Messages.get( "CSW_WRONG_TRANSACTION_RESULTTYPE",
170                                                            wfsResponse.getClass().getName() );
171                LOG.logError( msg );
172                throw new OGCWebServiceException( msg );
173            }
174    
175            TransactionResponse transResp = (TransactionResponse) wfsResponse;
176            XMLFragment wfsTransRespDoc = null;
177            try {
178                LOG.logDebug( "Parsing the wfs response." );
179                wfsTransRespDoc = org.deegree.ogcwebservices.wfs.XMLFactory.export( transResp );
180            } catch ( IOException e ) {
181                String msg = "export of WFS Transaction response as XML failed: " + e.getMessage();
182                LOG.logError( msg, e );
183                throw new OGCWebServiceException( msg );
184            }
185    
186            // --------------------------------------------------------------
187            // the following section will replace the feature ids returned by
188            // the WFS for Insert requests by the ID of the inserted metadata sets
189            List<String> ids = new ArrayList<String>();
190            List<Operation> ops = request.getOperations();
191            for ( int i = 0; i < ops.size(); i++ ) {
192                if ( ops.get( i ) instanceof Insert ) {
193                    try {
194                        ids = extractIdentifiers( ids, (Insert) ops.get( i ) );
195                    } catch ( Exception e ) {
196                        LOG.logError( e.getMessage(), e );
197                        throw new OGCWebServiceException( getClass().getName(), e.getMessage() );
198                    }
199                }
200            }
201            try {
202                if ( ids.size() > 0 ) {
203                    wfsTransRespDoc = replaceIds( wfsTransRespDoc, ids );
204                }
205            } catch ( Exception e ) {
206                LOG.logError( e.getMessage(), e );
207                throw new OGCWebServiceException( getClass().getName(), e.getMessage() );
208            }
209            // ---------------------------------------------------------------
210    
211            TransactionResultDocument cswTransactionDocument = null;
212            try {
213                XMLFragment tmp = OUT_XSL.transform( wfsTransRespDoc );
214                cswTransactionDocument = new TransactionResultDocument();
215                cswTransactionDocument.setRootElement( tmp.getRootElement() );
216            } catch ( TransformerException e ) {
217                String msg = org.deegree.i18n.Messages.get( "CSW_TRANSACTION_RESULT_TRANS_ERR", e.getMessage() );
218                LOG.logError( msg, e );
219                throw new OGCWebServiceException( msg );
220            }
221            TransactionResult result = null;
222            try {
223                result = cswTransactionDocument.parseTransactionResponse( request );
224            } catch ( XMLParsingException e ) {
225                String msg = org.deegree.i18n.Messages.get( "CSW_TRANSACTION_RESULT_PARSE_ERR" );
226                LOG.logError( msg, e );
227                throw new OGCWebServiceException( msg );
228            }
229            return result;
230        }
231    
232        /**
233         * replaces the id values of WFS Insert result with corresponding metadata identifieres
234         * 
235         * @param wfsTransRespDoc
236         * @param ids
237         * @return an xmlFragment with the gml:Feature ids replaced with the id' s given in the list
238         * @throws URISyntaxException
239         * @throws XMLParsingException
240         */
241        private XMLFragment replaceIds( XMLFragment wfsTransRespDoc, List<String> ids )
242                                throws XMLParsingException {
243    
244            List nodes = XMLTools.getRequiredNodes( wfsTransRespDoc.getRootElement(),
245                                                    "./wfs:InsertResults/wfs:Feature/ogc:FeatureId",
246                                                    CommonNamespaces.getNamespaceContext() );
247            for ( int i = 0; i < nodes.size(); i++ ) {
248                Element elem = (Element) nodes.get( i );
249                elem.setAttribute( "fid", ids.get( i ) );
250            }
251    
252            return wfsTransRespDoc;
253        }
254    
255        /**
256         * extracts all identifiers of the records to be inserted in correct order
257         * 
258         * @param ids
259         * @param insert
260         * @return a list of identifiers which should be keys to xpaths which are defined in the
261         *         messages.properties
262         * @throws XMLParsingException
263         * @throws URISyntaxException
264         */
265        private List<String> extractIdentifiers( List<String> ids, Insert insert )
266                                throws XMLParsingException {
267            List<Element> records = insert.getRecords();
268    
269            NamespaceContext nsc = CommonNamespaces.getNamespaceContext();
270    
271            for ( int i = 0; i < records.size(); i++ ) {
272                String xpath = getIdentifierXPath( records.get( i ) );
273                String fileIdentifier = XMLTools.getRequiredNodeAsString( records.get( i ), xpath, nsc );
274                ids.add( fileIdentifier );
275            }
276            return ids;
277        }
278    
279        /**
280         * returns the XPath the metadata records identifier
281         * 
282         * @param metaData
283         * @return the XPath the metadata records identifier
284         */
285        private String getIdentifierXPath( Element metaData ) {
286    
287            // default is iso 19115
288            String xpath = "iso19115:fileIdentifier/smXML:CharacterString";
289            if ( metaData != null ) {
290                String nspace = metaData.getNamespaceURI();
291                nspace = StringTools.replace( nspace, "http://", "", true );
292                xpath = Messages.getString( "Identifier_" + nspace );
293            }
294            return xpath;
295        }
296    
297    }