001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/framework/trigger/TriggerConfigurationDocument.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 package org.deegree.framework.trigger;
044
045 import java.io.File;
046 import java.io.IOException;
047 import java.net.MalformedURLException;
048 import java.net.URI;
049 import java.net.URISyntaxException;
050 import java.net.URL;
051 import java.util.ArrayList;
052 import java.util.Date;
053 import java.util.HashMap;
054 import java.util.List;
055 import java.util.Map;
056
057 import org.deegree.framework.log.ILogger;
058 import org.deegree.framework.log.LoggerFactory;
059 import org.deegree.framework.util.TimeTools;
060 import org.deegree.framework.xml.NamespaceContext;
061 import org.deegree.framework.xml.XMLFragment;
062 import org.deegree.framework.xml.XMLParsingException;
063 import org.deegree.framework.xml.XMLTools;
064 import org.deegree.i18n.Messages;
065 import org.w3c.dom.Element;
066 import org.w3c.dom.Node;
067 import org.xml.sax.SAXException;
068
069 /**
070 *
071 *
072 *
073 * @version $Revision: 9339 $
074 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
075 * @author last edited by: $Author: apoth $
076 *
077 * @version 1.0. $Revision: 9339 $, $Date: 2007-12-27 13:31:52 +0100 (Do, 27 Dez 2007) $
078 *
079 * @since 2.0
080 */
081 public class TriggerConfigurationDocument extends XMLFragment {
082
083 private ILogger LOG = LoggerFactory.getLogger( TriggerConfigurationDocument.class );
084
085 private static NamespaceContext nsc = new NamespaceContext();
086 static {
087 try {
088 nsc.addNamespace( "dgTr", new URI( "http://www.deegree.org/trigger" ) );
089 } catch ( URISyntaxException e ) {
090 // should never happen
091 e.printStackTrace();
092 }
093 }
094
095
096 /**
097 * default constructor
098 */
099 public TriggerConfigurationDocument() {
100
101 }
102
103 /**
104 * initialized the class by assigning a XML file
105 * @param file
106 * @throws IOException
107 * @throws SAXException
108 */
109 public TriggerConfigurationDocument( File file ) throws IOException, SAXException {
110 super( file.toURL() );
111 }
112
113 /**
114 *
115 * @return TriggerCapabilities
116 * @throws XMLParsingException
117 * @throws TriggerException
118 */
119 public TriggerCapabilities parseTriggerCapabilities()
120 throws XMLParsingException, TriggerException {
121
122 List list = XMLTools.getNodes( getRootElement(), "dgTr:class", nsc );
123 Map<String,TargetClass> targetClasses = new HashMap<String,TargetClass>( list.size() );
124 for ( int i = 0; i < list.size(); i++ ) {
125 TargetClass tc = parserTargetClass( (Element) list.get( i ) );
126 targetClasses.put( tc.getName(), tc );
127 }
128
129 return new TriggerCapabilities( targetClasses );
130 }
131
132 /**
133 *
134 * @param element
135 * @return TargetClass
136 * @throws XMLParsingException
137 * @throws TriggerException
138 */
139 private TargetClass parserTargetClass( Element element )
140 throws XMLParsingException, TriggerException {
141
142 String clName = XMLTools.getRequiredNodeAsString( element, "dgTr:name/text()", nsc );
143
144 List list = XMLTools.getNodes( element, "dgTr:method", nsc );
145 Map<String,TargetMethod> targetMethods = new HashMap<String,TargetMethod>( list.size() );
146 for ( int i = 0; i < list.size(); i++ ) {
147 TargetMethod tm = parseTargetMethod( (Element) list.get( i ) );
148 targetMethods.put( tm.getName(), tm );
149 }
150
151 return new TargetClass( clName, targetMethods );
152 }
153
154 /**
155 *
156 * @param element
157 * @return TargetMethod
158 * @throws XMLParsingException
159 * @throws TriggerException
160 */
161 private TargetMethod parseTargetMethod( Element element )
162 throws XMLParsingException, TriggerException {
163
164 String mName = XMLTools.getRequiredNodeAsString( element, "dgTr:name/text()", nsc );
165
166 TriggerCapability preTrigger = null;
167 TriggerCapability postTrigger = null;
168
169 //it is possible that no trigger is assigned to a method
170 // in this case the present of a method just indicates that
171 // it that Triggers can be assigned to it
172 Node node = XMLTools.getNode( element, "dgTr:preTrigger/dgTr:trigger", nsc );
173 if ( node != null ) {
174 preTrigger = parseTriggerCapability( (Element) node );
175 }
176 node = XMLTools.getNode( element, "dgTr:postTrigger/dgTr:trigger", nsc );
177 if ( node != null ) {
178 postTrigger = parseTriggerCapability( (Element) node );
179 }
180
181 return new TargetMethod( mName, preTrigger, postTrigger );
182 }
183
184 /**
185 *
186 * @param element
187 * @return trigger capability
188 * @throws XMLParsingException
189 * @throws TriggerException
190 */
191 private TriggerCapability parseTriggerCapability( Element element )
192 throws XMLParsingException, TriggerException {
193
194 if( LOG.getLevel() == ILogger.LOG_DEBUG ){
195 XMLFragment doc = new XMLFragment();
196 doc.setRootElement( element );
197 LOG.logDebug( "Incoming trigger configuration element:\n " + doc.getAsPrettyString() );
198 }
199 // a node (if not null) may represents a simple Trigger or a
200 // TriggerChain (which is a Trigger too)
201 String trName = XMLTools.getRequiredNodeAsString( element, "dgTr:name/text()", nsc );
202 String clName = XMLTools.getRequiredNodeAsString( element, "dgTr:performingClass/text()", nsc );
203 Class clss = null;
204 try {
205 clss = Class.forName( clName );
206 LOG.logDebug( "Found class: " + clss );
207 } catch ( ClassNotFoundException e ) {
208 LOG.logError( e.getMessage(), e );
209 throw new XMLParsingException( Messages.getMessage( "FRAMEWORK_UNKNOWN_TRIGGERCLASS",
210 clName ) );
211 }
212
213 if ( !Trigger.class.isAssignableFrom( clss ) ) {
214 // class read from the configuration must be an implementation
215 // of org.deegree.framework.trigger.Trigger
216 throw new TriggerException( Messages.getMessage( "FRAMEWORK_INVALID_TRIGGERCLASS",
217 clName ) );
218 }
219
220 Map<String, Class> paramTypes = new HashMap<String, Class>();
221 Map<String, Object> paramValues = new HashMap<String, Object>();
222 List<String> paramNames = new ArrayList<String>();
223 List initParams = XMLTools.getNodes( element, "dgTr:initParam", nsc );
224 parseInitParams( paramTypes, paramValues, paramNames, initParams );
225
226 // get nested Trigger capabilities if available
227 List nested = XMLTools.getNodes( element, "dgTr:trigger/dgTr:trigger", nsc );
228 List<TriggerCapability> nestedList = new ArrayList<TriggerCapability>( nested.size() );
229 for ( int i = 0; i < nested.size(); i++ ) {
230 nestedList.add( parseTriggerCapability( (Element)nested.get( i ) ) );
231 }
232
233 return new TriggerCapability( trName, clss, paramNames, paramTypes, paramValues, nestedList );
234
235 }
236
237 /**
238 *
239 * @param paramTypes
240 * @param paramValues
241 * @param paramNames
242 * @param initParams
243 * @throws XMLParsingException
244 */
245 private void parseInitParams( Map<String, Class> paramTypes, Map<String, Object> paramValues,
246 List<String> paramNames, List initParams )
247 throws XMLParsingException {
248 for ( int i = 0; i < initParams.size(); i++ ) {
249 String name = XMLTools.getRequiredNodeAsString( (Node)initParams.get( i ),
250 "dgTr:name/text()", nsc );
251 paramNames.add( name );
252 String tmp = XMLTools.getRequiredNodeAsString( (Node)initParams.get( i ),
253 "dgTr:type/text()", nsc );
254 Class cl = null;
255 try {
256 cl = Class.forName( tmp );
257 } catch ( ClassNotFoundException e ) {
258 LOG.logError( e.getMessage(), e );
259 throw new XMLParsingException( Messages.getMessage( "FRAMEWORK_UNKNOWN_INITPARAMCLASS",
260 tmp ) );
261 }
262 tmp = XMLTools.getRequiredNodeAsString( (Node)initParams.get( i ),
263 "dgTr:value/text()", nsc );
264 Object value = null;
265 try {
266 value = getValue( cl, tmp );
267 } catch ( MalformedURLException e ) {
268 LOG.logError( e.getMessage(), e );
269 throw new XMLParsingException( Messages.getMessage( "FRAMEWORK_TRIGGER_INITPARAM_PARSING",
270 tmp, cl.getName() ) );
271 }
272 paramTypes.put( name, cl );
273 paramValues.put( name, value );
274 }
275 }
276
277 /**
278 *
279 * @param type
280 * @param tmp
281 * @return parameter value
282 * @throws MalformedURLException
283 */
284 private Object getValue( Class type, String tmp ) throws MalformedURLException {
285 Object value = null;
286 if ( type.equals( Integer.class ) ) {
287 value = Integer.parseInt( tmp );
288 } else if ( type.equals( Double.class ) ) {
289 value = Double.parseDouble( tmp );
290 } else if ( type.equals( Float.class ) ) {
291 value = Float.parseFloat( tmp );
292 } else if ( type.equals( URL.class ) ) {
293 value = new URL( tmp );
294 } else if ( type.equals( Date.class ) ) {
295 value = TimeTools.createCalendar( tmp ).getTime();
296 } else if ( type.equals( String.class ) ) {
297 value = tmp;
298 }
299 return value;
300 }
301
302 }