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 15:51:12 UTC
svn commit: r1300571 - in
/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting:
core/api/ jsf/adapters/ jsf/adapters/handlers/ jsf/startup/
Author: werpu
Date: Wed Mar 14 14:51:12 2012
New Revision: 1300571
URL: http://svn.apache.org/viewvc?rev=1300571&view=rev
Log:
https://issues.apache.org/jira/browse/EXTSCRIPT-154 fixing the refresh in non request scopes
Added:
myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/api/ImplementationSPI.java
- copied, changed from r1300527, myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/adapters/ImplementationSPI.java
myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/adapters/handlers/
myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/adapters/handlers/MyFacesBeanHandler.java
myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/RefreshPhaseListener.java
- copied, changed from r1300527, myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/AnnotationScanPhaseListener.java
Removed:
myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/adapters/ImplementationSPI.java
myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/AnnotationScanPhaseListener.java
Modified:
myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/api/WeavingContext.java
myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/adapters/MyFacesSPI.java
myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/StartupServletContextPluginChainLoader.java
Copied: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/api/ImplementationSPI.java (from r1300527, myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/adapters/ImplementationSPI.java)
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/api/ImplementationSPI.java?p2=myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/api/ImplementationSPI.java&p1=myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/adapters/ImplementationSPI.java&r1=1300527&r2=1300571&rev=1300571&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/adapters/ImplementationSPI.java (original)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/api/ImplementationSPI.java Wed Mar 14 14:51:12 2012
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package rewrite.org.apache.myfaces.extensions.scripting.jsf.adapters;
+package rewrite.org.apache.myfaces.extensions.scripting.core.api;
import javax.servlet.ServletContext;
@@ -31,5 +31,6 @@ public interface ImplementationSPI
{
public void registerClassloadingExtension(ServletContext context);
public Class forName(String clazz);
+ public void refreshManagedBeans();
}
Modified: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/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/rewrite/org/apache/myfaces/extensions/scripting/core/api/WeavingContext.java?rev=1300571&r1=1300570&r2=1300571&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/api/WeavingContext.java (original)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/api/WeavingContext.java Wed Mar 14 14:51:12 2012
@@ -30,7 +30,7 @@ import rewrite.org.apache.myfaces.extens
import rewrite.org.apache.myfaces.extensions.scripting.core.monitor.WatchedResource;
import rewrite.org.apache.myfaces.extensions.scripting.core.reloading.GlobalReloadingStrategy;
import rewrite.org.apache.myfaces.extensions.scripting.core.reloading.MethodLevelReloadingHandler;
-import rewrite.org.apache.myfaces.extensions.scripting.jsf.adapters.ImplementationSPI;
+import rewrite.org.apache.myfaces.extensions.scripting.jsf.adapters.MyFacesSPI;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
@@ -211,6 +211,29 @@ public class WeavingContext
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
*
@@ -418,6 +441,10 @@ public class WeavingContext
//TODO implement this tomorrow
}
+ public ImplementationSPI getImplementationSPI() {
+ return MyFacesSPI.getInstance();
+ }
+
//----------------------------------------------------------------------
//lifecycle related tasks
public boolean isPostInit()
Modified: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/adapters/MyFacesSPI.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/adapters/MyFacesSPI.java?rev=1300571&r1=1300570&r2=1300571&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/adapters/MyFacesSPI.java (original)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/adapters/MyFacesSPI.java Wed Mar 14 14:51:12 2012
@@ -18,7 +18,9 @@
*/
package rewrite.org.apache.myfaces.extensions.scripting.jsf.adapters;
+import rewrite.org.apache.myfaces.extensions.scripting.core.api.ImplementationSPI;
import rewrite.org.apache.myfaces.extensions.scripting.core.common.util.ClassUtils;
+import rewrite.org.apache.myfaces.extensions.scripting.jsf.adapters.handlers.MyFacesBeanHandler;
import javax.servlet.ServletContext;
@@ -31,7 +33,8 @@ import javax.servlet.ServletContext;
public class MyFacesSPI implements ImplementationSPI
{
CustomChainLoader _loader = null;
-
+ MyFacesBeanHandler beanHandler = new MyFacesBeanHandler();
+
public void registerClassloadingExtension(ServletContext context) {
CustomChainLoader loader = new CustomChainLoader(context); //ReflectUtil.instantiate("extras.org.apache.myfaces.extensions
// .scripting.servlet" +
@@ -41,6 +44,10 @@ public class MyFacesSPI implements Imple
_loader = loader;
}
+ public void refreshManagedBeans() {
+ beanHandler.refreshAllManagedBeans();
+ }
+
public Class forName(String clazz) {
return _loader.forName(clazz);
}
Added: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/adapters/handlers/MyFacesBeanHandler.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/adapters/handlers/MyFacesBeanHandler.java?rev=1300571&view=auto
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/adapters/handlers/MyFacesBeanHandler.java (added)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/adapters/handlers/MyFacesBeanHandler.java Wed Mar 14 14:51:12 2012
@@ -0,0 +1,281 @@
+/*
+ * 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 rewrite.org.apache.myfaces.extensions.scripting.jsf.adapters.handlers;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ *
+ * TODO refactor this out
+ */
+
+import org.apache.myfaces.config.RuntimeConfig;
+import org.apache.myfaces.config.annotation.LifecycleProvider;
+import org.apache.myfaces.config.annotation.LifecycleProviderFactory;
+import rewrite.org.apache.myfaces.extensions.scripting.core.api.ScriptingConst;
+import rewrite.org.apache.myfaces.extensions.scripting.core.api.WeavingContext;
+import rewrite.org.apache.myfaces.extensions.scripting.core.common.util.ReflectUtil;
+import rewrite.org.apache.myfaces.extensions.scripting.core.monitor.ClassResource;
+
+import javax.faces.context.FacesContext;
+import java.lang.reflect.InvocationTargetException;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Bean handler implementation
+ * which encapsulates the myfaces specific parts
+ * of the bean processing
+ */
+public class MyFacesBeanHandler
+{
+
+ static final Logger _logger = Logger.getLogger(MyFacesBeanHandler.class.getName());
+
+ /**
+ * constructor
+ */
+ public MyFacesBeanHandler()
+ {
+
+ }
+
+ /**
+ * Refreshes all managed beans
+ * session, and personal scoped ones
+ * <p/>
+ * personal scoped beans are beans which
+ * have either
+ * <li> session scope </li>
+ * <li> page scope </li>
+ * <li> custom scope </li>
+ */
+ public void refreshAllManagedBeans()
+ {
+ if (FacesContext.getCurrentInstance() == null)
+ {
+ return;//no npe allowed
+ }
+
+ Collection<ClassResource> tainted = WeavingContext.getInstance().getTaintedClasses();
+ Set<String> taints = new HashSet<String>();
+ for (ClassResource taintedClass : tainted)
+ {
+ if(taintedClass.getAClass() != null) {
+ taints.add(taintedClass.getAClass().getName());
+ }
+ }
+
+ //scanElDependencies();
+
+ if (taints.size() > 0)
+ {
+ //We now have to check if the tainted classes belong to the managed beans
+ Set<String> managedBeanClasses = new HashSet<String>();
+
+ Map mbeans = RuntimeConfig.getCurrentInstance(FacesContext.getCurrentInstance().getExternalContext()).getManagedBeans();
+ Map mbeansSnapshotView;
+
+ //synchronized (RefreshContext.BEAN_SYNC_MONITOR) {
+ mbeansSnapshotView = makeSnapshot(mbeans);
+ //}
+
+ for (Object entry : mbeansSnapshotView.entrySet())
+ {
+ Object bean = (Object) ((Map.Entry) entry).getValue();
+
+ managedBeanClasses.add((String) ReflectUtil.executeMethod(bean, "getManagedBeanClassName"));//bean.getManagedBeanClassName());
+ }
+
+ boolean managedBeanTainted = isAnyManagedBeanTainted(taints, managedBeanClasses);
+ markPersonalScopeRefreshRecommended();
+ getLog().info("[EXT-SCRIPTING] Tainting all beans to avoid classcast exceptions");
+ if (managedBeanTainted)
+ {
+ globalManagedBeanRefresh(mbeansSnapshotView);
+ //personalScopeRefresh();
+ }
+ }
+ }
+
+
+ /**
+ * removes all bean references which have been tainted
+ * (note for now we remove all dynamic references until we
+ * get a more sophisticated handling of managed beans)
+ *
+ * @param workCopy the managed beam snapshot view
+ */
+ private void globalManagedBeanRefresh(Map workCopy)
+ {
+ Collection<ClassResource> tainted = WeavingContext.getInstance().getTaintedClasses();
+ Set<String> taints = new HashSet<String>();
+ for (ClassResource taintedClass : tainted)
+ {
+ if(taintedClass.getAClass() != null)
+ taints.add(taintedClass.getAClass().getName());
+ }
+
+ for (Object entry : workCopy.entrySet())
+ {
+ Object bean = ((Map.Entry) entry).getValue();
+ Class managedBeanClass = (Class) ReflectUtil.executeMethod(bean, "getManagedBeanClass");
+ if (hasToBeRefreshed(taints, managedBeanClass))
+ {
+ //managed bean class found we drop the class from our session
+ removeBeanReferences(bean);
+ }
+ }
+ }
+
+ /**
+ * determines whether any bean in our managed bean list
+ * is tainted or not
+ *
+ * @param tainted a list of classes which are tainted in this iteration
+ * @param managedBeanClasses a ist of classes which are our managed beans
+ * @return true if one of the beans is tainted
+ */
+ private boolean isAnyManagedBeanTainted(Set<String> tainted, Set<String> managedBeanClasses)
+ {
+ boolean managedBeanTainted = false;
+ for (String taintedClass : tainted)
+ {
+ if (managedBeanClasses.contains(taintedClass))
+ {
+ managedBeanTainted = true;
+ break;
+ }
+ }
+ return managedBeanTainted;
+ }
+
+ /**
+ * removes the references from out static scope
+ * for jsf2 we probably have some kind of notification mechanism
+ * which notifies custom scopes
+ *
+ * @param bean the managed bean which all references have to be removed from
+ */
+
+ private void removeBeanReferences(Object bean)
+ {
+ String managedBeanName = (String) ReflectUtil.executeMethod(bean, "getManagedBeanName");
+
+ if (getLog().isLoggable(Level.FINE))
+ {
+ getLog().log(Level.FINE, "[EXT-SCRIPTING] JavaScriptingWeaver.removeBeanReferences({0})", managedBeanName);
+ }
+
+ FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(managedBeanName);
+ FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().remove(managedBeanName);
+ removeCustomScopedBean(bean);
+ }
+
+ /**
+ * @return the log for this class
+ */
+ protected Logger getLog()
+ {
+ return Logger.getLogger(this.getClass().getName());
+ }
+
+ /**
+ * jsf2 helper to remove custom scoped beans
+ *
+ * @param bean the managed bean which has to be removed from the custom scope from
+ */
+ private void removeCustomScopedBean(Object bean)
+ {
+ Object scopeImpl = FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().get(ReflectUtil.executeMethod(bean, "getManagedBeanScope"));
+ if (scopeImpl == null) return; //scope not implemented
+ //we now have to revert to introspection here because scopes are a pure jsf2 construct
+ //so we use a messaging pattern here to cope with it
+
+ Object beanInstance = ReflectUtil.executeMethod(scopeImpl, "get", ReflectUtil.executeMethod(bean, "getManagedBeanName"));
+ LifecycleProvider lifecycleProvider =
+ LifecycleProviderFactory.getLifecycleProviderFactory().getLifecycleProvider(FacesContext.getCurrentInstance().getExternalContext());
+ try
+ {
+ lifecycleProvider.destroyInstance(beanInstance);
+ }
+ catch (IllegalAccessException e)
+ {
+ _logger.log(Level.WARNING, "removeCustomScopedBean():", e);
+ }
+ catch (InvocationTargetException e)
+ {
+ _logger.log(Level.WARNING, "removeCustomScopedBean():", e);
+ }
+ }
+
+ /**
+ * MyFaces 2.0 keeps an immutable map over the session
+ * and request scoped beans
+ * if we alter that during our loop we get a concurrent modification exception
+ * taking a snapshot in time fixes that
+ *
+ * @param mbeans the internal managed bean map which has to be investigated
+ * @return a map with the class name as key and the managed bean info
+ * as value of the current state of the internal runtime config bean map
+ */
+ private Map makeSnapshot(Map mbeans)
+ {
+ Map workCopy;
+
+ workCopy = new HashMap(mbeans.size());
+ for (Object elem : mbeans.entrySet())
+ {
+ Map.Entry entry = (Map.Entry) elem;
+ workCopy.put(entry.getKey(), entry.getValue());
+ }
+
+ return workCopy;
+ }
+
+ /**
+ * sets the internal timer for other processes
+ * to update their beans as well
+ */
+ private void markPersonalScopeRefreshRecommended()
+ {
+ long sessionRefreshTime = System.currentTimeMillis();
+ // WeavingContext.getRefreshContext().setPersonalScopedBeanRefresh(sessionRefreshTime);
+ FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(ScriptingConst.SESS_BEAN_REFRESH_TIMER, sessionRefreshTime);
+ }
+
+ /**
+ * important, this method determines whether a managed bean class
+ * has to be refreshed or not
+ *
+ * @param tainted set of tainted classes
+ * @param managedBeanClass the class to be checked for refresh criteria
+ * @return true if the current bean class fulfills our refresh criteria
+ */
+ protected boolean hasToBeRefreshed(Set<String> tainted, Class managedBeanClass)
+ {
+
+ return WeavingContext.getInstance().isDynamic(managedBeanClass) && tainted.contains(managedBeanClass.getName());
+ }
+
+
+}
+
Copied: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/RefreshPhaseListener.java (from r1300527, myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/AnnotationScanPhaseListener.java)
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/RefreshPhaseListener.java?p2=myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/RefreshPhaseListener.java&p1=myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/AnnotationScanPhaseListener.java&r1=1300527&r2=1300571&rev=1300571&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/AnnotationScanPhaseListener.java (original)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/RefreshPhaseListener.java Wed Mar 14 14:51:12 2012
@@ -34,7 +34,7 @@ import java.util.Map;
* This phase listener is needed because the annotation scanner
* relies on the facesContext to be present, we cannot do without it
*/
-public class AnnotationScanPhaseListener implements PhaseListener
+public class RefreshPhaseListener implements PhaseListener
{
@Override
@@ -51,6 +51,7 @@ public class AnnotationScanPhaseListener
if(params.containsKey("ANN_PROCESSED")) return;
else params.put("ANN_PROCESSED", Boolean.TRUE);
WeavingContext.getInstance().annotationScan();
+ WeavingContext.getInstance().getImplementationSPI().refreshManagedBeans();
}
@Override
Modified: myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/StartupServletContextPluginChainLoader.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/StartupServletContextPluginChainLoader.java?rev=1300571&r1=1300570&r2=1300571&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/StartupServletContextPluginChainLoader.java (original)
+++ myfaces/extensions/scripting/trunk/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/StartupServletContextPluginChainLoader.java Wed Mar 14 14:51:12 2012
@@ -64,6 +64,7 @@ public class StartupServletContextPlugin
ResourceMonitor.getInstance().start();
_log.info("[EXT-SCRIPTING] Startup done");
_log.info("[EXT-SCRIPTING] init the chain loader for class loading");
+ //TODO make this more generic depending on the implementation
MyFacesSPI.getInstance().registerClassloadingExtension(servletContext);
_log.info("[EXT-SCRIPTING] registering the JSF Implementation");
WeavingContext.getInstance().setImplementation(MyFacesSPI.getInstance());