001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_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 }