001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/framework/trigger/TriggerProvider.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001-2007 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.lang.reflect.Constructor;
046    import java.net.URL;
047    import java.util.ArrayList;
048    import java.util.HashMap;
049    import java.util.List;
050    import java.util.Map;
051    
052    import org.deegree.framework.trigger.TriggerCapabilities.TRIGGER_TYPE;
053    import org.deegree.framework.util.BootLogger;
054    import org.deegree.i18n.Messages;
055    
056    /**
057     * 
058     * 
059     * 
060     * @version $Revision: 7095 $
061     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
062     * @author last edited by: $Author: apoth $
063     * 
064     * @version 1.0. $Revision: 7095 $, $Date: 2007-05-10 20:07:43 +0200 (Do, 10 Mai 2007) $
065     * 
066     * @since 2.0
067     */
068    public class TriggerProvider {
069    
070        private static Map<String, TriggerProvider> providerMap = new HashMap<String, TriggerProvider>();
071    
072        private static TriggerCapabilities triggerCapabilities;
073    
074        static {
075            try {
076                URL url = TriggerProvider.class.getResource( "triggerConfiguration.xml" );
077                TriggerConfigurationDocument doc = new TriggerConfigurationDocument();
078                doc.load( url );
079                triggerCapabilities = doc.parseTriggerCapabilities();
080                // try reading trigger definitions from root that may overrides
081                // default trigger
082                url = TriggerProvider.class.getResource( "/triggerConfiguration.xml" );
083                try {
084                    if ( url != null ) {
085                        doc = new TriggerConfigurationDocument();
086                        doc.load( url );
087                        TriggerCapabilities temp = doc.parseTriggerCapabilities();
088                        triggerCapabilities.merge( temp );
089                    }
090                } catch ( Exception e ) {
091                    BootLogger.log( "!!! BOOTLOG: No valid trigger configuration available from root." );
092                }
093            } catch ( Exception e ) {
094                e.printStackTrace();
095            }
096        }
097    
098        private String className = null;
099    
100        private TriggerProvider( String className ) {
101            this.className = className;
102        }
103    
104        /**
105         * 
106         * @param clss
107         */
108        public static TriggerProvider create( Class clss ) {
109            String s = clss.getName();
110            if ( providerMap.get( s ) == null ) {
111                providerMap.put( s, new TriggerProvider( s ) );
112            }
113            return providerMap.get( s );
114        }
115    
116        /**
117         * @return all pre triggers assigend to the calling method
118         */
119        public List<Trigger> getPreTrigger()
120                                throws TriggerException {
121    
122            List<Trigger> trigger = new ArrayList<Trigger>();
123    
124            StackTraceElement[] st = Thread.currentThread().getStackTrace();
125            TriggerCapability tc = triggerCapabilities.getTriggerCapability( className, st[4].getMethodName(),
126                                                                             TRIGGER_TYPE.PRE );
127            if ( tc != null ) {
128                appendTrigger( trigger, tc );
129    
130                List<TriggerCapability> tCaps = tc.getTrigger();
131                for ( int i = 0; i < tCaps.size(); i++ ) {
132                    appendTrigger( trigger, tCaps.get( i ) );
133                }
134            }
135    
136            return trigger;
137        }
138    
139        /**
140         * returns all post triggers assigend to the calling method
141         * @return all post triggers assigend to the calling method
142         */
143        public List<Trigger> getPostTrigger()
144                                throws TriggerException {
145            List<Trigger> trigger = new ArrayList<Trigger>();
146    
147            StackTraceElement[] st = Thread.currentThread().getStackTrace();
148            TriggerCapability tc = triggerCapabilities.getTriggerCapability( className, st[4].getMethodName(),
149                                                                             TRIGGER_TYPE.POST );
150    
151            if ( tc != null ) {
152                appendTrigger( trigger, tc );
153    
154                List<TriggerCapability> tCaps = tc.getTrigger();
155                for ( int i = 0; i < tCaps.size(); i++ ) {
156                    appendTrigger( trigger, tCaps.get( i ) );
157                }
158            }
159    
160            return trigger;
161        }
162    
163        /**
164         * creates a Trigger instance from the passed TriggerCapability and add it to the passed list.
165         * If the TriggerCapability contains futher TriggerCapability entries they will also be added
166         * within a recursion
167         * 
168         * @param trigger
169         * @param tc
170         * @return extended list
171         * @throws TriggerException
172         */
173        private List<Trigger> appendTrigger( List<Trigger> trigger, TriggerCapability tc )
174                                throws TriggerException {
175            Class clss = tc.getPerformingClass();
176            List<String> paramNames = tc.getInitParameterNames();
177            Class[] initClasses = new Class[paramNames.size()];
178            Object[] paramVals = new Object[paramNames.size()];
179            for ( int i = 0; i < initClasses.length; i++ ) {
180                paramVals[i] = tc.getInitParameterValue( paramNames.get( i ) );
181                initClasses[i] = paramVals[i].getClass();
182            }
183            try {
184                Constructor cstrtr = clss.getConstructor( initClasses );
185                trigger.add( (Trigger) cstrtr.newInstance( paramVals ) );
186            } catch ( Exception e ) {
187                e.printStackTrace();
188                throw new TriggerException( Messages.getMessage( "FRAMEWORK_ERROR_INITIALIZING_TRIGGER", clss ) );
189            }
190            return trigger;
191        }
192    
193        /**
194         * performs pre triggers assigend to the calling method
195         * 
196         * @param caller
197         * @param obj
198         * @return changed object passed to the trigger(s)
199         * @throws TriggerException
200         */
201        public Object[] doPreTrigger( Object caller, Object... obj )
202                                throws TriggerException {
203            List<Trigger> list = getPreTrigger();
204            for ( int i = 0; i < list.size(); i++ ) {
205                obj = list.get( i ).doTrigger( caller, obj );
206            }
207            return obj;
208        }
209    
210        /**
211         * performs post triggers assigend to the calling method
212         * 
213         * @param caller
214         * @param obj
215         * @return changed object passed to the trigger(s)
216         */
217        public Object[] doPostTrigger( Object caller, Object... obj ) {
218            List<Trigger> list = getPostTrigger();
219            for ( int i = 0; i < list.size(); i++ ) {
220                obj = list.get( i ).doTrigger( caller, obj );
221            }
222            return obj;
223        }
224    
225        /**
226         * returns the root capabilities
227         * 
228         * @return the root capabilities
229         */
230        public TriggerCapabilities getCapabilities() {
231            return triggerCapabilities;
232        }
233    
234    }