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();
     }