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 }