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 }