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 2009/09/25 14:29:10 UTC
svn commit: r818833 - in /myfaces/extensions/scripting/trunk/core:
core/src/main/java/ core/src/main/java/org/apache/myfaces/scripting/api/
core/src/main/java/org/apache/myfaces/scripting/loaders/java/
core/src/main/java/org/apache/myfaces/scripting/re...
Author: werpu
Date: Fri Sep 25 12:29:09 2009
New Revision: 818833
URL: http://svn.apache.org/viewvc?rev=818833&view=rev
Log:
https://issues.apache.org/jira/browse/EXTSCRIPT-23
we now deregister classes which have lost their annotations
for now implemented only on managed bean level
the other artefacts have to follow
Added:
myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/
myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourcFileDeltaHolder.java (with props)
myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourceFile.java (with props)
myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourceFilesetState.java
- copied, changed from r818765, myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/AnnotationScanListener.java
myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourceFilesetStateHolder.java
- copied, changed from r818765, myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/AnnotationScanListener.java
Modified:
myfaces/extensions/scripting/trunk/core/core/src/main/java/ideas.txt
myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/AnnotationScanListener.java
myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/loaders/java/JavaScriptingWeaver.java
myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/FileChangedDaemon.java
myfaces/extensions/scripting/trunk/core/myfaces2-extensions/src/main/java/org/apache/myfaces/scripting/jsf2/annotation/BaseAnnotationScanListener.java
myfaces/extensions/scripting/trunk/core/myfaces2-extensions/src/main/java/org/apache/myfaces/scripting/jsf2/annotation/BeanImplementationListener.java
myfaces/extensions/scripting/trunk/core/myfaces2-extensions/src/main/java/org/apache/myfaces/scripting/jsf2/annotation/JavaAnnotationScanner.java
Modified: myfaces/extensions/scripting/trunk/core/core/src/main/java/ideas.txt
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/main/java/ideas.txt?rev=818833&r1=818832&r2=818833&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/main/java/ideas.txt (original)
+++ myfaces/extensions/scripting/trunk/core/core/src/main/java/ideas.txt Fri Sep 25 12:29:09 2009
@@ -39,6 +39,64 @@
+Annotation scanning and recompilation in an language independend manner
+
+Currently:
+We do currently source scanning for annotations this can only work in java
+and only works in a limited manner in java
+
+Goal:
+Annotatons should be processed on the fly and new ones automatically picked up
+and altered ones being reprocessed.
+
+Existing facilities, the class tracker which keeps track of already loaded
+classes.
+The MyFaces configuration object which keeps the data for the beans etc...
+
+Following way should be provided. If an object loading or reinitialisation
+runs into a class not found situation or resource not declared situation,
+track down the sources which are not processed yet and do a compilation of them
+then process the annotation and try to reload the class for further
+processing.
+
+
+Following interception points have to be triggered.
+
+A the scripting weaver has to trigger the tracking code if a class cannot
+be found.
+Upon initial loading for beans etc... in the proxies if a null value
+is given back we have to trigger the scanner and recompiler on this level as well.
+
+Extension to the tracker to deal with removed or renamed files.
+The tracker upon running has to track if the file still exists and if not
+has to remove the file from its list.
+
+Also we have to remove the facilities from the configuration in this case!
+PENDING removal:
+
+
+Following has to be done for now:
+a) provide the annotation scanning upon class loading every time a class
+is loaded via our facilities we have to rescan the annotations
+this can keep track of changes in the managed properties
+
+b) if a class cannot be found on loader level we have to compile all source files of the requested type
+currently not found in the tracker and then try to load it again and reparse it
+if the class still cannot be found we can fall back into the old class not found code
+(probably can be automatable via javac due to its nature of wildcarding)
+
+if a facility under a certain id cannot be found we have to do a recompile of all facilities
+and then do a full reregistration scan of all annotations (note we also should keep
+track of the annotation states so that we can unregister deleted ones )
+
+
+
+
+
+
+
+
+
Modified: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/AnnotationScanListener.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/AnnotationScanListener.java?rev=818833&r1=818832&r2=818833&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/AnnotationScanListener.java (original)
+++ myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/AnnotationScanListener.java Fri Sep 25 12:29:09 2009
@@ -32,10 +32,37 @@
public interface AnnotationScanListener {
+ /**
+ * returns true if the annotation marked by the incoming parameter is supported by this scanner
+ *
+ * @param annotation the supported annotation as neutral string representation of its class
+ * @return in case of support
+ */
public boolean supportsAnnotation(String annotation);
+ /**
+ * registers the class within the myfaces runtime system
+ * within a neutral source representation of this class
+ *
+ * @param clazz the class as neutral definition (currently qdox JavaClass only)
+ * @param annotationName the annotation name
+ * @param params a map of annotation params
+ */
public void registerSource(Object clazz, String annotationName, Map<String, Object> params);
+ /**
+ * class file registration of the supported annotation
+ *
+ * @param clazz
+ * @param annotationName
+ */
public void register(Class clazz, Annotation annotationName);
+ /**
+ * purges the class from the correct places of the myfaces registry
+ * so that the artefact is not reachable anymore
+ *
+ * @param className
+ */
+ public void purge(String className);
}
Modified: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/loaders/java/JavaScriptingWeaver.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/loaders/java/JavaScriptingWeaver.java?rev=818833&r1=818832&r2=818833&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/loaders/java/JavaScriptingWeaver.java (original)
+++ myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/loaders/java/JavaScriptingWeaver.java Fri Sep 25 12:29:09 2009
@@ -143,7 +143,19 @@
refreshReloadingMetaData(sourceRoot, file, currentClassFile, retVal, ScriptingConst.ENGINE_TYPE_JAVA);
}
-
+ /**
+ * we now scan the return value and update its configuration parameters if needed
+ * this can help to deal with method level changes of class files like managed properties
+ * or scope changes from shorter running scopes to longer running ones
+ * if the annotation has been moved the class will be deregistered but still delivered for now
+ *
+ * at the next refresh the second step of the registration cycle should pick the new class up
+ * //TODO we have to mark the artefacting class as deregistered and then enforce
+ * //a reload this is however not the scope of the commit of this subtask
+ * //we only deal with class level reloading here
+ * //the deregistration notification should happen on artefact level (which will be the next subtask)
+ */
+ _scanner.scanClass(retVal);
return retVal;
}
Modified: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/FileChangedDaemon.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/FileChangedDaemon.java?rev=818833&r1=818832&r2=818833&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/FileChangedDaemon.java (original)
+++ myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/FileChangedDaemon.java Fri Sep 25 12:29:09 2009
@@ -24,9 +24,7 @@
import org.apache.myfaces.scripting.api.ScriptingWeaver;
import java.io.File;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
/**
@@ -50,6 +48,9 @@
//should replace the map with something segmented, probably
//a balanced tree of depth 2
Map<String, ReloadingMetadata> classMap = Collections.synchronizedMap(new HashMap<String, ReloadingMetadata>());
+
+
+
boolean running = false;
Log log = LogFactory.getLog(FileChangedDaemon.class);
ScriptingWeaver _weavers = null;
Added: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourcFileDeltaHolder.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourcFileDeltaHolder.java?rev=818833&view=auto
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourcFileDeltaHolder.java (added)
+++ myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourcFileDeltaHolder.java Fri Sep 25 12:29:09 2009
@@ -0,0 +1,101 @@
+/*
+ * 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.scripting.refresh.sourceTracking;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ * <p/>
+ * We need additonal data structures which keep track of
+ * the current state of the source files, to be able
+ * to deal with annotations in a decent way
+ *
+ * For annotations we have to trigger the compiler as soon
+ * as a resolver runs into a class not exists situation
+ *
+ */
+
+public class SourcFileDeltaHolder {
+
+ public static final int STATE_INITIAL = 1;
+ public static final int STATE_ADDED = 2;
+ public static final int STATE_DELETED = 3;
+
+
+ /**
+ * state holder
+ */
+ SourceFilesetStateHolder _initialState = new SourceFilesetStateHolder();
+ SourceFilesetStateHolder _added = new SourceFilesetStateHolder();
+ SourceFilesetStateHolder _deleted = new SourceFilesetStateHolder();
+
+ public SourceFilesetState getFilesetState(int state, Integer engineType) {
+ SourceFilesetState retVal = null;
+ switch (state) {
+ case STATE_INITIAL:
+ return getFileSetState(engineType, _initialState);
+
+ case STATE_ADDED:
+ return getFileSetState(engineType, _added);
+
+ case STATE_DELETED:
+ return getFileSetState(engineType, _deleted);
+
+ default:
+ break;
+ }
+
+ return null;
+ }
+
+ private SourceFilesetState getFileSetState(Integer engineType, SourceFilesetStateHolder holder) {
+ SourceFilesetState retVal = null;
+ retVal = _initialState.get(engineType);
+ if (retVal == null) {
+ retVal = new SourceFilesetState();
+ _initialState.put(engineType, retVal);
+ }
+ return retVal;
+ }
+
+
+ public SourceFilesetStateHolder getInitialState() {
+ return _initialState;
+ }
+
+ public void setInitialState(SourceFilesetStateHolder initialState) {
+ _initialState = initialState;
+ }
+
+ public SourceFilesetStateHolder getAdded() {
+ return _added;
+ }
+
+ public void setAdded(SourceFilesetStateHolder added) {
+ _added = added;
+ }
+
+ public SourceFilesetStateHolder getDeleted() {
+ return _deleted;
+ }
+
+ public void setDeleted(SourceFilesetStateHolder deleted) {
+ _deleted = deleted;
+ }
+}
Propchange: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourcFileDeltaHolder.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourcFileDeltaHolder.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourceFile.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourceFile.java?rev=818833&view=auto
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourceFile.java (added)
+++ myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourceFile.java Fri Sep 25 12:29:09 2009
@@ -0,0 +1,74 @@
+/*
+ * 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.scripting.refresh.sourceTracking;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+
+public class SourceFile {
+ File _sourceFile = null;
+ String _rootPath = null;
+
+
+ public SourceFile(File sourceFile, String rootPath) {
+ _sourceFile = sourceFile;
+ _rootPath = rootPath;
+ }
+
+ public File getSourceFile() {
+ return _sourceFile;
+ }
+
+ public void setSourceFile(File sourceFile) {
+ _sourceFile = sourceFile;
+ }
+
+ public String getRootPath() {
+ return _rootPath;
+ }
+
+ public void setRootPath(String rootPath) {
+ _rootPath = rootPath;
+ }
+
+ public boolean equals(Object target) {
+ if (target == null) {
+ return false;
+ }
+ if (!(target instanceof SourceFile)) {
+ return false;
+ }
+
+ if (_sourceFile == null && ((SourceFile) target).getSourceFile() == null) {
+ return true;
+ }
+ try {
+ return _sourceFile.getCanonicalPath().equals(((SourceFile) target).getSourceFile().getCanonicalPath());
+ } catch (IOException e) {
+ return false;
+ }
+
+ }
+
+}
Propchange: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourceFile.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourceFile.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Copied: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourceFilesetState.java (from r818765, myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/AnnotationScanListener.java)
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourceFilesetState.java?p2=myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourceFilesetState.java&p1=myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/AnnotationScanListener.java&r1=818765&r2=818833&rev=818833&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/AnnotationScanListener.java (original)
+++ myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourceFilesetState.java Fri Sep 25 12:29:09 2009
@@ -16,26 +16,20 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.myfaces.scripting.api;
+package org.apache.myfaces.scripting.refresh.sourceTracking;
-
-import java.util.Map;
-import java.lang.annotation.Annotation;
+import java.util.HashSet;
+import java.util.Set;
/**
* @author Werner Punz (latest modification by $Author$)
* @version $Revision$ $Date$
- * <p/>
- * We use a source code artefact observer here to register the
- * meta data in the correct registry entries
*/
-public interface AnnotationScanListener {
-
- public boolean supportsAnnotation(String annotation);
-
- public void registerSource(Object clazz, String annotationName, Map<String, Object> params);
-
- public void register(Class clazz, Annotation annotationName);
-
+public class SourceFilesetState {
+ /**
+ * key canonical name,
+ * entry, relative fi
+ */
+ Set<SourceFile> _fileSet= new HashSet<SourceFile>();
}
Copied: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourceFilesetStateHolder.java (from r818765, myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/AnnotationScanListener.java)
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourceFilesetStateHolder.java?p2=myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourceFilesetStateHolder.java&p1=myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/AnnotationScanListener.java&r1=818765&r2=818833&rev=818833&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/api/AnnotationScanListener.java (original)
+++ myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/refresh/sourceTracking/SourceFilesetStateHolder.java Fri Sep 25 12:29:09 2009
@@ -16,26 +16,36 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.myfaces.scripting.api;
-
+package org.apache.myfaces.scripting.refresh.sourceTracking;
import java.util.Map;
-import java.lang.annotation.Annotation;
+import java.util.HashMap;
/**
* @author Werner Punz (latest modification by $Author$)
* @version $Revision$ $Date$
- * <p/>
- * We use a source code artefact observer here to register the
- * meta data in the correct registry entries
+ *
+ * a generic state holder which can keep track of multiple source files
+ * depending on the engine type
*/
-public interface AnnotationScanListener {
-
- public boolean supportsAnnotation(String annotation);
-
- public void registerSource(Object clazz, String annotationName, Map<String, Object> params);
+public class SourceFilesetStateHolder {
+ Map<Integer, SourceFilesetState> _added = new HashMap<Integer, SourceFilesetState>();
- public void register(Class clazz, Annotation annotationName);
+ public void put(Integer engineType, SourceFilesetState state) {
+ _added.put(engineType, state);
+ }
+
+ public SourceFilesetState get(Integer engineType) {
+ return _added.get(engineType);
+ }
+
+ public void clear() {
+ _added.clear();
+ }
+
+ public void remove(Integer engineType) {
+ _added.remove(engineType);
+ }
}
Modified: myfaces/extensions/scripting/trunk/core/myfaces2-extensions/src/main/java/org/apache/myfaces/scripting/jsf2/annotation/BaseAnnotationScanListener.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/myfaces2-extensions/src/main/java/org/apache/myfaces/scripting/jsf2/annotation/BaseAnnotationScanListener.java?rev=818833&r1=818832&r2=818833&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/myfaces2-extensions/src/main/java/org/apache/myfaces/scripting/jsf2/annotation/BaseAnnotationScanListener.java (original)
+++ myfaces/extensions/scripting/trunk/core/myfaces2-extensions/src/main/java/org/apache/myfaces/scripting/jsf2/annotation/BaseAnnotationScanListener.java Fri Sep 25 12:29:09 2009
@@ -64,4 +64,16 @@
Class val = (Class) propVal.getParameterValue();
return val;
}
+
+
+ /**
+ * unregisters this class in the central registry
+ * is triggered if the class itself has been registered previously
+ *
+ * @param className
+ * @return
+ */
+ public void purge(String className) {
+
+ }
}
Modified: myfaces/extensions/scripting/trunk/core/myfaces2-extensions/src/main/java/org/apache/myfaces/scripting/jsf2/annotation/BeanImplementationListener.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/myfaces2-extensions/src/main/java/org/apache/myfaces/scripting/jsf2/annotation/BeanImplementationListener.java?rev=818833&r1=818832&r2=818833&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/myfaces2-extensions/src/main/java/org/apache/myfaces/scripting/jsf2/annotation/BeanImplementationListener.java (original)
+++ myfaces/extensions/scripting/trunk/core/myfaces2-extensions/src/main/java/org/apache/myfaces/scripting/jsf2/annotation/BeanImplementationListener.java Fri Sep 25 12:29:09 2009
@@ -22,6 +22,7 @@
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaField;
import org.apache.myfaces.config.RuntimeConfig;
+import org.apache.myfaces.config.element.NavigationRule;
import org.apache.myfaces.config.impl.digester.elements.ManagedBean;
import org.apache.myfaces.scripting.api.AnnotationScanListener;
import org.apache.myfaces.scripting.core.util.ReflectUtil;
@@ -30,6 +31,8 @@
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
+import java.util.Collection;
+import java.util.ArrayList;
/**
* @author Werner Punz (latest modification by $Author$)
@@ -42,11 +45,12 @@
public class BeanImplementationListener extends BaseAnnotationScanListener implements AnnotationScanListener {
- private static final String SCOPE_SESSION = "session";
- private static final String SCOPE_APPLICATION = "application";
- private static final String SCOPE_VIEW = "view";
- private static final String SCOPE_NONE = "none";
- private static final String SCOPE_CUSTOM = "custom";
+ private static final String SCOPE_SESSION = "session";
+ private static final String SCOPE_APPLICATION = "application";
+ private static final String SCOPE_VIEW = "view";
+ private static final String SCOPE_NONE = "none";
+ private static final String SCOPE_CUSTOM = "custom";
+
public boolean supportsAnnotation(String annotation) {
return annotation.equals(javax.faces.bean.ManagedBean.class.getName());
@@ -277,4 +281,33 @@
ManagedBean mbean = (ManagedBean) _alreadyRegistered.get(name);
return mbean == null || !mbean.getManagedBeanClassName().equals(clazz.getFullyQualifiedName());
}
+
+ @SuppressWarnings("unchecked")
+ public void purge(String className) {
+ RuntimeConfig config = getRuntimeConfig();
+ //We have to purge and readd our managed beans, unfortunatly the myfaces impl enforces
+ //us to do the same for the nav rules after purge
+ //we cannot purge the managed beans and nav rules separately
+ Collection<NavigationRule> navigationRules = new ArrayList<NavigationRule>();
+ Map<String, org.apache.myfaces.config.element.ManagedBean> managedBeans = new HashMap<String, org.apache.myfaces.config.element.ManagedBean>();
+
+ navigationRules.addAll(config.getNavigationRules());
+ managedBeans.putAll(config.getManagedBeans());
+
+ config.purge();
+
+ for (NavigationRule navRule : navigationRules) {
+ config.addNavigationRule(navRule);
+ }
+
+ //We refresh the managed beans, dead references still can cause
+ //runtime errors but in this case we cannot do anything
+ for (Map.Entry mbean : managedBeans.entrySet()) {
+ org.apache.myfaces.config.element.ManagedBean bean = (org.apache.myfaces.config.element.ManagedBean) mbean.getValue();
+ if (!bean.getClass().getName().equals(className)) {
+ config.addManagedBean((String) mbean.getKey(), (org.apache.myfaces.config.element.ManagedBean) mbean.getValue());
+ }
+ }
+
+ }
}
Modified: myfaces/extensions/scripting/trunk/core/myfaces2-extensions/src/main/java/org/apache/myfaces/scripting/jsf2/annotation/JavaAnnotationScanner.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/myfaces2-extensions/src/main/java/org/apache/myfaces/scripting/jsf2/annotation/JavaAnnotationScanner.java?rev=818833&r1=818832&r2=818833&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/myfaces2-extensions/src/main/java/org/apache/myfaces/scripting/jsf2/annotation/JavaAnnotationScanner.java (original)
+++ myfaces/extensions/scripting/trunk/core/myfaces2-extensions/src/main/java/org/apache/myfaces/scripting/jsf2/annotation/JavaAnnotationScanner.java Fri Sep 25 12:29:09 2009
@@ -24,11 +24,12 @@
import com.thoughtworks.qdox.model.JavaSource;
import org.apache.myfaces.scripting.api.AnnotationScanListener;
import org.apache.myfaces.scripting.api.AnnotationScanner;
-import org.vafer.dependency.Clazz;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
/**
* @author Werner Punz (latest modification by $Author$)
@@ -44,6 +45,8 @@
List<AnnotationScanListener> _listeners = new LinkedList<AnnotationScanListener>();
JavaDocBuilder _builder = new JavaDocBuilder();
+ Map<String, String> _registeredAnnotations = new HashMap<String, String>();
+
public JavaAnnotationScanner() {
initDefaultListeners();
@@ -63,14 +66,13 @@
}
public void scanClass(Class clazz) {
- java.lang.annotation.Annotation[] anns = clazz.getAnnotations();
- for (java.lang.annotation.Annotation ann : anns) {
+ //java.lang.annotation.Annotation[] anns = clazz.getAnnotations();
- for (AnnotationScanListener listener : _listeners) {
- if (listener.supportsAnnotation(ann.getClass().getName())) {
- listener.register(clazz, ann);
- }
- }
+ java.lang.annotation.Annotation[] anns = clazz.getAnnotations();
+ if (anns != null || anns.length > 0) {
+ addOrMoveAnnotations(clazz);
+ } else {
+ removeAnnotations(clazz);
}
}
@@ -100,19 +102,128 @@
JavaClass[] classes = source.getClasses();
for (JavaClass clazz : classes) {
Annotation[] anns = clazz.getAnnotations();
- for (Annotation ann : anns) {
+ if (anns != null || anns.length > 0) {
+ addOrMoveAnnotations(clazz, anns);
+ } else {
+ removeAnnotations(clazz);
+ }
+ }
+
+ }
+ }
+
+ /**
+ * add or moves a class level annotation
+ * to a new place
+ *
+ * @param clazz
+ * @param anns
+ */
+ private void addOrMoveAnnotations(JavaClass clazz, Annotation[] anns) {
+ for (Annotation ann : anns) {
+ for (AnnotationScanListener listener : _listeners) {
+ if (listener.supportsAnnotation(ann.getType().getValue())) {
+ listener.registerSource(
+ clazz, ann.getType().getValue(), ann.getPropertyMap());
+
+ _registeredAnnotations.put(clazz.getFullyQualifiedName(), ann.getType().getValue());
+ } else {
+ annotationMoved(clazz, ann, listener);
+
+ }
+ }
+ }
+ }
+
+ /**
+ * add or moves a class level annotation
+ * to a new place
+ *
+ * @param clazz
+ */
+ private void addOrMoveAnnotations(Class clazz) {
+ java.lang.annotation.Annotation[] anns = clazz.getAnnotations();
+ for (java.lang.annotation.Annotation ann : anns) {
+ for (AnnotationScanListener listener : _listeners) {
+ if (listener.supportsAnnotation(ann.getClass().getName())) {
+ listener.register(clazz, ann);
+
+ _registeredAnnotations.put(clazz.getName(), ann.getClass().getName());
+ } else {
+ annotationMoved(clazz, ann, listener);
+
+ }
+ }
+ }
+ }
+
+ /**
+ * use case annotation removed
+ * we have to entirely remove the annotation
+ * from our internal registry and the myfaces registry
+ *
+ * @param clazz
+ */
+ private void removeAnnotations(JavaClass clazz) {
+ String registeredAnnotation = _registeredAnnotations.get(clazz.getFullyQualifiedName());
+ if (registeredAnnotation != null) {
+ for (AnnotationScanListener listener : _listeners) {
+ if (listener.supportsAnnotation(registeredAnnotation)) {
+ listener.purge(clazz.getFullyQualifiedName());
+ _registeredAnnotations.remove(clazz.getFullyQualifiedName());
+
+ }
+ }
+ }
+ }
+
+ /**
+ * use case annotation removed
+ * we have to entirely remove the annotation
+ * from our internal registry and the myfaces registry
+ *
+ * @param clazz
+ */
+ private void removeAnnotations(Class clazz) {
+ String registeredAnnotation = _registeredAnnotations.get(clazz.getName());
+ if (registeredAnnotation != null) {
+ for (AnnotationScanListener listener : _listeners) {
+ if (listener.supportsAnnotation(registeredAnnotation)) {
+ listener.purge(clazz.getName());
+ _registeredAnnotations.remove(clazz.getName());
- for (AnnotationScanListener listener : _listeners) {
- if (listener.supportsAnnotation(ann.getType().getValue())) {
- listener.registerSource(
- clazz, ann.getType().getValue(), ann.getPropertyMap());
- }
- }
}
}
}
}
+
+ /**
+ * use case annotation moved
+ * we have to remove the annotation from the myfaces registry of the old
+ * listeners place, the new entry is done in the first step add or move
+ *
+ * @param clazz
+ * @param ann
+ * @param listener
+ */
+ private void annotationMoved(JavaClass clazz, Annotation ann, AnnotationScanListener listener) {
+ //case class exists but it has been moved to anoter annotation
+ String registeredAnnotation = _registeredAnnotations.get(clazz.getFullyQualifiedName());
+ if (registeredAnnotation != null && registeredAnnotation.equals(ann.getType().getValue())) {
+ listener.purge(clazz.getFullyQualifiedName());
+ }
+ }
+
+ private void annotationMoved(Class clazz, java.lang.annotation.Annotation ann, AnnotationScanListener listener) {
+ //case class exists but it has been moved to anoter annotation
+ String registeredAnnotation = _registeredAnnotations.get(clazz.getName());
+ if (registeredAnnotation != null && registeredAnnotation.equals(ann.getClass().getName())) {
+ listener.purge(clazz.getName());
+ }
+ }
+
+
public void clearListeners() {
_listeners.clear();
}