001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/framework/trigger/TriggerProvider.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.framework.trigger; 037 038 import java.lang.reflect.Constructor; 039 import java.net.URL; 040 import java.util.ArrayList; 041 import java.util.HashMap; 042 import java.util.List; 043 import java.util.Map; 044 045 import org.deegree.framework.log.ILogger; 046 import org.deegree.framework.log.LoggerFactory; 047 import org.deegree.framework.trigger.TriggerCapabilities.TRIGGER_TYPE; 048 import org.deegree.framework.util.BootLogger; 049 import org.deegree.i18n.Messages; 050 051 /** 052 * 053 * 054 * 055 * @version $Revision: 18195 $ 056 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 057 * @author last edited by: $Author: mschneider $ 058 * 059 * @version 1.0. $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $ 060 * 061 * @since 2.0 062 */ 063 public class TriggerProvider { 064 065 private static Map<String, TriggerProvider> providerMap = new HashMap<String, TriggerProvider>(); 066 067 private static TriggerCapabilities triggerCapabilities; 068 069 private static final ILogger LOG = LoggerFactory.getLogger( TriggerProvider.class ); 070 071 static { 072 try { 073 URL url = TriggerProvider.class.getResource( "triggerConfiguration.xml" ); 074 TriggerConfigurationDocument doc = new TriggerConfigurationDocument(); 075 doc.load( url ); 076 triggerCapabilities = doc.parseTriggerCapabilities(); 077 // try reading trigger definitions from root that may overrides 078 // default trigger 079 url = TriggerProvider.class.getResource( "/triggerConfiguration.xml" ); 080 try { 081 082 if ( url != null ) { 083 LOG.logDebug( "Trying to create trigger from local configuration: " + url ); 084 doc = new TriggerConfigurationDocument(); 085 doc.load( url ); 086 TriggerCapabilities temp = doc.parseTriggerCapabilities(); 087 triggerCapabilities.merge( temp ); 088 } else { 089 LOG.logDebug( "No local configuration found." ); 090 } 091 092 } catch ( Exception e ) { 093 e.printStackTrace(); 094 BootLogger.log( "!!! BOOTLOG: No valid trigger configuration available from root." ); 095 } 096 } catch ( Exception e ) { 097 e.printStackTrace(); 098 } 099 } 100 101 private String className = null; 102 103 private TriggerProvider( String className ) { 104 this.className = className; 105 } 106 107 /** 108 * 109 * @param clss 110 */ 111 public static TriggerProvider create( Class clss ) { 112 String s = clss.getName(); 113 if ( providerMap.get( s ) == null ) { 114 providerMap.put( s, new TriggerProvider( s ) ); 115 } 116 return providerMap.get( s ); 117 } 118 119 /** 120 * @return all pre triggers assigend to the calling method 121 */ 122 public List<Trigger> getPreTrigger() 123 throws TriggerException { 124 125 List<Trigger> trigger = new ArrayList<Trigger>(); 126 127 StackTraceElement[] st = Thread.currentThread().getStackTrace(); 128 129 String mn = null; 130 for ( int i = 0; i < st.length; i++ ) { 131 if ( st[i].getClassName().equals( className ) ) { 132 mn = st[i].getMethodName(); 133 break; 134 } 135 } 136 if ( mn != null ) { 137 TriggerCapability tc = triggerCapabilities.getTriggerCapability( className, mn, TRIGGER_TYPE.PRE ); 138 if ( tc != null ) { 139 appendTrigger( trigger, tc ); 140 141 List<TriggerCapability> tCaps = tc.getTrigger(); 142 for ( int i = 0; i < tCaps.size(); i++ ) { 143 appendTrigger( trigger, tCaps.get( i ) ); 144 } 145 } 146 } 147 148 return trigger; 149 } 150 151 /** 152 * returns all post triggers assigend to the calling method 153 * 154 * @return all post triggers assigend to the calling method 155 */ 156 public List<Trigger> getPostTrigger() 157 throws TriggerException { 158 List<Trigger> trigger = new ArrayList<Trigger>(); 159 160 StackTraceElement[] st = Thread.currentThread().getStackTrace(); 161 String mn = null; 162 for ( int i = 0; i < st.length; i++ ) { 163 if ( st[i].getClassName().equals( className ) ) { 164 mn = st[i].getMethodName(); 165 break; 166 } 167 } 168 169 if ( mn != null ) { 170 TriggerCapability tc = triggerCapabilities.getTriggerCapability( className, mn, TRIGGER_TYPE.POST ); 171 172 if ( tc != null ) { 173 appendTrigger( trigger, tc ); 174 175 List<TriggerCapability> tCaps = tc.getTrigger(); 176 for ( int i = 0; i < tCaps.size(); i++ ) { 177 appendTrigger( trigger, tCaps.get( i ) ); 178 } 179 } 180 } 181 return trigger; 182 } 183 184 /** 185 * creates a Trigger instance from the passed TriggerCapability and add it to the passed list. 186 * If the TriggerCapability contains futher TriggerCapability entries they will also be added 187 * within a recursion 188 * 189 * @param trigger 190 * @param tc 191 * @return extended list 192 * @throws TriggerException 193 */ 194 private List<Trigger> appendTrigger( List<Trigger> trigger, TriggerCapability tc ) 195 throws TriggerException { 196 Class clss = tc.getPerformingClass(); 197 List<String> paramNames = tc.getInitParameterNames(); 198 Class[] initClasses = new Class[paramNames.size()]; 199 Object[] paramVals = new Object[paramNames.size()]; 200 for ( int i = 0; i < initClasses.length; i++ ) { 201 paramVals[i] = tc.getInitParameterValue( paramNames.get( i ) ); 202 initClasses[i] = paramVals[i].getClass(); 203 } 204 try { 205 Constructor cstrtr = clss.getConstructor( initClasses ); 206 LOG.logDebug( "Trying to instantiate new class" ); 207 trigger.add( (Trigger) cstrtr.newInstance( paramVals ) ); 208 LOG.logDebug( "Succesfully instantiated configured trigger class." ); 209 } catch ( Exception e ) { 210 e.printStackTrace(); 211 throw new TriggerException( Messages.getMessage( "FRAMEWORK_ERROR_INITIALIZING_TRIGGER", clss ) ); 212 } 213 return trigger; 214 } 215 216 /** 217 * performs pre triggers assigend to the calling method 218 * 219 * @param caller 220 * @param obj 221 * @return changed object passed to the trigger(s) 222 * @throws TriggerException 223 */ 224 public Object[] doPreTrigger( Object caller, Object... obj ) 225 throws TriggerException { 226 List<Trigger> list = getPreTrigger(); 227 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { 228 LOG.logDebug( "list of appliable pretriggers: " + list ); 229 } 230 for ( int i = 0; i < list.size(); i++ ) { 231 obj = list.get( i ).doTrigger( caller, obj ); 232 } 233 return obj; 234 } 235 236 /** 237 * performs post triggers assigend to the calling method 238 * 239 * @param caller 240 * @param obj 241 * @return changed object passed to the trigger(s) 242 */ 243 public Object[] doPostTrigger( Object caller, Object... obj ) { 244 List<Trigger> list = getPostTrigger(); 245 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { 246 LOG.logDebug( "list of appliable posttriggers: " + list ); 247 } 248 for ( int i = 0; i < list.size(); i++ ) { 249 obj = list.get( i ).doTrigger( caller, obj ); 250 } 251 return obj; 252 } 253 254 /** 255 * returns the root capabilities 256 * 257 * @return the root capabilities 258 */ 259 public TriggerCapabilities getCapabilities() { 260 return triggerCapabilities; 261 } 262 263 }