001 //$HeadURL: svn+ssh://developername@svn.wald.intevation.org/deegree/base/trunk/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.MalformedURLException;
050 import java.net.URISyntaxException;
051 import java.net.URL;
052 import java.util.ArrayList;
053 import java.util.HashMap;
054 import java.util.Iterator;
055 import java.util.List;
056 import java.util.Map;
057
058 import javax.xml.transform.TransformerException;
059
060 import org.deegree.framework.log.ILogger;
061 import org.deegree.framework.log.LoggerFactory;
062 import org.deegree.framework.xml.DOMPrinter;
063 import org.deegree.framework.xml.XMLFragment;
064 import org.deegree.framework.xml.XMLParsingException;
065 import org.deegree.framework.xml.XMLTools;
066 import org.deegree.framework.xml.XSLTDocument;
067 import org.deegree.ogcbase.CommonNamespaces;
068 import org.deegree.ogcwebservices.EchoRequest;
069 import org.deegree.ogcwebservices.OGCWebServiceException;
070 import org.deegree.ogcwebservices.wfs.operation.transaction.TransactionResponse;
071 import org.w3c.dom.Document;
072 import org.w3c.dom.Element;
073 import org.w3c.dom.NamedNodeMap;
074 import org.w3c.dom.Node;
075 import org.w3c.dom.NodeList;
076 import org.xml.sax.SAXException;
077
078 /**
079 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
080 *
081 * @author last edited by: $Author: apoth $
082 *
083 * @version 2.0, $Revision: 9359 $, $Date: 2007-12-28 16:30:52 +0100 (Fr, 28 Dez 2007) $
084 */
085
086 public class Manager_2_0_2 extends AbstractManager {
087
088 private static final ILogger LOG = LoggerFactory.getLogger( Manager_2_0_2.class );
089
090 private static final URL xsltURL = Manager_2_0_2.class.getResource( "iso_ap_1_0_full2brief.xsl" );
091
092 /*
093 * (non-Javadoc)
094 *
095 * @see org.deegree.ogcwebservices.csw.manager.Manager#harvestRecords(org.deegree.ogcwebservices.csw.manager.Harvest)
096 */
097 public EchoRequest harvestRecords( Harvest request )
098 throws OGCWebServiceException {
099 try {
100 HarvesterFactory hf = new HarvesterFactory( harvester );
101 AbstractHarvester h = hf.findHarvester( request );
102 h.addRequest( request );
103 if ( !h.isRunning() ) {
104 h.startHarvesting();
105 }
106 if ( request.getHarvestInterval() == null ) {
107 // h.removeRequest( request );
108 }
109 } catch ( Exception e ) {
110 LOG.logError( "could not perform harvest operation", e );
111 throw new OGCWebServiceException( getClass().getName(), "could not perform harvest operation"
112 + e.getMessage() );
113 }
114
115 return new EchoRequest( request.getId(), null );
116 }
117
118 /*
119 * (non-Javadoc)
120 *
121 * @see org.deegree.ogcwebservices.csw.manager.Manager#transaction(org.deegree.ogcwebservices.csw.manager.Transaction)
122 */
123 public TransactionResult transaction( Transaction request )
124 throws OGCWebServiceException {
125 XMLFragment wfsTransactionDocument = null;
126
127 try {
128 XMLFragment transactionDocument = XMLFactory.export( request );
129 String nsp = getAllNamespaceDeclarations( transactionDocument.getRootElement() );
130 StringWriter sww = new StringWriter( 15000 );
131 transactionDocument.write( sww );
132 transactionDocument.load( new StringReader( sww.getBuffer().toString() ), XMLFragment.DEFAULT_URL );
133
134 synchronized ( IN_XSL ) {
135 Map<String, String> param = new HashMap<String, String>();
136 param.put( "NSP", nsp );
137 try {
138 wfsTransactionDocument = IN_XSL.transform( transactionDocument, XMLFragment.DEFAULT_URL, null,
139 param );
140 } catch ( MalformedURLException e ) {
141 LOG.logError( e.getMessage(), e );
142 }
143 }
144
145 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
146 LOG.logDebug( "The (first) resulting wfs:Transaction document: \n "
147 + wfsTransactionDocument.getAsPrettyString() );
148 }
149 } catch ( SAXException saxe ) {
150 String msg = org.deegree.i18n.Messages.get( "CSW_CREATE_TRANSACTION_ERROR", saxe.getMessage() );
151 LOG.logError( msg, saxe );
152 throw new OGCWebServiceException( msg );
153 } catch ( IOException ioe ) {
154 String msg = org.deegree.i18n.Messages.get( "CSW_CREATE_TRANSACTION_ERROR", ioe.getMessage() );
155 LOG.logError( msg, ioe );
156 throw new OGCWebServiceException( msg );
157 } catch ( TransformerException te ) {
158 String msg = org.deegree.i18n.Messages.get( "CSW_CREATE_TRANSACTION_ERROR", te.getMessage() );
159 LOG.logError( msg, te );
160 throw new OGCWebServiceException( msg );
161 } catch ( XMLParsingException xmle ) {
162 String msg = org.deegree.i18n.Messages.get( "CSW_CREATE_TRANSACTION_ERROR", xmle.getMessage() );
163 LOG.logError( msg, xmle );
164 throw new OGCWebServiceException( msg );
165 }
166
167 org.deegree.ogcwebservices.wfs.operation.transaction.Transaction wfstrans = null;
168 try {
169 LOG.logDebug( "Creating a wfs transaction from the document" );
170 wfstrans = org.deegree.ogcwebservices.wfs.operation.transaction.Transaction.create(
171 request.getId(),
172 wfsTransactionDocument.getRootElement() );
173 } catch ( OGCWebServiceException ogcwe ) {
174 LOG.logError( ogcwe.getMessage(), ogcwe );
175 String msg = org.deegree.i18n.Messages.get( "CSW_CREATE_TRANSACTION_ERROR2", ogcwe.getMessage() );
176 throw new OGCWebServiceException( msg );
177 }
178
179 Object wfsResponse = null;
180 try {
181 LOG.logDebug( "Sending the wfs transaction to the wfservice." );
182 wfsResponse = wfsService.doService( wfstrans );
183 } catch ( OGCWebServiceException e ) {
184 String msg = org.deegree.i18n.Messages.get( "CSW_PERFORMING_TRANSACTION_ERROR", e.getMessage() );
185 LOG.logError( msg, e );
186 throw new OGCWebServiceException( msg );
187 }
188
189 if ( !( wfsResponse instanceof org.deegree.ogcwebservices.wfs.operation.transaction.TransactionResponse ) ) {
190 String msg = org.deegree.i18n.Messages.get( "CSW_WRONG_TRANSACTION_RESULTTYPE",
191 wfsResponse.getClass().getName() );
192 LOG.logError( msg );
193 throw new OGCWebServiceException( msg );
194 }
195
196 TransactionResponse transResp = (TransactionResponse) wfsResponse;
197 XMLFragment wfsTransRespDoc = null;
198 try {
199 LOG.logDebug( "Parsing the wfs response." );
200 wfsTransRespDoc = org.deegree.ogcwebservices.wfs.XMLFactory.export( transResp );
201 } catch ( IOException e ) {
202 String msg = "export of WFS Transaction response as XML failed: " + e.getMessage();
203 LOG.logError( msg, e );
204 throw new OGCWebServiceException( msg );
205 }
206
207 // --------------------------------------------------------------
208 // the following section will replace the feature ids returned by
209 // the WFS for Insert requests by the ID of the inserted metadata sets
210 List<Document> briefDocs = new ArrayList<Document>();
211 List<Operation> ops = request.getOperations();
212 for ( int i = 0; i < ops.size(); i++ ) {
213 if ( ops.get( i ) instanceof Insert ) {
214 try {
215 briefDocs = getAsBriefDocuments( briefDocs, (Insert) ops.get( i ) );
216 } catch ( Exception e ) {
217 LOG.logError( e.getMessage(), e );
218 throw new OGCWebServiceException( getClass().getName(), e.getMessage() );
219 }
220 }
221 }
222 try {
223 if ( briefDocs.size() > 0 ) {
224 wfsTransRespDoc = replaceIds( wfsTransRespDoc, briefDocs );
225 }
226 } catch ( Exception e ) {
227 LOG.logError( e.getMessage(), e );
228 throw new OGCWebServiceException( getClass().getName(), e.getMessage() );
229 }
230 // ---------------------------------------------------------------
231
232 TransactionResultDocument cswTransactionDocument = null;
233 try {
234 XMLFragment tmp = OUT_XSL.transform( wfsTransRespDoc );
235 cswTransactionDocument = new TransactionResultDocument();
236 cswTransactionDocument.setRootElement( tmp.getRootElement() );
237 } catch ( TransformerException e ) {
238 String msg = org.deegree.i18n.Messages.get( "CSW_TRANSACTION_RESULT_TRANS_ERR", e.getMessage() );
239 LOG.logError( msg, e );
240 throw new OGCWebServiceException( msg );
241 }
242 TransactionResult result = null;
243 try {
244 result = cswTransactionDocument.parseTransactionResponse( request );
245 } catch ( XMLParsingException e ) {
246 String msg = org.deegree.i18n.Messages.get( "CSW_TRANSACTION_RESULT_PARSE_ERR" );
247 LOG.logError( msg, e );
248 throw new OGCWebServiceException( msg );
249 }
250 return result;
251 }
252
253 private String getAllNamespaceDeclarations( Element doc ) {
254 Map<String, String> nsp = new HashMap<String, String>();
255 nsp = collect( nsp, doc );
256 Iterator<String> iter = nsp.keySet().iterator();
257 StringBuffer sb = new StringBuffer( 1000 );
258 while ( iter.hasNext() ) {
259 String s = iter.next();
260 String val = nsp.get( s );
261 sb.append( s ).append( ":" ).append( val );
262 if ( iter.hasNext() ) {
263 sb.append( ';' );
264 }
265 }
266 return sb.toString();
267 }
268
269 private Map<String, String> collect( Map<String, String> nsp, Node node ) {
270 NamedNodeMap nnm = node.getAttributes();
271 if ( nnm != null ) {
272 for ( int i = 0; i < nnm.getLength(); i++ ) {
273 String s = nnm.item( i ).getNodeName();
274 if ( s.startsWith( "xmlns:" ) ) {
275 nsp.put( s.substring( 6, s.length() ), nnm.item( i ).getNodeValue() );
276 }
277 }
278 }
279
280 NodeList nl = node.getChildNodes();
281 if ( nl != null ) {
282 for ( int i = 0; i < nl.getLength(); i++ ) {
283 collect( nsp, nl.item( i ) );
284 }
285 }
286 return nsp;
287 }
288
289 /**
290 * replaces the id values of WFS Insert result with corresponding metadata brief representations
291 *
292 * @param wfsTransRespDoc
293 * @param briefDocs
294 * @return an xmlFragment with the gml:Feature ids replaced with the id' s given in the list
295 * @throws URISyntaxException
296 * @throws XMLParsingException
297 */
298 private XMLFragment replaceIds( XMLFragment wfsTransRespDoc, List<Document> briefDocs )
299 throws XMLParsingException {
300
301 List nodes = XMLTools.getRequiredNodes( wfsTransRespDoc.getRootElement(),
302 "./wfs:InsertResults/wfs:Feature/ogc:FeatureId",
303 CommonNamespaces.getNamespaceContext() );
304 Element parent = null;
305 for ( int i = 0; i < nodes.size(); i++ ) {
306 Element elem = (Element) nodes.get( i );
307 parent = (Element) elem.getParentNode();
308 parent.removeChild( elem );
309 }
310 if ( parent != null ) {
311 for ( int i = 0; i < briefDocs.size(); i++ ) {
312 parent = (Element) XMLTools.insertNodeInto( briefDocs.get( i ).getDocumentElement(), parent );
313 }
314 }
315
316 return wfsTransRespDoc;
317 }
318
319 /**
320 * all inserted records into threir brief representation
321 *
322 * @param docs
323 * @param insert
324 * @return a list of brief metadata records
325 * @throws SAXException
326 * @throws IOException
327 * @throws TransformerException
328 */
329 private List<Document> getAsBriefDocuments( List<Document> docs, Insert insert )
330 throws IOException, SAXException, TransformerException {
331 List<Element> records = insert.getRecords();
332
333 XSLTDocument xslt = new XSLTDocument( xsltURL );
334
335 for ( int i = 0; i < records.size(); i++ ) {
336 XMLFragment xml = new XMLFragment();
337 xml.setRootElement( records.get( i ) );
338 xml = xslt.transform( xml );
339 docs.add( xml.getRootElement().getOwnerDocument() );
340 }
341 return docs;
342 }
343
344 }