001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/csw/manager/Harvest.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.net.URI;
047    import java.net.URISyntaxException;
048    import java.util.ArrayList;
049    import java.util.Date;
050    import java.util.GregorianCalendar;
051    import java.util.List;
052    import java.util.Map;
053    
054    import org.deegree.datatypes.time.TimeDuration;
055    import org.deegree.framework.log.ILogger;
056    import org.deegree.framework.log.LoggerFactory;
057    import org.deegree.framework.util.TimeTools;
058    import org.deegree.framework.xml.XMLParsingException;
059    import org.deegree.ogcwebservices.AbstractOGCWebServiceRequest;
060    import org.deegree.ogcwebservices.InvalidParameterValueException;
061    import org.deegree.ogcwebservices.MissingParameterValueException;
062    import org.w3c.dom.Element;
063    
064    /**
065     * <p>
066     * The general model defines two operations in the Manager class that may be used to create or
067     * update records in the catalogue. They are the transaction operation and the harvestRecords
068     * operation. The transaction operation may be used to "push" data into the catalogue and is defined
069     * in Subclause 10.11. of CS-W specification. This subclause defines the optional Harvest operation,
070     * which is an operation that "pulls" data into the catalogue. That is, this operation only
071     * references the data to be inserted or updated in the catalogue, and it is the job of the
072     * catalogue service to resolve the reference, fetch that data, and process it into the catalogue.
073     * </p>
074     * <p>
075     * The Harvest operation had two modes of operation, controlled by a flag in the request. The first
076     * mode of operation is a synchronous mode in whice the CSW receives a Harvest request from the
077     * client, processes it immediately, and sends the results to the client while the client waits. The
078     * second mode of operation is asynchronous in that the server receives a Harvest request from the
079     * client, and sends the client an immediate acknowledgement that the request has been successfully
080     * received. The server can then process the Harvest request whenever it likes, taking as much time
081     * as is required and then send the results of the processing to a URI specified in the original
082     * Harvest request. This latter mode of operation is included to support Harvest requests that could
083     * run for a period of time longer than most HTTP timeout’s will allow.
084     * </p>
085     * <p>
086     * Processing a Harvest request means that the CSW resolves the URI pointing to the metadata
087     * resource, parses the resource, and then creates or modifies metadata records in the catalogue in
088     * order to register the resource. This operation may be performed only once or periodically
089     * depending on how the client invokes the operation.
090     * </p>
091     * 
092     * @version $Revision: 9345 $
093     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
094     * @author last edited by: $Author: apoth $
095     * 
096     * @version 1.0. $Revision: 9345 $, $Date: 2007-12-27 17:22:25 +0100 (Do, 27 Dez 2007) $
097     * 
098     * @since 2.0
099     */
100    public class Harvest extends AbstractOGCWebServiceRequest {
101    
102        private static final long serialVersionUID = -3531806711669781486L;
103    
104        private static final ILogger LOG = LoggerFactory.getLogger( Harvest.class );
105    
106        private URI source = null;
107    
108        private URI resourceType = null;
109    
110        private String resourceFormat = null;
111    
112        private TimeDuration harvestInterval = null;
113    
114        private List<URI> responseHandler = null;
115    
116        private Date startTimestamp = null;
117    
118        /**
119         * factory method for creating a Harvest request from its KVP representation
120         * 
121         * @param param
122         * @return
123         */
124        public static Harvest create( Map param )
125                                throws InvalidParameterValueException, MissingParameterValueException {
126    
127            LOG.logInfo( "parse harvest request KVP-encoded" );
128    
129            String id = (String) param.get( "ID" );
130            if ( id == null ) {
131                throw new MissingParameterValueException( "ID parameter must be set" );
132            }
133    
134            String version = (String) param.get( "VERSION" );
135            if ( version == null ) {
136                throw new MissingParameterValueException( "VERSION parameter must be set for "
137                                                          + "a harvest request" );
138            }
139    
140            String tmp = (String) param.get( "SOURCE" );
141            if ( tmp == null ) {
142                throw new MissingParameterValueException( "SOURCE parameter must be set for "
143                                                          + "a harvest request" );
144            }
145            URI source = null;
146            try {
147                source = new URI( tmp );
148            } catch ( URISyntaxException e ) {
149                throw new InvalidParameterValueException( tmp + " is no valid source URI for a "
150                                                          + "harvest request" );
151            }
152    
153            tmp = (String) param.get( "RESOURCETYPE" );
154            URI resourceType = null;
155            if ( tmp != null ) {
156                try {
157                    resourceType = new URI( tmp );
158                } catch ( URISyntaxException e ) {
159                    throw new InvalidParameterValueException( tmp + " is no valid resourceType URI "
160                                                              + "for a harvest request" );
161                }
162            }
163    
164            String resourceFormat = (String) param.get( "RESOURCEFORMAT" );
165            if ( resourceFormat == null ) {
166                resourceFormat = "text/xml";
167            }
168    
169            List<URI> list = new ArrayList<URI>();
170            tmp = (String) param.get( "RESPONSEHANDLER" );
171            URI responseHandler = null;
172            if ( tmp != null ) {
173                try {
174                    responseHandler = new URI( tmp );
175                } catch ( URISyntaxException e ) {
176                    throw new InvalidParameterValueException( tmp + " is no valid resourceHandler URI "
177                                                              + "for a harvest request" );
178                }
179                list.add( responseHandler );
180            }        
181            
182    
183            tmp = (String) param.get( "HARVESTINTERVAL" );
184            TimeDuration timeDuration = null;
185            if ( tmp != null ) {
186                timeDuration = TimeDuration.createTimeDuration( tmp );
187            }
188    
189            Date date = new GregorianCalendar().getTime();
190            tmp = (String) param.get( "STARTTIMESTAMP" );
191            if ( tmp != null ) {
192                date = TimeTools.createCalendar( tmp ).getTime();
193            }
194    
195            return new Harvest( version, id, null, source, resourceType, resourceFormat, timeDuration,
196                                list, date );
197        }
198    
199        /**
200         * creates a Harvesting Request from its XM representation
201         * 
202         * @param id
203         * @param transRoot
204         * @return
205         * @throws XMLParsingException
206         */
207        public static final Transaction create( String id, Element transRoot )
208                                throws XMLParsingException {
209            throw new UnsupportedOperationException( "create( String, Element )" );
210        }
211    
212        /**
213         * 
214         * @param version
215         * @param id
216         * @param vendorSpecificParameter
217         * @param source
218         * @param resourceType
219         * @param resourceFormat
220         * @param harvestTimeDuration
221         * @param responseHandler
222         */
223        Harvest( String version, String id, Map<String,String> vendorSpecificParameter, 
224                 URI source, URI resourceType, String resourceFormat, 
225                 TimeDuration harvestTimeDuration, List<URI> responseHandler,
226                 Date startTimestamp ) {
227            super( version, id, vendorSpecificParameter );
228            this.source = source;
229            this.resourceType = resourceType;
230            this.resourceFormat = resourceFormat;
231            this.harvestInterval = harvestTimeDuration;
232            this.responseHandler = responseHandler;
233            this.startTimestamp = startTimestamp;
234        }
235    
236        /**
237         * <p>
238         * The HarvestTimeDuration parameter is used to specify the period of time, in ISO 8601 period
239         * format, that should elapse before a CSW attempts to re-harvest the specified resource thus
240         * refreshing it copy of a resource.
241         * </p>
242         * <p>
243         * If no HarvestTimeDuration parameter is specified then the resource is harvested only once in
244         * response to the Harvest request.
245         * </p>
246         * 
247         * @return
248         */
249        public TimeDuration getHarvestInterval() {
250            return harvestInterval;
251        }
252    
253        /**
254         * The ResourceFormat paramter is used to indicate the encoding used for the resource being
255         * harvested. This parameter is included to support the harvesting of metadata resources
256         * available in various formats such as plain text, XML or HTML. The values of this parameter
257         * must be a MIME type. If the parameter is not specified then the default value of text/xml
258         * should be assumed.
259         * 
260         * @return
261         */
262        public String getResourceFormat() {
263            return resourceFormat;
264        }
265    
266        /**
267         * The ResourceType parameter is a reference to a schema document that defines the structure of
268         * the resource being harvested. This is an optional parameter and if it not specified then the
269         * catalogue must employee other means to determine the type of resource being harvested. For
270         * example, the catalogue may use schema references in the input document to determine the
271         * resource type, or perhaps parse the root element to determine the type of metadata being
272         * harvested (e.g. &lt;fgdc:metadata&gt; is the root element of an FGDC document).
273         * 
274         * @return
275         */
276        public URI getResourceType() {
277            return resourceType;
278        }
279    
280        /**
281         * <p>
282         * The ResponseHandler parameter is a flag that indicates how the Harvest operation should be
283         * processed by a CSW server.
284         * </p>
285         * <p>
286         * If the parameter is not present, then the Harvest operation is processed synchronously
287         * meaning that the client sends the Harvest request to a CSW and then waits to receive a
288         * HarvestResponse or exception message. The CSW immediately processes the Harvest request,
289         * while the client waits for a response. The problem with this mode of operation is that the
290         * client may timeout waiting for the server to process the request.
291         * </p>
292         * If the parameter is present, the Harvest operation is processed asynchronously. In this case,
293         * the server responds immediately to a client’s request with an acknowledgement message. The
294         * acknowlegment message echos the client’s request, using the &lt;EchoedRequest&gt; element,
295         * and may include an optionally generated request identifier using the &lt;RequestId&gt;
296         * element. The acknowledgement message tells the client that the request has been received and
297         * notification of completion will be send to the URL specified as the value of the
298         * ResponseHandler parameter. The Harvest request may then be processed at some later time
299         * taking as much time as is required to complete the operation. When the operation is
300         * completed, a HarvestResponse message or exception message (if a problem was encountered) is
301         * sent to the URL specified as the value of the ResponseHandler parameter.
302         * 
303         * @return
304         */
305        public List<URI> getResponseHandler() {
306            return responseHandler;
307        }
308    
309        /**
310         * The Source parameter is used to specify a URI reference to the metadata resource to be
311         * harvested.
312         * 
313         * @return
314         */
315        public URI getSource() {
316            return source;
317        }
318    
319        /**
320         * returns the deegree specific timestamp when harvesting shall start. If <code>null</code> is
321         * returned harvesting shall start as soon as possible
322         * 
323         * @return
324         */
325        public Date getStartTimestamp() {
326            return startTimestamp;
327        }
328    
329        /**
330         * will always return 'CSW'
331         */
332        public String getServiceName() {
333            return "CSW";
334        }
335    
336    }