You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by we...@apache.org on 2012/03/14 16:46:07 UTC

svn commit: r1300598 [2/10] - in /myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src: main/java/org/apache/myfaces/extensions/scripting/core/api/ main/java/org/apache/myfaces/extensions/scripting/core/common/ main/java/org/apache...

Added: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/api/WeavingContext.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/api/WeavingContext.java?rev=1300598&view=auto
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/api/WeavingContext.java (added)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/api/WeavingContext.java Wed Mar 14 15:46:00 2012
@@ -0,0 +1,646 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.extensions.scripting.core.api;
+
+import org.apache.myfaces.extensions.scripting.core.common.util.ClassUtils;
+import org.apache.myfaces.extensions.scripting.core.common.util.ReflectUtil;
+import org.apache.myfaces.extensions.scripting.core.engine.FactoryEngines;
+import org.apache.myfaces.extensions.scripting.core.engine.api.ClassScanner;
+import org.apache.myfaces.extensions.scripting.core.engine.api.CompilationResult;
+import org.apache.myfaces.extensions.scripting.core.engine.api.ScriptingEngine;
+import org.apache.myfaces.extensions.scripting.core.loader.ThrowAwayClassloader;
+import org.apache.myfaces.extensions.scripting.core.monitor.ClassResource;
+import org.apache.myfaces.extensions.scripting.core.monitor.WatchedResource;
+import org.apache.myfaces.extensions.scripting.core.reloading.GlobalReloadingStrategy;
+import org.apache.myfaces.extensions.scripting.core.reloading.MethodLevelReloadingHandler;
+import org.apache.myfaces.extensions.scripting.jsf.adapters.MyFacesSPI;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.logging.Logger;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ *          <p/>
+ *          Central weaving context
+ */
+
+public class WeavingContext
+{
+    static final Logger log = Logger.getLogger(WeavingContext.class.getName());
+
+    /**
+     * lock var which can be used for recompilation
+     */
+    public AtomicBoolean recompileLock = new AtomicBoolean(false);
+    /**
+     * configuration which stores all external configuration entries
+     */
+    protected Configuration configuration = new Configuration();
+
+    //ClassDependencies _dependencyMap = new ClassDependencies();
+    /**
+     * Service provider for the implementation under which this extension
+     * runs
+     */
+    ImplementationSPI _implementation = null;
+    /**
+     * the collection of reloading strategies depending on their artifact type
+     */
+    GlobalReloadingStrategy _reloadingStrategy = new GlobalReloadingStrategy();
+    /**
+     * the annotation scanning reference
+     */
+    ClassScanner _annotationScanner = null;
+
+    /**
+     * true only if the startup has performed without errors
+     */
+    boolean _scriptingEnabled = true;
+
+    /**
+     * holder for various operations within our lifecycle
+     */
+    ConcurrentHashMap<String, Long> lifecycleRegistry = new ConcurrentHashMap<String, Long>();
+
+    /**
+     * This is a log which keeps track of the taints
+     * over time, we need that mostly for bean refreshes
+     * in multiuser surroundings, because only tainted beans need
+     * to be refreshed.
+     * Now if a user misses multiple updates he has to get a full
+     * set of changed classes to be able to drop all personal scoped beans tainted
+     * since the he refreshed last! Hence we have to move away from our
+     * two dimensional &lt;class, taint&gt; to a three dimensional &lt;class, taint, time&gt;
+     * view of things
+     */
+    private List<TaintingHistoryEntry> _taintLog = Collections.synchronizedList(new LinkedList<TaintingHistoryEntry>());
+
+    /**
+     * compilation results holder for the compiler listeners (components etc...)
+     */
+    private static final Map<Integer, CompilationResult> _compilationResults = new ConcurrentHashMap<Integer, CompilationResult>();
+
+    /**
+     * we keep a 10 minutes timeout period to keep the performance in place
+     */
+    private final long TAINT_HISTORY_TIMEOUT = 10 * 60 * 1000;
+
+    /**
+     * internal class used by our own history log
+     */
+    static class TaintingHistoryEntry
+    {
+        long _timestamp;
+        ClassResource _data;
+
+        public TaintingHistoryEntry(ClassResource data)
+        {
+            _data = data;
+            _timestamp = System.currentTimeMillis();
+        }
+
+        public long getTimestamp()
+        {
+            return _timestamp;
+        }
+
+        public ClassResource getData()
+        {
+            return _data;
+        }
+    }
+
+    public void initEngines() throws IOException
+    {
+        FactoryEngines.getInstance().init();
+        initScanner();
+    }
+
+    public void initScanner()
+    {
+        try
+        {
+            Class scanner = ClassUtils.getContextClassLoader().loadClass("org.apache.myfaces.extensions.scripting.jsf.annotation.GenericAnnotationScanner");
+            this._annotationScanner = (ClassScanner) ReflectUtil.instantiate(scanner);
+
+        }
+        catch (ClassNotFoundException e)
+        {
+            //we do nothing here
+            //generic annotation scanner can be missing in jsf 1.2 environments
+            //_logger.log(Level.FINER, "", e);
+        }
+    }
+
+    public Collection<ScriptingEngine> getEngines()
+    {
+        return FactoryEngines.getInstance().getEngines();
+    }
+
+    public ScriptingEngine getEngine(int engineType)
+    {
+        return FactoryEngines.getInstance().getEngine(engineType);
+    }
+
+    /**
+     * returns the mitable watche resource maps for the various engines
+     *
+     * @return
+     */
+    public Map<Integer, Map<String, ClassResource>> getWatchedResources()
+    {
+        Map<Integer, Map<String, ClassResource>> ret = new HashMap<Integer, Map<String, ClassResource>>();
+        for (ScriptingEngine engine : getEngines())
+        {
+            ret.put(engine.getEngineType(), engine.getWatchedResources());
+        }
+        return ret;
+    }
+
+    /**
+     * @return a map of all watched resources over all engines
+     */
+    public Map<String, ClassResource> getAllWatchedResources()
+    {
+        Map<String, ClassResource> ret = new HashMap<String, ClassResource>();
+        for (ScriptingEngine engine : getEngines())
+        {
+            Map<String, ClassResource> watchedResourceMap = engine.getWatchedResources();
+            for (Map.Entry<String, ClassResource> entry : watchedResourceMap.entrySet())
+            {
+                ret.put(entry.getKey(), entry.getValue());
+            }
+        }
+        return ret;
+    }
+
+    /**
+     * @param key the watched resource classname
+     * @return the watched resource from the given key or null
+     */
+    public ClassResource getWatchedResource(String key)
+    {
+        for (ScriptingEngine engine : getEngines())
+        {
+            if (!engine.getWatchedResources().containsKey(key)) continue;
+            return engine.getWatchedResources().get(key);
+        }
+        return null;
+    }
+
+    public Collection<ClassResource> getTaintedClasses(int scriptingEngine) {
+            Map<String, ClassResource> watchedResources = getEngine(scriptingEngine).getWatchedResources();
+            List<ClassResource> res = new LinkedList<ClassResource>();
+            for(Map.Entry<String, ClassResource> entry: watchedResources.entrySet()) {
+                if(entry.getValue().isTainted()) {
+                    res.add(entry.getValue());
+                }
+            }
+            return res;
+        }
+
+
+    public Collection<ClassResource> getTaintedClasses() {
+        Map<String, ClassResource> watchedResources = getAllWatchedResources();
+        List<ClassResource> res = new LinkedList<ClassResource>();
+        for(Map.Entry<String, ClassResource> entry: watchedResources.entrySet()) {
+            if(entry.getValue().isTainted()) {
+                res.add(entry.getValue());
+            }
+        }
+        return res;
+    }
+    
+    /**
+     * checks if a resource idenified by key is tainted
+     *
+     * @param key the identifier for the resource
+     * @return true in case of being tainted
+     */
+    public boolean isTainted(String key)
+    {
+        ClassResource res = getWatchedResource(key);
+        if (res == null) return false;
+        return res.isTainted();
+    }
+
+    public Set<String> loadPossibleDynamicClasses()
+    {
+        return getAllWatchedResources().keySet();
+    }
+
+    public Configuration getConfiguration()
+    {
+        return configuration;
+    }
+
+    public void setConfiguration(Configuration configuration)
+    {
+        this.configuration = configuration;
+    }
+
+    public boolean needsRecompile()
+    {
+        for (ScriptingEngine engine : getEngines())
+        {
+            //log.info("[EXT-SCRIPTING] scanning " + engine.getEngineType() + " files");
+            if (engine.needsRecompile()) return true;
+            //log.info("[EXT-SCRIPTING] scanning " + engine.getEngineType() + " files done");
+        }
+        return false;
+    }
+
+    public void initialFullScan()
+    {
+        for (ScriptingEngine engine : getEngines())
+        {
+            engine.scanForAddedDeleted();
+        }
+        //the scanner scans only the tainted classes
+        //hence this should work whatever happens
+
+    }
+
+    public void annotationScan()
+    {
+        if (_annotationScanner != null)
+            _annotationScanner.scanPaths();
+    }
+
+    public boolean compile()
+    {
+        boolean compile = false;
+        for (ScriptingEngine engine : getEngines())
+        {
+            if (!engine.needsRecompile()) continue;
+            compile = true;
+            log.info("[EXT-SCRIPTING] compiling " + engine.getEngineTypeAsStr() + " files");
+            CompilationResult result = engine.compile();
+            if(result != null) {
+                WeavingContext.getInstance().setCompilationResult(engine.getEngineType(), result);
+            }
+            
+            log.info("[EXT-SCRIPTING] compiling " + engine.getEngineTypeAsStr() + " files done");
+        }
+        return compile;
+    }
+
+    public void scanDependencies()
+    {
+        for (ScriptingEngine engine : getEngines())
+        {
+            if (engine.isTainted())
+            {
+                log.info("[EXT-SCRIPTING] scanning " + engine.getEngineTypeAsStr() + " dependencies");
+                engine.scanDependencies();
+                log.info("[EXT-SCRIPTING] scanning " + engine.getEngineTypeAsStr() + " dependencies end");
+            }
+        }
+    }
+
+    public void markTaintedDependends()
+    {
+        for (ScriptingEngine engine : getEngines())
+        {
+            engine.markTaintedDependencies();
+        }
+    }
+
+    public WatchedResource getResource(String className)
+    {
+        WatchedResource ret = null;
+        for (ScriptingEngine engine : getEngines())
+        {
+            ret = engine.getWatchedResources().get(className);
+            if (ret != null) return ret;
+        }
+        return ret;
+    }
+
+    public boolean isDynamic(Class clazz)
+    {
+        return clazz.getClassLoader() instanceof ThrowAwayClassloader;
+    }
+
+    /**
+     * we create a proxy to an existing object
+     * which does reloading of the internal class
+     * on method level
+     * <p/>
+     * this works only on classes which implement contractual interfaces
+     * it cannot work on things like the navigation handler
+     * which rely on base classes
+     *
+     * @param o            the source object to be proxied
+     * @param theInterface the proxying interface
+     * @param artifactType the artifact type to be reloaded
+     * @return a proxied reloading object of type theInterface
+     */
+    public Object createMethodReloadingProxyFromObject(Object o, Class theInterface, int artifactType)
+    {
+        //if (!isScriptingEnabled()) {
+        //    return o;
+        //}
+        return Proxy.newProxyInstance(o.getClass().getClassLoader(),
+                new Class[]{theInterface},
+                new MethodLevelReloadingHandler(o, artifactType));
+    }
+
+    /**
+     * reload the class dynamically
+     */
+    public Class reload(Class clazz)
+    {
+        if (!isDynamic(clazz)) return clazz;
+        ClassResource resource = (ClassResource) getResource(clazz.getName());
+        if (resource == null) return clazz;
+        if (resource.isTainted() || resource.getAClass() == null)
+        {
+            clazz = _implementation.forName(clazz.getName());
+            //TODO not needed anymore, done by the forName now
+            resource.setAClass(clazz);
+        }
+        return clazz;
+    }
+
+    public Object reload(Object instance, int strategyType)
+    {
+        return _reloadingStrategy.reload(instance, strategyType);
+    }
+
+    /**
+     * we create a proxy to an existing object
+     * which does reloading of the internal class
+     * on newInstance level
+     *
+     * @param o            the original object
+     * @param theInterface the proxy interface
+     * @param artifactType the artifact type to be handled
+     * @return the proxy of the object if scripting is enabled, the original one otherwise
+     */
+    @SuppressWarnings("unused")
+    public static Object createConstructorReloadingProxyFromObject(Object o, Class theInterface, int artifactType)
+    {
+        //if (!isScriptingEnabled()) {
+        //    return o;
+        //}
+        return Proxy.newProxyInstance(o.getClass().getClassLoader(),
+                new Class[]{theInterface},
+                new MethodLevelReloadingHandler(o, artifactType));
+    }
+
+    /**
+     * un-mapping of a proxied object
+     *
+     * @param o the proxied object
+     * @return the un-proxied object
+     */
+    public static Object getDelegateFromProxy(Object o)
+    {
+        if (o == null)
+        {
+            return null;
+        }
+        if (o instanceof Decorated)
+            return ((Decorated) o).getDelegate();
+
+        if (!Proxy.isProxyClass(o.getClass())) return o;
+        InvocationHandler handler = Proxy.getInvocationHandler(o);
+        if (handler instanceof Decorated)
+        {
+            return ((Decorated) handler).getDelegate();
+        }
+        return o;
+    }
+
+    public void addDependency(int engineType, String fromClass, String toClass)
+    {
+        //TODO implement this tomorrow
+    }
+
+    public ImplementationSPI getImplementationSPI() {
+        return MyFacesSPI.getInstance();
+    }
+
+    //----------------------------------------------------------------------
+    //lifecycle related tasks
+    public boolean isPostInit()
+    {
+        return (lifecycleRegistry.get("LIFECYCLE_POST_INIT") != null);
+    }
+
+    public void markPostInit()
+    {
+        lifecycleRegistry.put("LIFECYCLE_POST_INIT", System.currentTimeMillis());
+    }
+
+    public void markLastTaint()
+    {
+        lifecycleRegistry.put("LIFECYCLE_LAST_TAINTED", System.currentTimeMillis());
+    }
+
+    /**
+     * @return the time value of the last taint happening
+     */
+    public long getLastTaint()
+    {
+        Long lastTainted = lifecycleRegistry.get("LIFECYCLE_LAST_TAINTED");
+        lastTainted = (lastTainted != null) ? lastTainted : -1L;
+        return lastTainted;
+    }
+
+    /**
+     * marks the last annotation scan
+     */
+    public void markLastAnnotationScan()
+    {
+        lifecycleRegistry.put("LIFECYCLE_LAST_ANN_SCAN", System.currentTimeMillis());
+    }
+
+    /**
+     * @return a the time value of the last annotation scan
+     */
+    public long getLastAnnotationScan()
+    {
+        Long lastTainted = lifecycleRegistry.get("LIFECYCLE_LAST_ANN_SCAN");
+        lastTainted = (lastTainted != null) ? lastTainted : -1L;
+        return lastTainted;
+    }
+
+    //------------------------------ tainting history entries -----------------------
+
+    /**
+     * adds a new entry into our taint log
+     * which allows us to access tainting data
+     * from a given point in time
+     *
+     * @param data the tainting data to be added
+     */
+    public void addTaintLogEntry(ClassResource data)
+    {
+        _taintLog.add(new TaintingHistoryEntry(data));
+    }
+
+    /**
+     * garbage collects our tainting data
+     * and removes all entries which are not
+     * present anymore due to timeout
+     * this gc code is called asynchronously
+     * from our tainting thread to keep the
+     * performance intact
+     */
+    public void gcTaintLog()
+    {
+        long timeoutTimestamp = System.currentTimeMillis() - TAINT_HISTORY_TIMEOUT;
+        Iterator<TaintingHistoryEntry> it = _taintLog.iterator();
+
+        while (it.hasNext())
+        {
+            TaintingHistoryEntry entry = it.next();
+            if (entry.getTimestamp() < timeoutTimestamp)
+            {
+                it.remove();
+            }
+        }
+    }
+
+    /**
+     * returns the last noOfEntries entries in the taint history
+     *
+     * @param noOfEntries the number of entries to be delivered
+     * @return a collection of the last &lt;noOfEntries&gt; entries
+     */
+    public Collection<ClassResource> getLastTainted(int noOfEntries)
+    {
+        Iterator<TaintingHistoryEntry> it = _taintLog.subList(Math.max(_taintLog.size() - noOfEntries, 0), _taintLog.size()).iterator();
+        List<ClassResource> retVal = new LinkedList<ClassResource>();
+        while (it.hasNext())
+        {
+            TaintingHistoryEntry entry = it.next();
+            retVal.add(entry.getData());
+        }
+        return retVal;
+    }
+
+    /**
+     * Returns a set of tainting data from a given point in time up until now
+     *
+     * @param timestamp the point in time from which the tainting data has to be derived from
+     * @return a set of entries which are a union of all points in time beginning from timestamp
+     */
+    public Collection<ClassResource> getTaintHistory(long timestamp)
+    {
+        List<ClassResource> retVal = new LinkedList<ClassResource>();
+        Iterator<TaintingHistoryEntry> it = _taintLog.iterator();
+
+        while (it.hasNext())
+        {
+            TaintingHistoryEntry entry = it.next();
+            if (entry.getTimestamp() >= timestamp)
+            {
+                retVal.add(entry.getData());
+            }
+        }
+        return retVal;
+    }
+
+    /**
+     * Returns a set of tainted classes from a given point in time up until now
+     *
+     * @param timestamp the point in time from which the tainting data has to be derived from
+     * @return a set of classnames which are a union of all points in time beginning from timestamp
+     */
+    public Set<String> getTaintHistoryClasses(long timestamp)
+    {
+        Set<String> retVal = new HashSet<String>();
+        Iterator<TaintingHistoryEntry> it = _taintLog.iterator();
+
+        while (it.hasNext())
+        {
+            TaintingHistoryEntry entry = it.next();
+            if (entry.getTimestamp() >= timestamp)
+            {
+                if (entry.getData() instanceof ClassResource)
+                {
+                    retVal.add(((ClassResource) entry.getData()).getAClass().getName());
+                } else
+                {
+                    retVal.add(entry.getData().getFile().getAbsolutePath());
+                }
+            }
+        }
+        return retVal;
+    }
+
+    //----------------------------------------------------------------------
+    /*public ClassDependencies getDependencyMap()
+    {
+        return _dependencyMap;
+    }
+
+    public void setDependencyMap(ClassDependencies dependencyMap)
+    {
+        _dependencyMap = dependencyMap;
+    } */
+
+    protected static WeavingContext _instance = new WeavingContext();
+
+    public static WeavingContext getInstance()
+    {
+        return _instance;
+    }
+
+    public ImplementationSPI getImplementation()
+    {
+        return _implementation;
+    }
+
+    public void setImplementation(ImplementationSPI implementation)
+    {
+        _implementation = implementation;
+    }
+
+    public boolean isScriptingEnabled()
+    {
+        return _scriptingEnabled;
+    }
+
+    public void setScriptingEnabled(boolean scriptingEnabled)
+    {
+        _scriptingEnabled = scriptingEnabled;
+    }
+
+    public CompilationResult getCompilationResult(Integer scriptingEngine)
+    {
+        return _compilationResults.get(scriptingEngine);
+    }
+
+    public void setCompilationResult(Integer scriptingEngine, CompilationResult result)
+    {
+        _compilationResults.put(scriptingEngine, result);
+    }
+
+}

