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 <class, taint> to a three dimensional <class, taint, time>
+ * 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 <noOfEntries> 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);
+ }
+ }
+}