001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/wps/configuration/WPSConfiguration.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/exse/
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     Aennchenstraße 19
030     53177 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     * asdfasd
045     */
046    package org.deegree.ogcwebservices.wps.configuration;
047    
048    import java.io.File;
049    import java.io.IOException;
050    import java.lang.reflect.Constructor;
051    import java.lang.reflect.InvocationTargetException;
052    import java.net.URL;
053    import java.util.ArrayList;
054    import java.util.HashMap;
055    import java.util.Iterator;
056    import java.util.List;
057    import java.util.Map;
058    
059    import org.deegree.framework.log.ILogger;
060    import org.deegree.framework.log.LoggerFactory;
061    import org.deegree.framework.util.ConvenienceFileFilter;
062    import org.deegree.framework.xml.InvalidConfigurationException;
063    import org.deegree.framework.xml.XMLParsingException;
064    import org.deegree.ogcwebservices.getcapabilities.Contents;
065    import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException;
066    import org.deegree.ogcwebservices.getcapabilities.OperationsMetadata;
067    import org.deegree.ogcwebservices.getcapabilities.ServiceIdentification;
068    import org.deegree.ogcwebservices.getcapabilities.ServiceProvider;
069    import org.deegree.ogcwebservices.wps.ProcessBrief;
070    import org.deegree.ogcwebservices.wps.capabilities.ProcessOfferings;
071    import org.deegree.ogcwebservices.wps.capabilities.WPSCapabilities;
072    import org.deegree.ogcwebservices.wps.describeprocess.ProcessDescription;
073    import org.deegree.ogcwebservices.wps.describeprocess.ProcessDescriptionDocument;
074    import org.deegree.ogcwebservices.wps.execute.Process;
075    import org.xml.sax.SAXException;
076    
077    /**
078     * WPSConfiguration.java
079     * 
080     * Created on 08.03.2006. 17:58:55h
081     * 
082     * @author <a href="mailto:christian@kiehle.org">Christian Kiehle</a>
083     * @author <a href="mailto:christian.heier@gmx.de">Christian Heier</a>
084     * @version 1.0.
085     * @since 2.0
086     */
087    public class WPSConfiguration extends WPSCapabilities {
088    
089        private static final ILogger LOG = LoggerFactory.getLogger( WPSConfiguration.class );
090    
091        private WPSDeegreeParams deegreeParams = null;
092    
093        private Map<String, Process> registeredProcesses;
094    
095        private static final String SPEC_PROC_DIR = "Specified process directory '";
096    
097        /**
098         * Constructor initializes WPSConfiguration from passed parameters
099         * 
100         * @param version
101         * @param updateSequence
102         * @param serviceIdentification
103         * @param serviceProvider
104         * @param operationsMetadata
105         * @param contents
106         * @throws InvalidConfigurationException
107         */
108        protected WPSConfiguration( String version, String updateSequence, ServiceIdentification serviceIdentification,
109                                    ServiceProvider serviceProvider, OperationsMetadata operationsMetadata,
110                                    Contents contents, WPSDeegreeParams wpsDeegreeParams )
111                                throws InvalidConfigurationException {
112            super( version, updateSequence, serviceIdentification, serviceProvider, operationsMetadata, contents );
113            this.deegreeParams = wpsDeegreeParams;
114            try {
115                loadProcessConfigs();
116                setConfiguredProcessOfferings();
117            } catch ( InvalidConfigurationException e ) {
118                LOG.logError( e.getMessage(), e );
119                throw e;
120            }
121        }
122    
123        private void setConfiguredProcessOfferings() {
124    
125            List<ProcessBrief> processBriefList = new ArrayList<ProcessBrief>();
126    
127            Iterator<Process> registeredProcessesValuesIterator = registeredProcesses.values().iterator();
128    
129            while ( registeredProcessesValuesIterator.hasNext() ) {
130                Process process = registeredProcessesValuesIterator.next();
131    
132                ProcessDescription processDescription = process.getProcessDescription();
133    
134                processBriefList.add( new ProcessBrief( processDescription.getIdentifier(), processDescription.getTitle(),
135                                                        processDescription.getAbstract(),
136                                                        processDescription.getProcessVersion(),
137                                                        processDescription.getMetadata() ) );
138            }
139    
140            ProcessOfferings processOfferings = new ProcessOfferings( processBriefList );
141    
142            super.setProcessOfferings( processOfferings );
143        }
144    
145        /**
146         * @return Returns the registeredProcesses.
147         */
148        public Map<String, Process> getRegisteredProcesses() {
149            return registeredProcesses;
150        }
151    
152        /**
153         * loads and initializes processes configured in the process directory.
154         * 
155         * @throws InvalidConfigurationException
156         */
157        private void loadProcessConfigs()
158                                throws InvalidConfigurationException {
159            this.registeredProcesses = scanForRegisteredProcesses();
160    
161        }
162    
163        /**
164         * Scans for process configuration documents located in process directory of current WPS
165         * configuration.
166         * 
167         * @return Map<String, Process>
168         * @throws InvalidConfigurationException
169         */
170        private Map<String, Process> scanForRegisteredProcesses()
171                                throws InvalidConfigurationException {
172            List<String> fileNameList = new ArrayList<String>();
173            String[] processDirectories = getDeegreeParams().getProcessDirectories();
174    
175            for ( int i = 0; i < processDirectories.length; i++ ) {
176                File file = new File( processDirectories[i] );
177                LOG.logInfo( "Directory '" + file.getAbsolutePath() + "' will be scanned for process configuration files." );
178                String[] list = file.list( new ConvenienceFileFilter( false, "XML" ) );
179                if ( list != null ) {
180                    if ( list.length == 0 ) {
181                        String msg = SPEC_PROC_DIR + processDirectories[i] + "' does not contain any '.xml' files.";
182                        LOG.logError( msg );
183                        throw new InvalidConfigurationException( msg );
184                    }
185                    for ( int j = 0; j < list.length; j++ ) {
186                        fileNameList.add( processDirectories[i] + '/' + list[j] );
187                    }
188                } else {
189                    String msg = SPEC_PROC_DIR + processDirectories[i] + "' does not denote a directory.";
190                    LOG.logError( msg );
191                    throw new InvalidConfigurationException( msg );
192                }
193            }
194            String[] fileNames = fileNameList.toArray( new String[fileNameList.size()] );
195            return extractProcessDescriptions( fileNames );
196        }
197    
198        /**
199         * Extracts a <code>ProcessDescription</code> for each provided files in <code>String[]</code>
200         * fileNames.
201         * 
202         * @param fileNames
203         * @return
204         * @throws InvalidConfigurationException
205         */
206        private Map<String, Process> extractProcessDescriptions( String[] fileNames )
207                                throws InvalidConfigurationException {
208            int size = fileNames.length;
209            Map<String, Process> processMap = new HashMap<String, Process>( size );
210            for ( int i = 0; i < size; i++ ) {
211                LOG.logInfo( "Parsing process configuration file: '" + fileNames[i] + "'." );
212                Process process = null;
213                try {
214                    URL fileURL = new File( fileNames[i] ).toURL();
215                    ProcessDescriptionDocument processDescriptionDocument = new ProcessDescriptionDocument();
216                    processDescriptionDocument.load( fileURL );
217                    ProcessDescription processDescription = processDescriptionDocument.parseProcessDescription();
218    
219                    String className = processDescription.getResponsibleClass();
220                    try {
221                        Class processClass = Class.forName( className );
222                        Constructor con = processClass.getConstructor( ProcessDescription.class );
223                        process = (Process) con.newInstance( processDescription );
224                    } catch ( ClassNotFoundException cnfEx ) {
225                        String msg = "Responsible class for process execution: '" + className + "' not found.";
226                        LOG.logError( msg, cnfEx );
227                        throw new XMLParsingException( msg, cnfEx );
228                    } catch ( NoSuchMethodException nsmEx ) {
229                        String msg = "Responsible class for process execution: '" + className
230                                     + "' can not be instantiated.";
231                        LOG.logError( msg, nsmEx );
232                        throw new XMLParsingException( msg, nsmEx );
233                    } catch ( InstantiationException iEx ) {
234                        String msg = "Responsible class for process execution: '" + className
235                                     + "' can not be instantiated.";
236                        LOG.logError( msg, iEx );
237                        throw new XMLParsingException( msg, iEx );
238                    } catch ( InvocationTargetException itEx ) {
239                        String msg = "Responsible class for process execution: '" + className
240                                     + "' can not be instantiated.";
241                        LOG.logError( msg, itEx );
242                        throw new XMLParsingException( msg, itEx );
243                    } catch ( IllegalAccessException iaEx ) {
244                        String msg = "Responsible class for process execution: '" + className
245                                     + "' can not be instantiated.";
246                        LOG.logError( msg, iaEx );
247                        throw new XMLParsingException( msg, iaEx );
248                    }
249    
250                    String processKey = processDescription.getIdentifier().getCode().toUpperCase();
251                    if ( !processMap.containsKey( processKey ) ) {
252                        processMap.put( processKey, process );
253                        LOG.logDebug( "Process '" + processKey + "' registered to server." );
254                    } else {
255                        String msg = "Multiple definition of process '" + processKey + "' not allowed! Process '"
256                                     + processKey + "' is already defined.";
257                        LOG.logError( msg );
258                        throw new InvalidConfigurationException( msg );
259                    }
260    
261                } catch ( IOException ioe ) {
262                    String msg = "Error loading '" + fileNames[i] + "': " + ioe.getMessage();
263                    LOG.logError( msg );
264                    throw new InvalidConfigurationException( msg, ioe );
265                } catch ( Exception e ) {
266                    String msg = "Error parsing '" + fileNames[i] + "': " + e.getMessage();
267                    LOG.logError( msg );
268                    throw new InvalidConfigurationException( msg, e );
269                }
270            }
271    
272            return processMap;
273        }
274    
275        /**
276         * @return Returns the deegreeParams.
277         */
278        public WPSDeegreeParams getDeegreeParams() {
279            return deegreeParams;
280        }
281    
282        /**
283         * @param deegreeParams
284         *            The deegreeParams to set.
285         */
286        public void setDeegreeParams( WPSDeegreeParams deegreeParams ) {
287            this.deegreeParams = deegreeParams;
288        }
289    
290        /**
291         * 
292         * @param url
293         * @return
294         * @throws IOException
295         * @throws SAXException
296         * @throws InvalidCapabilitiesException
297         * @throws InvalidConfigurationException
298         */
299        public static WPSConfiguration createConfiguration( URL url )
300                                throws IOException, SAXException, InvalidConfigurationException {
301            WPSConfigurationDocument confDoc = new WPSConfigurationDocument();
302            confDoc.load( url );
303            WPSConfiguration configuration = confDoc.getConfiguration();
304    
305            return configuration;
306        }
307    
308    }