Copied: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/Array.java (from r1300587, myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/probes/Probe2.java)
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/Array.java?p2=myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/Array.java&p1=myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/probes/Probe2.java&r1=1300587&r2=1300598&rev=1300598&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/probes/Probe2.java (original)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/Array.java Wed Mar 14 15:46:00 2012
@@ -16,21 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
-package org.apache.myfaces.extensions.scripting.scanningcore.probes;
+package org.apache.myfaces.extensions.scripting.core.common.util;
 
 /**
  * @author Werner Punz (latest modification by $Author$)
  * @version $Revision$ $Date$
  */
+@SuppressWarnings("unused")
+public class Array extends Cast
+{
+    public Array(Class clazz, Object... value) {
 
-public class Probe2 {
-
-    public Probe2(String[] test) {
-
-    }
-
-    public static Boolean myHello(String xxx) {
-        return Boolean.TRUE;
+        super(java.lang.reflect.Array.newInstance(clazz, 0).getClass(), value);
     }
 }

Copied: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/Cast.java (from r1300587, myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/probes/Probe2.java)
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/Cast.java?p2=myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/Cast.java&p1=myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/probes/Probe2.java&r1=1300587&r2=1300598&rev=1300598&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/probes/Probe2.java (original)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/Cast.java Wed Mar 14 15:46:00 2012
@@ -16,21 +16,27 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
-package org.apache.myfaces.extensions.scripting.scanningcore.probes;
+package org.apache.myfaces.extensions.scripting.core.common.util;
 
 /**
- * @author Werner Punz (latest modification by $Author$)
- * @version $Revision$ $Date$
+ * Simple casting representation for introspection
+ * calls
  */
+public class Cast {
 
-public class Probe2 {
+    Class clazz;
+    Object value;
 
-    public Probe2(String[] test) {
+    public Cast(Class clazz, Object value) {
+        this.clazz = clazz;
+        this.value = value;
+    }
 
+    public Class getClazz() {
+        return clazz;
     }
 
-    public static Boolean myHello(String xxx) {
-        return Boolean.TRUE;
+    public Object getValue() {
+        return value;
     }
 }

Added: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/ClassLoaderUtils.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/ClassLoaderUtils.java?rev=1300598&view=auto
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/ClassLoaderUtils.java (added)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/ClassLoaderUtils.java Wed Mar 14 15:46:00 2012
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.scripting.core.common.util;
+
+
+import org.apache.myfaces.extensions.scripting.core.api.WeavingContext;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * <p>Utility class for class loading purposes, e.g. to determine the classpath of a
+ * class loader hierarchy.</p>
+ */
+public class ClassLoaderUtils {
+
+
+    // ------------------------------------------ Public methods
+
+    /**
+     * CompilationResult
+     * <p>Returns the default class loader to use.</p>
+     *
+     * @return the default class loader to use
+     */
+    public static ClassLoader getDefaultClassLoader() {
+        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+        if (classLoader != null) {
+            return classLoader;
+        } else {
+            return ClassLoaderUtils.class.getClassLoader();
+        }
+    }
+
+    /**
+     * <p>Determines whether the given class is loadable by the given class loader.</p>
+     *
+     * @param className   the class you want to check
+     * @param classLoader the class loader to use for that check
+     * @return <code>true</code>, if the given class is loadable by the given class loader
+     */
+    public static boolean isClassAvailable(String className, ClassLoader classLoader) {
+        try {
+            classLoader.loadClass(className);
+            return true;
+        }
+        catch (Throwable ex) {
+            return false;
+        }
+    }
+
+    /**
+     * <p>Resolves the classpath by walking up the hierachy of class loaders. Assuming
+     * that we're only dealing with URLClassLoaders it's possible to determine the
+     * classpath. This method, however, returns the classpath as a String, where each
+     * classpath entry is separated by a ';', i.e. it returns the classpath in a format
+     * that Java tools usually expect it to be.</p>
+     * <p/>
+     * it also adds the additional classpaths issued by our configuration to the list
+     *
+     * @param classLoader the class loader which you want to resolve the class path for
+     * @return the final classpath
+     */
+    public static String buildClasspath(ClassLoader classLoader) {
+        StringBuilder classpath = new StringBuilder();
+
+        URL[] urls = resolveClasspath(classLoader);
+        for (URL url : urls) {
+            classpath.append(url.getPath());
+
+            // Note that the classpath separator character is platform
+            // dependent. On Windows systems it's ";" whereas on other
+            // UNIX systems it's ":".
+            classpath.append(File.pathSeparatorChar);
+        }
+
+        String retVal = classpath.toString();
+        if (retVal.endsWith(File.pathSeparator)) {
+            retVal = retVal.substring(0, retVal.length() - 1);
+        }
+        return retVal;
+    }
+
+    /**
+     * <p>Resolves the classpath by walking up the hierarchy of class loaders. Assuming
+     * that we're only dealing with URLClassLoaders it's possible to determine the
+     * classpath.</p>
+     *
+     * @param parent the class loader which you want to resolve the class path for
+     * @return the final classpath
+     */
+    public static URL[] resolveClasspath(ClassLoader parent) {
+        List<URL> classpath = new ArrayList<URL>();
+
+        ClassLoader classLoader = parent;
+        // Walk up the hierachy of class loaders in order to determine the current classpath.
+        File target = WeavingContext.getInstance().getConfiguration().getCompileTarget();
+        if (target != null) {
+            addFile(classpath, target);
+        }
+
+        while (classLoader != null) {
+            if (classLoader instanceof URLClassLoader) {
+                URLClassLoader urlClassLoader = (URLClassLoader) classLoader;
+
+                URL[] urls = urlClassLoader.getURLs();
+                if (urls != null) {
+                    classpath.addAll(Arrays.asList(urls));
+                }
+            } /*else {
+                if (logger.isWarnEnabled()) {
+                    logger.warn("Resolving the classpath of the classloader '" + parent + "' - One of its parent class"
+                            + " loaders is no URLClassLoader '" + classLoader + "', which means it's possible that"
+                            + " some classpath entries aren't in the final outcome of this method call.");
+                }
+            } */
+
+            //we disable this warning entirely for now because our own url classloader
+            //can deal with this properly, due to extra startup context classpath determination
+
+            // Inspect the parent class loader next.
+            classLoader = classLoader.getParent();
+        }
+
+        List<String> additionalClassPaths = WeavingContext.getInstance().getConfiguration().getAdditionalClassPath();
+        if (!(additionalClassPaths == null || additionalClassPaths.isEmpty())) {
+            for (String additionalClassPath : additionalClassPaths) {
+                File additionalPath = new File(additionalClassPath);
+                addFile(classpath, additionalPath);
+            }
+        }
+
+        return classpath.toArray(new URL[classpath.size()]);
+    }
+
+    private static void addFile(List<URL> classpath, File additionalPath) {
+        if (additionalPath.exists()) {
+            try {
+                classpath.add(additionalPath.toURI().toURL());
+            } catch (MalformedURLException e) {
+                Logger log = Logger.getLogger(ClassLoaderUtils.class.getName());
+                log.log(Level.SEVERE, "Additionalclasspath wrong url", e);
+            }
+        }
+    }
+
+}

Added: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/ClassUtils.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/ClassUtils.java?rev=1300598&view=auto
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/ClassUtils.java (added)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/ClassUtils.java Wed Mar 14 15:46:00 2012
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.scripting.core.common.util;
+
+//TODO this needs to be moved into the JSF 2.0 and 1.2 packages
+//reason due to the changes caused by the shade plugin it the ClassLoader
+//Extensions is in shared_impl in 1.2 and in shared in 2.x
+
+import java.io.File;
+
+/**
+ * A generic utils class dealing with different aspects
+ * (naming and reflection) of java classes
+ *
+ * @author werpu
+ *         <p/>
+ */
+public class ClassUtils
+{
+
+    public static Class forName(String name)
+    {
+        try
+        {
+            return Class.forName(name);
+        }
+        catch (ClassNotFoundException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static boolean isPresent(String clazz)
+    {
+        try
+        {
+            getContextClassLoader().loadClass(clazz);
+        }
+        catch (ClassNotFoundException e)
+        {
+            return false;
+        }
+        return true;
+    }
+
+    public static File classNameToFile(String classPath, String className)
+    {
+        String classFileName = classNameToRelativeFileName(className);
+        return new File(classPath + File.separator + classFileName);
+    }
+
+    private static String classNameToRelativeFileName(String className)
+    {
+        String separator = FileUtils.getFileSeparatorForRegex();
+
+        return className.replaceAll("\\.", separator) + ".class";
+    }
+
+    public static String relativeFileToClassName(String relativeFileName)
+    {
+        String className = relativeFileName.replaceAll("\\\\", ".").replaceAll("\\/", ".");
+        className = className.substring(0, className.lastIndexOf("."));
+        if(className.startsWith(".")) {
+            className = className.substring(1);
+        }
+        return className;
+    }
+
+    public static void addClassLoadingExtension(Object extension, boolean top)
+    {
+        try
+        {
+            ReflectUtil.executeStaticMethod(forName("org.apache.myfaces.shared_impl.util.ClassUtils"),
+                    "addClassLoadingExtension");
+        }
+        catch (Exception e)
+        {
+            ReflectUtil.executeStaticMethod(forName("org.apache.myfaces.shared.util.ClassUtils"),
+                    "addClassLoadingExtension", extension, top);
+        }
+
+        //ClassUtils.addClassLoadingExtension(extension, top);
+    }
+
+    public static ClassLoader getContextClassLoader()
+    {
+        try
+        {
+            return (ClassLoader) ReflectUtil.executeStaticMethod(forName("org.apache.myfaces.shared_impl.util.ClassUtils"),
+                    "getContextClassLoader");
+        }
+        catch (Exception e)
+        {
+            return (ClassLoader) ReflectUtil.executeStaticMethod(forName("org.apache.myfaces.shared.util.ClassUtils"),
+                    "getContextClassLoader");
+        }
+
+        //return (ClassLoader) ReflectUtil.executeStaticMethod(forName("org.apache.myfaces.extensions.scripting.util" +
+        //        ".ClassUtils"),
+        //        "getContextClassLoader");
+    }
+
+}

Copied: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/DirStrategy.java (from r1300587, myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/probes/Probe2.java)
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/DirStrategy.java?p2=myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/DirStrategy.java&p1=myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/probes/Probe2.java&r1=1300587&r2=1300598&rev=1300598&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/probes/Probe2.java (original)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/DirStrategy.java Wed Mar 14 15:46:00 2012
@@ -16,21 +16,34 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+package org.apache.myfaces.extensions.scripting.core.common.util;
 
-package org.apache.myfaces.extensions.scripting.scanningcore.probes;
+import java.io.File;
+import java.util.LinkedList;
+import java.util.List;
 
 /**
  * @author Werner Punz (latest modification by $Author$)
  * @version $Revision$ $Date$
  */
 
-public class Probe2 {
-
-    public Probe2(String[] test) {
+public class DirStrategy implements Strategy
+{
+    List<File> _foundFiles = new LinkedList<File>();
+
+    public void apply(Object element) {
+        File foundFile = (File) element;
+        if (foundFile.isDirectory()) {
+            _foundFiles.add(foundFile);
+        }
+    }
 
+    public List<File> getFoundFiles() {
+        return _foundFiles;
     }
 
-    public static Boolean myHello(String xxx) {
-        return Boolean.TRUE;
+    public void setFoundFiles(List<File> foundFiles) {
+        _foundFiles = foundFiles;
     }
 }
+

Added: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/FileStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/FileStrategy.java?rev=1300598&view=auto
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/FileStrategy.java (added)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/FileStrategy.java Wed Mar 14 15:46:00 2012
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.scripting.core.common.util;
+
+import java.io.File;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ *          <p/>
+ *          Java file strategy pattern to filter out all java files which are possible sources
+ *          so that we can recompile them
+ */
+
+public class FileStrategy implements Strategy
+{
+    Pattern _rePattern;
+
+    public FileStrategy(String pattern) {
+        pattern = pattern.trim().replaceAll("\\.", "\\\\.");
+        pattern = "." + pattern;
+
+        _rePattern = Pattern.compile(pattern);
+
+    }
+
+    public FileStrategy(Pattern pattern) {
+
+
+            _rePattern = pattern;
+
+        }
+
+
+    List<File> _foundFiles = new LinkedList<File>();
+
+    public void apply(Object element) {
+        File foundFile = (File) element;
+        String fileName = foundFile.getName().toLowerCase(Locale.getDefault());
+        Matcher matcher = _rePattern.matcher(fileName);
+
+        if (!matcher.matches()) return;
+        _foundFiles.add(foundFile);
+    }
+
+    public List<File> getFoundFiles() {
+        return _foundFiles;
+    }
+
+}

Added: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/FileUtils.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/FileUtils.java?rev=1300598&view=auto
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/FileUtils.java (added)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/FileUtils.java Wed Mar 14 15:46:00 2012
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.scripting.core.common.util;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+
+public class FileUtils {
+    static double _tempMarker = Math.random();
+
+    /**
+     * Get the file separator for this platform.
+     *
+     * @return The file separator.
+     */
+    public static String getFileSeparator() {
+        return File.separator;
+    }
+
+    /**
+     * touch functionality to mark
+     * compiles and dependencies as changed
+     * to get a clean reloading state
+     * <p/>
+     * the touch is basically just the same as unix touch
+     *
+     * @param fileToTouch
+     */
+    public static void touch(File fileToTouch) {
+        //we change our lastMofied to the current system time
+        if (!fileToTouch.exists()) return;
+        fileToTouch.setLastModified(System.currentTimeMillis());
+    }
+
+    /**
+     * Get the file separator for this platform, properly escaped for usage in a regular expression.
+     * workaround for http://bugs.sun.com/view_bug.do?bug_id=4626653 another workaround would be
+     * to use the Matcher.quoteReplacement as of http://bugs.sun.com/view_bug.do?bug_id=5024613  instead
+     * of using String.replaceAll
+     *
+     * @return The file separator, escaped for in a regex.
+     */
+    public static String getFileSeparatorForRegex() {
+        String sep = getFileSeparator();
+
+        if ("\\".equals(sep)) {
+            sep = "\\\\";
+        }
+
+        return sep;
+    }
+
+    public static File getTempDir() {
+        File tempDir;
+
+        String baseTempPath = System.getProperty("java.io.tmpdir");
+        String tempDirName = "myfaces_compilation_" + _tempMarker;
+
+        tempDir = new File(baseTempPath + File.separator + tempDirName);
+        /*while (tempDir.exists()) {
+            tempDirName = "myfaces_compilation_" + System.currentTimeMillis() + Math.random();
+            tempDir = new File(baseTempPath + File.separator + tempDirName);
+        }
+
+        synchronized (FileUtils.class) {
+            if (tempDir.exists()) {
+                return tempDir;
+            }
+            if (tempDir.mkdirs()) {
+                tempDir.deleteOnExit();
+            }
+        } */
+        return tempDir;
+    }
+
+    /**
+     * we roll our own tree walker here
+     * to avoid a dependency into commons fileutils
+     * and to apply an easier pattern than
+     * commons fileutils uses
+     *
+     * @param rootDir  the root dir for our walking
+     * @param strategy the strategy to apply to for our walking
+     */
+    public static void listFiles(File rootDir, Strategy strategy) {
+        if (!rootDir.isDirectory()) {
+            strategy.apply(rootDir);
+            return;
+        }
+
+        File[] files = rootDir.listFiles();
+        for (File file : files) {
+            boolean isDirectory = file.isDirectory();
+            if (isDirectory && !file.getName().endsWith(".")) {
+                listFiles(file, strategy);
+                strategy.apply(file);
+            } else if (!isDirectory) {
+                strategy.apply(file);
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * target path check to check if the targetPath is valid or can be created
+     * </p>
+     *
+     * @param path the path to be investigated
+     */
+    public static void assertPath(File path) {
+        // The destination directory must already exist as javac will not create the destination directory.
+        if (!path.exists()) {
+            if (!path.mkdirs()) {
+                throw new IllegalStateException("It wasn't possible to create the target " +
+                        "directory for the compiler ['" + path.getAbsolutePath() + "'].");
+            }
+
+            // If we've created the destination directory, we'll delete it as well once the application exits
+            path.deleteOnExit();
+        }
+    }
+
+    /**
+     * fetches recursively the files under the current root
+     *
+     * @param sourcePath the source path from which the walker should start from
+     * @param fileType   the pattern upon which the file has to be matched to aka *.java etc...
+     * @return a list of source files
+     */
+    public static List<File> fetchSourceFiles(File sourcePath, String fileType) {
+        FileStrategy strategy = new FileStrategy(fileType);
+        listFiles(sourcePath, strategy);
+
+        return strategy.getFoundFiles();
+    }
+
+    /**
+     * fetches the source files from a list of source paths
+     *
+     * @param sourcePaths the collection of paths to be searched for
+     * @param fileType    the filetype to be searched for
+     * @return a list of files found
+     */
+    public static List<File> fetchSourceFiles(Collection<String> sourcePaths, String fileType) {
+        FileStrategy strategy = new FileStrategy(fileType);
+
+        for (String sourcePath : sourcePaths) {
+            File fSourcePath = new File(sourcePath);
+            if (fSourcePath.exists()) {
+                listFiles(fSourcePath, strategy);
+            }
+        }
+
+        return strategy.getFoundFiles();
+    }
+
+    /**
+     * fetches the source paths from a given root directory in the format
+     * <path>/<appendix>;...
+     *
+     * @param sourcePath the sourcePath from which the directory traversal should happen from
+     * @param appendix   the appendix which has to be appended to every path found
+     * @return a string builder of the paths found
+     */
+    @SuppressWarnings("unused")
+    public static StringBuilder fetchSourcePaths(File sourcePath, String appendix) {
+        DirStrategy dirStrategy = new DirStrategy();
+        StringBuilder sourcesList = new StringBuilder(512);
+
+        listFiles(sourcePath, dirStrategy);
+        for (File foundDir : dirStrategy.getFoundFiles()) {
+            String dirName = foundDir.getAbsolutePath();
+            sourcesList.append(dirName);
+            sourcesList.append(File.separator);
+            sourcesList.append(appendix);
+        }
+        return sourcesList;
+    }
+}

Copied: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/Null.java (from r1300587, myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/probes/Probe2.java)
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/Null.java?p2=myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/Null.java&p1=myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/probes/Probe2.java&r1=1300587&r2=1300598&rev=1300598&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/probes/Probe2.java (original)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/Null.java Wed Mar 14 15:46:00 2012
@@ -16,21 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
-package org.apache.myfaces.extensions.scripting.scanningcore.probes;
+package org.apache.myfaces.extensions.scripting.core.common.util;
 
 /**
- * @author Werner Punz (latest modification by $Author$)
- * @version $Revision$ $Date$
+ * @Author Werner Punz
+ * Null representation for easier introspection calls
  */
+public class Null extends Cast
+{
 
-public class Probe2 {
-
-    public Probe2(String[] test) {
-
+    public Null(Class clazz) {
+        super(clazz, null);
     }
 
-    public static Boolean myHello(String xxx) {
-        return Boolean.TRUE;
-    }
 }

Added: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/ReflectUtil.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/ReflectUtil.java?rev=1300598&view=auto
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/ReflectUtil.java (added)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/ReflectUtil.java Wed Mar 14 15:46:00 2012
@@ -0,0 +1,432 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.scripting.core.common.util;
+
+
+import org.apache.myfaces.extensions.scripting.core.api.WeavingContext;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+
+public class ReflectUtil {
+
+    static final Logger _logger = Logger.getLogger(ReflectUtil.class.getName());
+
+    public static Object instantiate(String clazz, Object... varargs) {
+        return instantiate(ClassUtils.forName(clazz), varargs);
+    }
+
+    /**
+     * A simplified instantiation over reflection
+     *
+     * @param clazz   the class to be instantiated
+     * @param varargs the instantiation parameters
+     * @return the instantiated object
+     */
+    public static Object instantiate(Class clazz, Object... varargs) {
+        Class[] classes = new Class[varargs.length];
+        for (int cnt = 0; cnt < varargs.length; cnt++) {
+
+            if (varargs[cnt] instanceof Cast) {
+                classes[cnt] = ((Cast) varargs[cnt]).getClazz();
+                varargs[cnt] = ((Cast) varargs[cnt]).getValue();
+            } else {
+                classes[cnt] = varargs[cnt].getClass();
+            }
+        }
+
+        try {
+            Constructor constr = clazz.getConstructor(classes);
+            return constr.newInstance(varargs);
+        } catch (NoSuchMethodException e) {
+            throw new RuntimeException(e);
+        } catch (InvocationTargetException e) {
+            throw new RuntimeException(e);
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException(e);
+        } catch (InstantiationException e) {
+            throw new RuntimeException(e);
+        }
+    }/*this is mostly just a helper to bypass a groovy bug in a more
+   * complex delegation environment. Groovy throws a classcast
+   * exception wrongly, delegating the instantiation code to java
+   * fixes that
+   * */
+
+    public static Object newObject(Class clazz) throws IllegalAccessException, InstantiationException {
+        return clazz.newInstance();
+    }
+
+    /**
+     * Generic execute method which simplifies the reflection api
+     * down to a usable system
+     *
+     * @param obj        the target object the method has to be executed upon
+     * @param methodName the method name
+     * @param varargs    the arguments which have to be passed to the method
+     * @return the return value of the method
+     */
+    public static Object executeStaticMethod(Class obj, String methodName, Object... varargs) {
+
+        Collection<Method> methods = getMethods(obj, methodName, varargs.length);
+
+        Object retVal = handleStaticMethod(obj, methodName, methods, varargs);
+        if (!methodNotFound(retVal)) {
+            return retVal;
+        }
+
+        methods = getAllMethods(obj, methodName, varargs.length);
+        retVal = handleStaticMethod(obj, methodName, methods, varargs);
+        if (!methodNotFound(retVal)) {
+            return retVal;
+        }
+
+        throw new RuntimeException("Static Method of :" + methodName + " from class " + obj.getClass().getName() + " not found");
+
+    }
+
+    public static Collection<Method> getAllMethods(Class clazz, String methodName, int varargLength) {
+        ArrayList<Method> retVal = new ArrayList<Method>(30);
+        while (clazz != null) {
+            for (Method m : clazz.getDeclaredMethods()) {
+                if (m.getParameterTypes().length == varargLength && m.getName().equals(methodName)) {
+                    retVal.add(m);
+                }
+            }
+            clazz = clazz.getSuperclass();
+        }
+
+        return retVal;
+    }
+
+    public static Collection<Method> getMethods(Class clazz, String methodName, int varargLength) {
+        ArrayList<Method> retVal = new ArrayList<Method>(30);
+        for (Method m : clazz.getDeclaredMethods()) {
+            if (m.getParameterTypes().length == varargLength && m.getName().equals(methodName)) {
+                retVal.add(m);
+            }
+        }
+
+        return retVal;
+    }
+
+    /**
+     * Generic execute method which simplifies the reflection api
+     * down to a usable system
+     *
+     * @param obj        the target object the method has to be executed upon
+     * @param methodName the method name
+     * @param varargs    the arguments which have to be passed to the method
+     * @return the return value of the method
+     * @throws RuntimeException a generic runtime exception in case of a failure
+     *                          we use unmanaged exceptions here to get a behavior similar to scripting
+     *                          language execution where failures can happen but method executions
+     *                          should not enforce exception handling
+     */
+    public static Object executeMethod(Object obj, String methodName, Object... varargs) {
+
+        Collection<Method> methods;
+        //if we have an invocationHandler here we
+        //can work over the generic invoke interface
+        //That way we can cover more dynamic stuff
+        //our reload invocation handler is treated differently here
+
+        if (obj instanceof InvocationHandler) {
+            InvocationHandler objToInvoke = (InvocationHandler) obj;
+
+            Object realTarget = WeavingContext.getInstance().getDelegateFromProxy(objToInvoke);
+
+            //first we try only the public because they are the most likely ones
+            //to be accessed
+            methods = getMethods(realTarget.getClass(), methodName, varargs.length);
+            Object retVal = handleInvHandlerMethod(objToInvoke, methodName, methods, varargs);
+            if (!methodNotFound(retVal)) {
+                return retVal;
+            }
+            //if not we try all of them until we have a match
+            methods = getAllMethods(realTarget.getClass(), methodName, varargs.length);
+            retVal = handleInvHandlerMethod(objToInvoke, methodName, methods, varargs);
+            if (!(methodNotFound(retVal))) {
+                return retVal;
+            }
+
+            throw new RuntimeException("Method of :" + methodName + " from class " + obj.getClass().getName() + " not found");
+        }
+
+        Class clazz = obj.getClass();
+
+        //first we try only the public because they are the most likely ones
+        //to be accessed
+        methods = getMethods(clazz, methodName, varargs.length);
+        Object retVal = handleObjMethod(obj, methodName, methods, varargs);
+        if (!methodNotFound(retVal)) {
+            return retVal;
+        }
+
+        //if not we try all of them until we have a match
+        methods = getAllMethods(clazz, methodName, varargs.length);
+        retVal = handleObjMethod(obj, methodName, methods, varargs);
+        if (!methodNotFound(retVal)) {
+            return retVal;
+        }
+
+        throw new RuntimeException("Method of :" + methodName + " from class " + obj.getClass().getName() + " not found");
+    }
+
+    /**
+     * special marker class which is a special return value indicating
+     * that not method has been found which can be executed
+     */
+    static class _MethodNotFound {
+    }
+
+    /**
+     * check if the return value is a method not found return val which
+     * indicates we have to follow the next workflow step
+     *
+     * @param retVal the retVal which has to be investigated
+     * @return true if the retVal is instance of _MethodNotFound false otherwise
+     */
+    private static boolean methodNotFound(Object retVal) {
+        return retVal instanceof _MethodNotFound;
+    }
+
+    /**
+     * executes a method in an invocation handler with a set of
+     * methods which are canidates for execution
+     *
+     * @param objToInvoke the invokee object
+     * @param methodName  the method name
+     * @param methods     the methods which are under investigation for invoking
+     * @param varargs     the list of varargs to be passed to the method
+     * @return the result of the invocation, or an object of type _MethodNotFound otherwise
+     */
+    static private Object handleInvHandlerMethod(InvocationHandler objToInvoke, String methodName, Collection<Method> methods, Object... varargs) {
+        for (Method m : methods) {
+            if (!m.getName().equals(methodName) || m.getParameterTypes().length != varargs.length) {
+                continue;
+            }
+            try {
+                return objToInvoke.invoke(objToInvoke, m, varargs);
+            } catch (Throwable e) {
+                handleException(e);
+            }
+        }
+        return new _MethodNotFound();
+    }
+
+    /**
+     * executes a method on an object
+     *
+     * @param objToInvoke the invokee object
+     * @param methodName  the method name
+     * @param methods     the methods which are under investigation for invoking
+     * @param varargs     the list of varargs to be passed to the method
+     * @return the result of the invocation, or an object of type _MethodNotFound otherwise
+     */
+    static private Object handleObjMethod(Object objToInvoke, String methodName, Collection<Method> methods, Object... varargs) {
+        for (Method m : methods) {
+            if (!m.getName().equals(methodName) || m.getParameterTypes().length != varargs.length) {
+                continue;
+            }
+            try {
+                return m.invoke(objToInvoke, varargs);
+            } catch (Throwable e) {
+                handleException(e);
+            }
+        }
+        return new _MethodNotFound();
+    }
+
+    /**
+     * executes a static method on a class
+     *
+     * @param objToInvoke the invokee object
+     * @param methodName  the method name
+     * @param methods     the methods which are under investigation for invoking
+     * @param varargs     the list of varargs to be passed to the method
+     * @return the result of the invocation, or an object of type _MethodNotFound otherwise
+     */
+    static private Object handleStaticMethod(Class objToInvoke, String methodName, Collection<Method> methods, Object... varargs) {
+        for (Method m : methods) {
+            if (!m.getName().equals(methodName) || m.getParameterTypes().length != varargs.length) {
+                continue;
+            }
+            try {
+                return m.invoke(objToInvoke, varargs);
+            } catch (Throwable e) {
+                handleException(e);
+            }
+        }
+        return new _MethodNotFound();
+    }
+
+    private static void handleException(Throwable e) {
+        if (e instanceof IllegalAccessException) {
+            if (_logger.isLoggable(Level.FINEST)) {
+                _logger.log(Level.FINEST, "", e);
+            }
+        } else if (e instanceof IllegalArgumentException) {
+            if (_logger.isLoggable(Level.FINEST)) {
+                _logger.log(Level.FINEST, "", e);
+            }
+        } else {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * executes a function method on a target object
+     *
+     * @param obj        the target object
+     * @param methodName the method name
+     * @param varargs    a list of objects casts or nulls defining the parameter classes and its values
+     *                   if something occurs on introspection level an unmanaged exception is throw, just like
+     *                   it would happen in a scripting class
+     * @return the result object for the Method(method) call
+     * @throws RuntimeException an unmanaged runtime exception in case of an introspection error
+     */
+    public static Object fastExecuteMethod(Object obj, String methodName, Object... varargs) {
+        Class[] classes = new Class[varargs.length];
+        for (int cnt = 0; cnt < varargs.length; cnt++) {
+
+            if (varargs[cnt] instanceof Cast) {
+                classes[cnt] = ((Cast) varargs[cnt]).getClazz();
+                varargs[cnt] = ((Cast) varargs[cnt]).getValue();
+            } else {
+                classes[cnt] = varargs[cnt].getClass();
+            }
+        }
+
+        try {
+            Method m = fastGetMethod(obj, methodName, classes);
+            return m.invoke(obj, varargs);
+        } catch (NoSuchMethodException e) {
+            throw new RuntimeException(e);
+        } catch (InvocationTargetException e) {
+            throw new RuntimeException(e);
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException(e);
+        }
+
+    }
+
+    /**
+     * faster reflection call
+     * if we know the data types exactly we can
+     * trigger a direct call instead of walking through all methods
+     * note this method only allows to trigger against directly declared methods
+     * it ignores the inheritance hierarchy for faster access
+     *
+     * @param obj        the invokee object
+     * @param methodName the metod name
+     * @param classes    the parameter type classes
+     * @return the method if found
+     * @throws NoSuchMethodException in case it could not be found
+     */
+    public static Method fastGetMethod(Object obj, String methodName, Class[] classes) throws NoSuchMethodException {
+        Method m;
+        try {
+            m = obj.getClass().getDeclaredMethod(methodName, classes);
+        } catch (NoSuchMethodException e) {
+            m = obj.getClass().getMethod(methodName, classes);
+        }
+        return m;
+    }
+
+    /**
+     * executes a function method on a target object
+     *
+     * @param obj        the target object
+     * @param methodName the method name
+     * @param varargs    a list of objects casts or nulls defining the parameter classes and its values
+     *                   if something occurs on introspection level an unmanaged exception is throw, just like
+     *                   it would happen in a scripting class
+     * @return the result object for the Method(method) call
+     * @throws RuntimeException an unmanaged runtime exception in case of an introspection error
+     */
+    public static Object fastExecuteStaticMethod(Class obj, String methodName, Object... varargs) {
+        Class[] classes = new Class[varargs.length];
+        for (int cnt = 0; cnt < varargs.length; cnt++) {
+
+            if (varargs[cnt] instanceof Cast) {
+                classes[cnt] = ((Cast) varargs[cnt]).getClazz();
+                varargs[cnt] = ((Cast) varargs[cnt]).getValue();
+            } else {
+                classes[cnt] = varargs[cnt].getClass();
+            }
+        }
+
+        try {
+            Method m = fastGetStaticMethod(obj, methodName, classes);
+            return m.invoke(obj, varargs);
+        } catch (NoSuchMethodException e) {
+            throw new RuntimeException(e);
+        } catch (InvocationTargetException e) {
+            throw new RuntimeException(e);
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException(e);
+        }
+
+    }
+
+    public static Method fastGetStaticMethod(Class obj, String methodName, Class[] classes) throws NoSuchMethodException {
+        Method m;
+        try {
+            m = obj.getDeclaredMethod(methodName, classes);
+        } catch (NoSuchMethodException e) {
+            m = obj.getMethod(methodName, classes);
+        }
+        return m;
+    }
+
+    /**
+     * convenience method which makes the code a little bit more readable
+     * use it in conjunction with static imports
+     *
+     * @param clazz the cast target for the method call
+     * @param value the value object to be used as param
+     * @return a Cast object of the parameters
+     */
+    public static Cast cast(Class clazz, Object value) {
+        return new Cast(clazz, value);
+    }
+
+    /**
+     * convenience method which makes the code a little bit more readable
+     * use it in conjunction with static imports
+     *
+     * @param clazz the cast target for the method call
+     * @return a null value Cast object of the parameters
+     */
+    public static Null nullCast(Class clazz) {
+        return new Null(clazz);
+    }
+}

Copied: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/Strategy.java (from r1300587, myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/probes/Probe2.java)
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/Strategy.java?p2=myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/Strategy.java&p1=myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/probes/Probe2.java&r1=1300587&r2=1300598&rev=1300598&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/probes/Probe2.java (original)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/Strategy.java Wed Mar 14 15:46:00 2012
@@ -16,21 +16,18 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
-package org.apache.myfaces.extensions.scripting.scanningcore.probes;
+package org.apache.myfaces.extensions.scripting.core.common.util;
 
 /**
+ * Applied strategy class for iteration walkers
+ * to make the handling of iterated objects
+ * more scripting language like (aka a pattern similar to closures)
+ *
  * @author Werner Punz (latest modification by $Author$)
  * @version $Revision$ $Date$
  */
+public interface Strategy {
 
-public class Probe2 {
-
-    public Probe2(String[] test) {
-
-    }
+    public void apply(Object element);
 
-    public static Boolean myHello(String xxx) {
-        return Boolean.TRUE;
-    }
 }

Copied: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/StringUtils.java (from r1300587, myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/probes/Probe2.java)
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/StringUtils.java?p2=myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/StringUtils.java&p1=myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/probes/Probe2.java&r1=1300587&r2=1300598&rev=1300598&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/probes/Probe2.java (original)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/common/util/StringUtils.java Wed Mar 14 15:46:00 2012
@@ -17,20 +17,19 @@
  * under the License.
  */
 
-package org.apache.myfaces.extensions.scripting.scanningcore.probes;
+package org.apache.myfaces.extensions.scripting.core.common.util;
 
 /**
+ * Replacement for commons lang
+ * because we want to get the dependency out
+ * after all we only used StringUtils
+ * 
  * @author Werner Punz (latest modification by $Author$)
  * @version $Revision$ $Date$
  */
 
-public class Probe2 {
-
-    public Probe2(String[] test) {
-
-    }
-
-    public static Boolean myHello(String xxx) {
-        return Boolean.TRUE;
+public class StringUtils {
+    public static boolean isBlank(String in) {
+        return in == null || in.trim().equals("");
     }
 }

Added: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/engine/BaseEngine.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/engine/BaseEngine.java?rev=1300598&view=auto
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/engine/BaseEngine.java (added)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/engine/BaseEngine.java Wed Mar 14 15:46:00 2012
@@ -0,0 +1,242 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.scripting.core.engine;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.myfaces.extensions.scripting.core.common.util.ClassUtils;
+import org.apache.myfaces.extensions.scripting.core.common.util.FileUtils;
+import org.apache.myfaces.extensions.scripting.core.engine.dependencyScan.api.DependencyRegistry;
+import org.apache.myfaces.extensions.scripting.core.engine.dependencyScan.core.ClassDependencies;
+import org.apache.myfaces.extensions.scripting.core.engine.dependencyScan.registry.DependencyRegistryImpl;
+import org.apache.myfaces.extensions.scripting.core.monitor.ClassResource;
+
+import javax.servlet.ServletContext;
+import java.io.File;
+import java.net.URL;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.logging.Logger;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+
+public abstract class BaseEngine
+{
+    CopyOnWriteArrayList<String> _sourcePaths = new CopyOnWriteArrayList<String>();
+    Map<String, ClassResource> _watchedResources = new ConcurrentHashMap<String, ClassResource>();
+    //both belong together but the dependencyregistry is just
+    //a wrapper for the dep map with additional functionality
+    ClassDependencies _dependencyMap = new ClassDependencies();
+    DependencyRegistry _dependencyRegistry = new DependencyRegistryImpl(getEngineType(), _dependencyMap);
+
+    Logger log = Logger.getLogger(this.getClass().getName());
+
+
+    protected BaseEngine()
+    {
+
+    }
+
+    public Map<String, ClassResource> getWatchedResources()
+    {
+        return _watchedResources;
+    }
+
+    public List<String> getSourcePaths()
+    {
+        return _sourcePaths;
+    }
+
+    public abstract String getFileEnding();
+
+    public abstract int getEngineType();
+
+    /**
+     * @return a collection of possible dynamic classes
+     */
+    public Collection<String> getPossibleDynamicClasses()
+    {
+        return _watchedResources.keySet();
+    }
+
+    /**
+     * runs a full scan of files to get a list of files which need to be processed
+     * for the future
+     */
+    public void scanForAddedDeleted()
+    {
+        Set<String> processedClasses = new HashSet<String>();
+        processedClasses.addAll(_watchedResources.keySet());
+
+        for (String sourcePath : getSourcePaths())
+        {
+            Collection<File> sourceFiles = FileUtils.fetchSourceFiles(new File(sourcePath), "*." + getFileEnding());
+
+            for (File sourceFile : sourceFiles)
+            {
+                ClassResource classToProcess = new ClassResource();
+                classToProcess.setFile(sourceFile);
+
+
+                classToProcess.setScriptingEngine(getEngineType());
+                if (!_watchedResources.containsKey(classToProcess.getIdentifier()))
+                {
+                    _watchedResources.put(classToProcess.getIdentifier(), classToProcess);
+                } else
+                {
+                    processedClasses.remove(classToProcess.getIdentifier());
+
+                    classToProcess = _watchedResources.get(classToProcess.getIdentifier());
+                }
+                if (classToProcess.needsRecompile())
+                {
+                    //TODO add entry for logging component here
+                    log.info("[EXT-SCRIPTING] tainting " + classToProcess.getIdentifier());
+                    classToProcess.setTainted(true);
+                    classToProcess.setChangedForCompile(true);
+                }
+            }
+        }
+        for (String deleted : processedClasses)
+        {
+            _watchedResources.remove(deleted);
+        }
+
+    }
+
+    /**
+     * checks whether we have resources which are in need of a recompile
+     *
+     * @return
+     */
+    public boolean needsRecompile()
+    {
+        //TODO buffer this from scan
+        for (Map.Entry<String, ClassResource> resource : _watchedResources.entrySet())
+        {
+            if (resource.getValue().needsRecompile()) return true;
+        }
+        return false;
+    }
+
+    /**
+     * checks whether we have resources which are tainted
+     *
+     * @return
+     */
+    public boolean isTainted()
+    {
+        //TODO buffer this from scan
+        for (Map.Entry<String, ClassResource> resource : _watchedResources.entrySet())
+        {
+            if (resource.getValue().isTainted()) return true;
+        }
+        return false;
+    }
+
+    public DependencyRegistry getDependencyRegistry()
+    {
+        return _dependencyRegistry;
+    }
+
+    public void setDependencyRegistry(DependencyRegistry dependencyRegistry)
+    {
+        _dependencyRegistry = dependencyRegistry;
+    }
+
+    public ClassDependencies getDependencyMap()
+    {
+        return _dependencyMap;
+    }
+
+    public void setDependencyMap(ClassDependencies dependencyMap)
+    {
+        _dependencyMap = dependencyMap;
+    }
+
+    /**
+     * marks all the dependencies of the tainted objects
+     * also as tainted to allow proper refreshing.
+     */
+    public void markTaintedDependencies()
+    {
+        //basic tainted set by the full scall
+        Set<String> _processedClasses = new HashSet<String>();
+        for (Map.Entry<String, ClassResource> entry : _watchedResources.entrySet())
+        {
+            //TODO add entry for logging component here
+            ClassResource resource = entry.getValue();
+            if (!resource.isChangedForCompile()) continue;
+            resource.setChangedForCompile(false);
+            log.info("[EXT-SCRIPTING] tainting dependency " + resource.getIdentifier());
+            resource.setTainted(true);
+            //classname
+            String identifier = resource.getIdentifier();
+            if (_processedClasses.contains(identifier)) continue;
+            markDependencies(_processedClasses, identifier);
+
+        }
+
+    }
+
+    /*marks all backward dependencies of the existing class*/
+    private void markDependencies(Set<String> _processedClasses, String identifier)
+    {
+        Set<String> referringClasses = _dependencyMap.getReferringClasses(identifier);
+        if (referringClasses == null) return;
+        for (String referringClass : referringClasses)
+        {
+            if (_processedClasses.contains(referringClass)) continue;
+            ClassResource toTaint = _watchedResources.get(referringClass);
+            if (toTaint == null) continue;
+            //TODO add entry for logging component here
+            if (toTaint.isTainted())
+            {
+                log.info("[EXT-SCRIPTING] dependency already tainted:" + toTaint.getIdentifier());
+                _processedClasses.add(toTaint.getIdentifier());
+                continue;
+            }
+            toTaint.setTainted(true);
+            toTaint.setChangedForCompile(false);
+            log.info("[EXT-SCRIPTING] tainting dependency " + toTaint.getIdentifier());
+            _processedClasses.add(toTaint.getIdentifier());
+            markDependencies(_processedClasses, toTaint.getIdentifier());
+        }
+
+    }
+
+    protected void initPaths(ServletContext context, String initParam, String defaultValue)
+    {
+        String pathSeparatedList = context.getInitParameter(initParam);
+        pathSeparatedList = (pathSeparatedList != null) ? pathSeparatedList : defaultValue;
+        if (pathSeparatedList.equals(defaultValue))
+        {
+            URL resource = ClassUtils.getContextClassLoader().getResource("./");
+            pathSeparatedList = FilenameUtils.normalize(resource.getPath() + "../.." + defaultValue);
+        }
+        String[] paths = pathSeparatedList.split(",");
+        for (String path : paths)
+        {
+            getSourcePaths().add(path);
+        }
+    }
+}