001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/ogcwebservices/csw/manager/ServiceHarvester.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 package org.deegree.ogcwebservices.csw.manager; 037 038 import java.io.IOException; 039 import java.net.URI; 040 import java.net.URL; 041 import java.util.Date; 042 import java.util.Iterator; 043 import java.util.List; 044 045 import javax.xml.transform.TransformerException; 046 047 import org.deegree.framework.log.ILogger; 048 import org.deegree.framework.log.LoggerFactory; 049 import org.deegree.framework.xml.XMLFragment; 050 import org.deegree.framework.xml.XMLParsingException; 051 import org.deegree.framework.xml.XMLTools; 052 import org.deegree.framework.xml.XSLTDocument; 053 import org.deegree.ogcwebservices.csw.manager.HarvestRepository.ResourceType; 054 import org.xml.sax.SAXException; 055 056 /** 057 * <p> 058 * Concrete implementation of 059 * 060 * @see org.deegree.ogcwebservices.csw.manager.AbstractHarvester for harvesting service metadata 061 * from OGC web services. To enable this capabilities documents of the OWS will be accessed and 062 * transformed into a valid format that will be understood by the underlying catalogue. To 063 * enable a lot of flexibility a XSLT read from resource bundle (harvestservice.xsl) script 064 * will be used to perform the required transformation. 065 * </p> 066 * <p> 067 * A valid harvest SOURCE for a service must be a complete GetCapabilities request; the 068 * RESOURCETYPE must be 'service'. Example: 069 * </p> 070 * <p> 071 * ...?request=Harvest&version=2.0.0&source=[http://MyServer:8080/deegree? 072 * service=WFS&version=1.1.0&request=GetCapabilities]&resourceType=service& 073 * resourceFormat=text/xml&responseHandler=mailto:info@lat-lon.de&harvestInterval=P2W 074 * </p> 075 * <p> 076 * value in brackets [..] must be URL encoded and send without brackets! 077 * </p> 078 * <p> 079 * This is not absolutly compliant to OGc CSW 2.0.0 specification but Harvest definition as 080 * available from the spec is to limited because it just targets single metadata documents. 081 * </p> 082 * 083 * @version $Revision: 19475 $ 084 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 085 * @author last edited by: $Author: lbuesching $ 086 * 087 * @version 1.0. $Revision: 19475 $, $Date: 2009-09-02 14:51:48 +0200 (Mi, 02 Sep 2009) $ 088 * 089 * @since 2.0 090 */ 091 public class ServiceHarvester extends AbstractHarvester { 092 093 static final ILogger LOG = LoggerFactory.getLogger( ServiceHarvester.class ); 094 095 static final URL xslt = ServiceHarvester.class.getResource( "harvestservice.xsl" ); 096 097 private static ServiceHarvester sh = null; 098 099 /** 100 * @param version 101 * the version of the CSW 102 */ 103 public ServiceHarvester( String version ) { 104 super( version ); 105 } 106 107 /** 108 * singelton 109 * 110 * @param version 111 * the version of the CSW 112 * 113 * @return the new instance 114 */ 115 public static ServiceHarvester getInstance( String version ) { 116 if ( sh == null ) { 117 sh = new ServiceHarvester( version ); 118 } 119 return sh; 120 } 121 122 @Override 123 public void run() { 124 LOG.logDebug( "starting harvest iteration for ServiceHarvester." ); 125 try { 126 HarvestRepository repository = HarvestRepository.getInstance(); 127 128 List<URI> sources = repository.getSources(); 129 for ( Iterator<URI> iter = sources.iterator(); iter.hasNext(); ) { 130 URI source = iter.next(); 131 try { 132 // determine if source shall be harvested 133 if ( shallHarvest( source, ResourceType.service ) ) { 134 inProgress.add( source ); 135 HarvestProcessor processor = new HarvestProcessor( this, source ); 136 processor.start(); 137 } 138 } catch ( Exception e ) { 139 LOG.logError( "Exception harvesting service: " + source, e ); 140 informResponseHandlers( source, e ); 141 } 142 } 143 } catch ( Exception e ) { 144 LOG.logError( "generell Exception harvesting services", e ); 145 } 146 147 } 148 149 /** 150 * inner class for processing asynchronous harvesting of a service 151 * 152 * @version $Revision: 19475 $ 153 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 154 * @author last edited by: $Author: lbuesching $ 155 * 156 * @version 1.0. $Revision: 19475 $, $Date: 2009-09-02 14:51:48 +0200 (Mi, 02 Sep 2009) $ 157 * 158 * @since 2.0 159 */ 160 protected class HarvestProcessor extends AbstractHarvestProcessor { 161 162 HarvestProcessor( AbstractHarvester owner, URI source ) { 163 super( owner, source ); 164 } 165 166 @Override 167 public void run() { 168 try { 169 HarvestRepository repository = HarvestRepository.getInstance(); 170 XMLFragment capabilities = accessSourceCapabilities( source ); 171 Date harvestingTimestamp = repository.getNextHarvestingTimestamp( source ); 172 XMLFragment metaData = transformCapabilities( capabilities ); 173 String trans = null; 174 if ( repository.getLastHarvestingTimestamp( source ) == null ) { 175 trans = createInsertRequest( metaData ); 176 } else { 177 trans = createUpdateRequest( getID( metaData ), getIdentifierXPathForUpdate( metaData ), metaData ); 178 } 179 performTransaction( trans ); 180 // update timestamps just if transaction has been performed 181 // successfully 182 writeLastHarvestingTimestamp( source, harvestingTimestamp ); 183 writeNextHarvestingTimestamp( source, harvestingTimestamp ); 184 informResponseHandlers( source ); 185 } catch ( Exception e ) { 186 LOG.logError( "could not perform harvest operation for source: " + source, e ); 187 try { 188 owner.informResponseHandlers( source, e ); 189 } catch ( Exception ee ) { 190 ee.printStackTrace(); 191 } 192 } 193 } 194 195 private String getID( XMLFragment metaData ) 196 throws XMLParsingException { 197 String xpath = getIdentifierXPath( metaData ); 198 String fileIdentifier = XMLTools.getRequiredNodeAsString( metaData.getRootElement(), xpath, nsc ); 199 return fileIdentifier; 200 } 201 202 @Override 203 protected String createConstraint( String fileIdentifier, String xPath ) { 204 throw new UnsupportedOperationException(); 205 } 206 207 /** 208 * transforms a OWS capabilities document into the desired target format 209 * 210 * @param xml 211 * @return the transformed document 212 * @throws IOException 213 * @throws SAXException 214 * @throws TransformerException 215 */ 216 private XMLFragment transformCapabilities( XMLFragment xml ) 217 throws IOException, SAXException, TransformerException { 218 219 XSLTDocument xsltDoc = new XSLTDocument(); 220 xsltDoc.load( xslt ); 221 222 return xsltDoc.transform( xml ); 223 } 224 225 /** 226 * returns the capabilities of 227 * 228 * @param source 229 * @return the capabilities 230 * @throws IOException 231 * @throws SAXException 232 */ 233 private XMLFragment accessSourceCapabilities( URI source ) 234 throws IOException, SAXException { 235 236 URL url = source.toURL(); 237 XMLFragment xml = new XMLFragment(); 238 xml.load( url ); 239 return xml; 240 } 241 242 } 243 244 }