geronimo-xbean-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dblev...@apache.org
Subject svn commit: r1084087 [1/2] - in /geronimo/xbean/trunk/xbean-finder/src: main/java/org/apache/xbean/finder/ test/java/org/apache/xbean/finder/
Date Tue, 22 Mar 2011 07:35:15 GMT
Author: dblevins
Date: Tue Mar 22 07:35:14 2011
New Revision: 1084087

URL: http://svn.apache.org/viewvc?rev=1084087&view=rev
Log:
XBEAN-165: Meta Annotation Support
Not complete just, but basically working and is more code than I care to lose :) (call me paranoid)

Added:
    geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotatedMember.java   (with props)
    geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotatedMethod.java   (with props)
    geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotatedTarget.java   (with props)
    geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/Archive.java   (with props)
    geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/BundleArchive.java   (with props)
    geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/Classes.java   (with props)
    geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/ClassesArchive.java   (with props)
    geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/ClasspathArchive.java   (with props)
    geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MetaAnnotation.java   (with props)
    geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MetaAnnotationFinder.java   (contents, props changed)
      - copied, changed from r1079521, geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AbstractFinder.java
    geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/Metatype.java   (with props)
    geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/PackageFilteredArchive.java   (with props)
    geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/PrefixFilteredArchive.java   (with props)
    geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/RegexFilteredArchive.java   (with props)
    geronimo/xbean/trunk/xbean-finder/src/test/java/org/apache/xbean/finder/MetaAnnotatedClassTest.java   (with props)
    geronimo/xbean/trunk/xbean-finder/src/test/java/org/apache/xbean/finder/MetaAnnotatedMethodTest.java   (with props)

Added: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotatedMember.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotatedMember.java?rev=1084087&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotatedMember.java (added)
+++ geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotatedMember.java Tue Mar 22 07:35:14 2011
@@ -0,0 +1,27 @@
+/**
+ * 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.xbean.finder;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Member;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface AnnotatedMember<T> extends AnnotatedTarget<T>, Member {
+
+}

Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotatedMember.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotatedMethod.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotatedMethod.java?rev=1084087&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotatedMethod.java (added)
+++ geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotatedMethod.java Tue Mar 22 07:35:14 2011
@@ -0,0 +1,41 @@
+/**
+ * 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.xbean.finder;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface AnnotatedMethod<T> extends AnnotatedMember<T> {
+
+    public Annotation[][] getParameterAnnotations();
+
+    public Class<?>[] getExceptionTypes();
+
+    public Class<?>[] getParameterTypes();
+
+    public String toGenericString();
+
+    public Type[] getGenericExceptionTypes();
+
+    public Type[] getGenericParameterTypes();
+
+    public boolean isVarArgs();
+
+}
\ No newline at end of file

Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotatedMethod.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotatedTarget.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotatedTarget.java?rev=1084087&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotatedTarget.java (added)
+++ geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotatedTarget.java Tue Mar 22 07:35:14 2011
@@ -0,0 +1,29 @@
+/**
+ * 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.xbean.finder;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.GenericDeclaration;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface AnnotatedTarget<T> extends AnnotatedElement, GenericDeclaration {
+
+    T getTarget();
+
+}

Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AnnotatedTarget.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/Archive.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/Archive.java?rev=1084087&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/Archive.java (added)
+++ geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/Archive.java Tue Mar 22 07:35:14 2011
@@ -0,0 +1,31 @@
+/**
+ * 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.xbean.finder;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface Archive extends Iterable<String> {
+
+    InputStream getBytecode(String className) throws IOException, ClassNotFoundException;
+
+    Class<?> loadClass(String className) throws ClassNotFoundException;
+
+}

Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/Archive.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/BundleArchive.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/BundleArchive.java?rev=1084087&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/BundleArchive.java (added)
+++ geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/BundleArchive.java Tue Mar 22 07:35:14 2011
@@ -0,0 +1,102 @@
+/**
+ * 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.xbean.finder;
+
+import org.apache.xbean.osgi.bundle.util.BundleResourceFinder;
+import org.apache.xbean.osgi.bundle.util.ResourceDiscoveryFilter;
+import org.osgi.framework.Bundle;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.zip.ZipEntry;
+
+/**
+ * TODO Unfinished
+ * @version $Rev$ $Date$
+ */
+public class BundleArchive implements Archive {
+
+    private final Bundle bundle;
+
+    public BundleArchive(PackageAdmin packageAdmin, Bundle bundle) throws Exception {
+        this(packageAdmin, bundle, BundleResourceFinder.FULL_DISCOVERY_FILTER);
+    }
+
+    public BundleArchive(PackageAdmin packageAdmin, Bundle bundle, ResourceDiscoveryFilter discoveryFilter) throws Exception {
+        this.bundle = bundle;
+        BundleResourceFinder bundleResourceFinder = new BundleResourceFinder(packageAdmin, bundle, "", ".class", discoveryFilter);
+        bundleResourceFinder.find(new AnnotationFindingCallback());
+    }
+
+    @Override
+    public Iterator<String> iterator() {
+        // TODO
+        return Collections.EMPTY_LIST.iterator();
+    }
+
+    @Override
+    public InputStream getBytecode(String className) throws IOException, ClassNotFoundException {
+        int pos = className.indexOf("<");
+        if (pos > -1) {
+            className = className.substring(0, pos);
+        }
+        pos = className.indexOf(">");
+        if (pos > -1) {
+            className = className.substring(0, pos);
+        }
+        if (!className.endsWith(".class")) {
+            className = className.replace('.', '/') + ".class";
+        }
+
+        URL resource = bundle.getResource(className);
+        if (resource != null) return resource.openStream();
+
+        throw new ClassNotFoundException(className);
+    }
+
+    @Override
+    public Class<?> loadClass(String s) throws ClassNotFoundException {
+        return bundle.loadClass(s);
+    }
+
+    private class AnnotationFindingCallback implements BundleResourceFinder.ResourceFinderCallback {
+
+        public boolean foundInDirectory(Bundle bundle, String baseDir, URL url) throws Exception {
+            InputStream in = url.openStream();
+            try {
+                //TODO
+//                readClassDef(in);
+            } finally {
+                in.close();
+            }
+            return true;
+        }
+
+
+        public boolean foundInJar(Bundle bundle, String jarName, ZipEntry entry, InputStream in) throws Exception {
+            //TODO
+//            readClassDef(in);
+            return true;
+        }
+    }
+
+
+}
\ No newline at end of file

Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/BundleArchive.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/Classes.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/Classes.java?rev=1084087&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/Classes.java (added)
+++ geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/Classes.java Tue Mar 22 07:35:14 2011
@@ -0,0 +1,96 @@
+/**
+ * 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.xbean.finder;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Classes {
+
+    private static final Map<Class<?>, Class<?>> primitiveWrappers = new HashMap<Class<?>, Class<?>>();
+    private static final HashMap<String, Class> primitives = new HashMap<String, Class>();
+
+    static {
+        primitives.put("boolean", boolean.class);
+        primitives.put("byte", byte.class);
+        primitives.put("char", char.class);
+        primitives.put("short", short.class);
+        primitives.put("int", int.class);
+        primitives.put("long", long.class);
+        primitives.put("float", float.class);
+        primitives.put("double", double.class);
+
+        primitiveWrappers.put(boolean.class, Boolean.class);
+        primitiveWrappers.put(byte.class, Byte.class);
+        primitiveWrappers.put(char.class, Character.class);
+        primitiveWrappers.put(double.class, Double.class);
+        primitiveWrappers.put(float.class, Float.class);
+        primitiveWrappers.put(int.class, Integer.class);
+        primitiveWrappers.put(long.class, Long.class);
+        primitiveWrappers.put(short.class, Short.class);
+    }
+
+    public static boolean equals(String classNameA, String classNameB) {
+        return classNameA.equals(classNameB);
+    }
+
+    public static Class forName(String string, ClassLoader classLoader) throws ClassNotFoundException {
+        int arrayDimentions = 0;
+        while (string.endsWith("[]")){
+            string = string.substring(0, string.length() - 2);
+            arrayDimentions++;
+        }
+
+        Class clazz = primitives.get(string);
+
+        if (clazz == null) clazz = Class.forName(string, true, classLoader);
+
+        if (arrayDimentions == 0){
+            return clazz;
+        }
+        return Array.newInstance(clazz, new int[arrayDimentions]).getClass();
+    }
+
+    public static String packageName(Class clazz){
+        return packageName(clazz.getName());
+    }
+
+    public static String packageName(String clazzName){
+        int i = clazzName.lastIndexOf('.');
+        if (i > 0){
+            return clazzName.substring(0, i);
+        } else {
+            return "";
+        }
+    }
+
+    public static List<String> getSimpleNames(Class... classes){
+        List<String> list = new ArrayList<String>();
+        for (Class aClass : classes) {
+            list.add(aClass.getSimpleName());
+        }
+
+        return list;
+    }
+
+    public static Class<?> deprimitivize(Class<?> fieldType) {
+        return fieldType = fieldType.isPrimitive() ? primitiveWrappers.get(fieldType): fieldType;
+    }
+}

Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/Classes.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/ClassesArchive.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/ClassesArchive.java?rev=1084087&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/ClassesArchive.java (added)
+++ geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/ClassesArchive.java Tue Mar 22 07:35:14 2011
@@ -0,0 +1,88 @@
+/**
+ * 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.xbean.finder;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ClassesArchive implements Archive {
+
+    private final Set<ClassLoader> loaders = new LinkedHashSet<ClassLoader>();
+    private final Map<String, Class<?>> classes = new LinkedHashMap<String, Class<?>>();
+
+    public ClassesArchive(Class<?>... classes) {
+        this(Arrays.asList(classes));
+    }
+
+    public ClassesArchive(Iterable<Class<?>> classes) {
+        for (Class<?> clazz : classes) {
+            this.classes.put(clazz.getName(), clazz);
+            loaders.add(clazz.getClassLoader());
+        }
+    }
+
+    @Override
+    public Iterator<String> iterator() {
+        return classes.keySet().iterator();
+    }
+
+    @Override
+    public InputStream getBytecode(String className) throws IOException, ClassNotFoundException {
+        int pos = className.indexOf("<");
+        if (pos > -1) {
+            className = className.substring(0, pos);
+        }
+        pos = className.indexOf(">");
+        if (pos > -1) {
+            className = className.substring(0, pos);
+        }
+        if (!className.endsWith(".class")) {
+            className = className.replace('.', '/') + ".class";
+        }
+        for (ClassLoader loader : loaders) {
+            URL resource = loader.getResource(className);
+            if (resource != null) return resource.openStream();
+        }
+
+        throw new ClassNotFoundException(className);
+    }
+
+    @Override
+    public Class<?> loadClass(String className) throws ClassNotFoundException {
+        Class<?> clazz = classes.get(className);
+        if (clazz != null) return clazz;
+
+        for (ClassLoader loader : loaders) {
+            try {
+                return loader.loadClass(className);
+            } catch (ClassNotFoundException e) {
+            }
+        }
+
+        throw new ClassNotFoundException(className);
+    }
+}

Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/ClassesArchive.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/ClasspathArchive.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/ClasspathArchive.java?rev=1084087&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/ClasspathArchive.java (added)
+++ geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/ClasspathArchive.java Tue Mar 22 07:35:14 2011
@@ -0,0 +1,78 @@
+/**
+ * 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.xbean.finder;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * TODO Unfinished
+ * @version $Rev$ $Date$
+ */
+public class ClasspathArchive implements Archive {
+
+    private final List<URL> urls = new ArrayList<URL>();
+    private final ClassLoader loader;
+
+    public ClasspathArchive(ClassLoader loader, URL... urls) {
+        this(loader, Arrays.asList(urls));
+    }
+
+    public ClasspathArchive(ClassLoader loader, Iterable<URL> urls) {
+        this.loader = loader;
+        for (URL url : urls) {
+            this.urls.add(url);
+        }
+    }
+
+    @Override
+    public Iterator<String> iterator() {
+        // TODO
+        return Collections.EMPTY_LIST.iterator();
+    }
+
+    @Override
+    public InputStream getBytecode(String className) throws IOException, ClassNotFoundException {
+        int pos = className.indexOf("<");
+        if (pos > -1) {
+            className = className.substring(0, pos);
+        }
+        pos = className.indexOf(">");
+        if (pos > -1) {
+            className = className.substring(0, pos);
+        }
+        if (!className.endsWith(".class")) {
+            className = className.replace('.', '/') + ".class";
+        }
+
+        URL resource = loader.getResource(className);
+        if (resource != null) return resource.openStream();
+
+        throw new ClassNotFoundException(className);
+    }
+
+    @Override
+    public Class<?> loadClass(String className) throws ClassNotFoundException {
+        return loader.loadClass(className);
+    }
+}
\ No newline at end of file

Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/ClasspathArchive.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MetaAnnotation.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MetaAnnotation.java?rev=1084087&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MetaAnnotation.java (added)
+++ geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MetaAnnotation.java Tue Mar 22 07:35:14 2011
@@ -0,0 +1,40 @@
+/**
+ * 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.xbean.finder;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+
+/**
+* @version $Rev$ $Date$
+*/
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ANNOTATION_TYPE)
+public @interface MetaAnnotation {
+Class<? extends Annotation> value();
+}
\ No newline at end of file

Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MetaAnnotation.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MetaAnnotationFinder.java (from r1079521, geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AbstractFinder.java)
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MetaAnnotationFinder.java?p2=geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MetaAnnotationFinder.java&p1=geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AbstractFinder.java&r1=1079521&r2=1084087&rev=1084087&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/AbstractFinder.java (original)
+++ geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MetaAnnotationFinder.java Tue Mar 22 07:35:14 2011
@@ -20,47 +20,78 @@
 
 package org.apache.xbean.finder;
 
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.EmptyVisitor;
+import org.objectweb.asm.signature.SignatureReader;
+import org.objectweb.asm.signature.SignatureVisitor;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.annotation.Annotation;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
+import java.lang.reflect.Member;
 import java.lang.reflect.Method;
-import java.net.URL;
+import java.lang.reflect.TypeVariable;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.commons.EmptyVisitor;
-import org.objectweb.asm.signature.SignatureReader;
-import org.objectweb.asm.signature.SignatureVisitor;
+import java.util.Set;
 
 /**
  * @version $Rev$ $Date$
  */
-public abstract class AbstractFinder {
+public class MetaAnnotationFinder {
+
+    private final Set<Class<? extends Annotation>> metaroots = new HashSet<Class<? extends Annotation>>();
+    {
+        metaroots.add(Metatype.class);
+    }
+    
     private final Map<String, List<Info>> annotated = new HashMap<String, List<Info>>();
+
     protected final Map<String, ClassInfo> classInfos = new HashMap<String, ClassInfo>();
     private final List<String> classesNotLoaded = new ArrayList<String>();
-    private final int ASM_FLAGS = ClassReader.SKIP_CODE + ClassReader.SKIP_DEBUG + ClassReader.SKIP_FRAMES;
+    private final int ASM_FLAGS = 0;//ClassReader.SKIP_CODE + ClassReader.SKIP_DEBUG + ClassReader.SKIP_FRAMES;
+    private final Archive archive;
 
-    protected abstract URL getResource(String className);
+    public MetaAnnotationFinder(Archive archive) {
+        this.archive = archive;
+
+        for (String className : this.archive) {
+            try {
+                readClassDef(archive.getBytecode(className));
+            } catch (NoClassDefFoundError e) {
+                throw new NoClassDefFoundError("Could not fully load class: " + className + "\n due to:" + e.getMessage());
+            } catch (ClassNotFoundException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
 
-    protected abstract Class<?> loadClass(String fixedName) throws ClassNotFoundException;
 
     /**
      * The link() method must be called to successfully use the findSubclasses and findImplementations methods
+     *
      * @return
-     * @throws IOException
+     * @throws java.io.IOException
      */
-    public AbstractFinder link() throws IOException {
+    public MetaAnnotationFinder link() throws IOException, ClassNotFoundException {
         for (ClassInfo classInfo : classInfos.values().toArray(new ClassInfo[classInfos.size()])) {
 
             linkParent(classInfo);
@@ -69,15 +100,54 @@ public abstract class AbstractFinder {
         for (ClassInfo classInfo : classInfos.values().toArray(new ClassInfo[classInfos.size()])) {
 
             linkInterfaces(classInfo);
+
         }
 
+        // diff new and old lists
+        resolveAnnotations(new ArrayList<String>());
+
         return this;
     }
 
-    private void linkParent(ClassInfo classInfo) throws IOException {
+    /**
+     * Used to support meta annotations
+     * <p/>
+     * Once the list of classes has been read from the Archive, we
+     * iterate over all the annotations that are used by those classes
+     * and recursively resolve any annotations those annotations use.
+     *
+     * @param scanned
+     * @throws ClassNotFoundException
+     * @throws IOException
+     */
+    private void resolveAnnotations(List<String> scanned) throws ClassNotFoundException, IOException {
+
+        // Get a list of the annotations that exist before we start
+        List<String> annotations = new ArrayList<String>(annotated.keySet());
+
+        for (String annotation : annotations) {
+            if (scanned.contains(annotation)) continue;
+            readClassDef(annotation);
+        }
+
+        for (Info info : annotated.get(Metatype.class.getName())) {
+            try {
+                readClassDef(info.getName() + "$$");
+            } catch (ClassNotFoundException e) {
+                // we don't care, this is only a convenience
+            }
+        }
+
+        // If the "annotated" list has grown, then we must scan those
+        if (annotated.keySet().size() != annotations.size()) {
+            resolveAnnotations(annotations);
+        }
+    }
+
+    private void linkParent(ClassInfo classInfo) throws IOException, ClassNotFoundException {
         if (classInfo.superType == null) return;
         if (classInfo.superType.equals("java.lang.Object")) return;
-        
+
         ClassInfo parentInfo = classInfo.superclassInfo;
 
         if (parentInfo == null) {
@@ -95,7 +165,7 @@ public abstract class AbstractFinder {
                 parentInfo = classInfos.get(classInfo.superType);
 
                 if (parentInfo == null) return;
-                
+
                 linkParent(parentInfo);
             }
 
@@ -107,16 +177,16 @@ public abstract class AbstractFinder {
         }
     }
 
-    private void linkInterfaces(ClassInfo classInfo) throws IOException {
+    private void linkInterfaces(ClassInfo classInfo) throws IOException, ClassNotFoundException {
         final List<ClassInfo> infos = new ArrayList<ClassInfo>();
 
-        if (classInfo.clazz != null){
+        if (classInfo.clazz != null) {
             final Class<?>[] interfaces = classInfo.clazz.getInterfaces();
 
             for (Class<?> clazz : interfaces) {
                 ClassInfo interfaceInfo = classInfos.get(clazz.getName());
 
-                if (interfaceInfo == null){
+                if (interfaceInfo == null) {
                     readClassDef(clazz);
                 }
 
@@ -130,7 +200,7 @@ public abstract class AbstractFinder {
             for (String className : classInfo.interfaces) {
                 ClassInfo interfaceInfo = classInfos.get(className);
 
-                if (interfaceInfo == null){
+                if (interfaceInfo == null) {
                     readClassDef(className);
                 }
 
@@ -162,13 +232,14 @@ public abstract class AbstractFinder {
      * results from the last findAnnotated* method call.
      * <p/>
      * This method is not thread safe.
+     *
      * @return an unmodifiable live view of classes that could not be loaded in previous findAnnotated* call.
      */
     public List<String> getClassesNotLoaded() {
         return Collections.unmodifiableList(classesNotLoaded);
     }
 
-    public List<Package> findAnnotatedPackages(Class<? extends Annotation> annotation) {
+    public List<AnnotatedTarget<Package>> findAnnotatedPackages(Class<? extends Annotation> annotation) {
         classesNotLoaded.clear();
         List<Package> packages = new ArrayList<Package>();
         List<Info> infos = getAnnotationInfos(annotation.getName());
@@ -186,7 +257,7 @@ public abstract class AbstractFinder {
                 }
             }
         }
-        return packages;
+        return null;
     }
 
     public List<Class<?>> findAnnotatedClasses(Class<? extends Annotation> annotation) {
@@ -210,21 +281,61 @@ public abstract class AbstractFinder {
         return classes;
     }
 
+    public List<AnnotatedTarget<Class<?>>> findMetaAnnotatedClasses(Class<? extends Annotation> annotation) {
+        classesNotLoaded.clear();
+        Set<Class<?>> classes = findMetaAnnotatedClasses(annotation, new HashSet<Class<?>>());
+
+        List<AnnotatedTarget<Class<?>>> list = new ArrayList<AnnotatedTarget<Class<?>>>();
+
+        for (Class<?> clazz : classes) {
+            list.add(new MetaAnnotatedClass(clazz));
+        }
+
+        return list;
+    }
+
+    private Set<Class<?>> findMetaAnnotatedClasses(Class<? extends Annotation> annotation, Set<Class<?>> classes) {
+        List<Info> infos = getAnnotationInfos(annotation.getName());
+        for (Info info : infos) {
+            if (info instanceof ClassInfo) {
+                ClassInfo classInfo = (ClassInfo) info;
+                try {
+                    Class clazz = classInfo.get();
+
+                    if (classes.contains(clazz)) continue;
+
+                    // double check via proper reflection
+                    if (clazz.isAnnotationPresent(annotation)) {
+                        classes.add(clazz);
+                    }
+
+                    String meta = info.getMetaAnnotationName();
+                    if (meta != null) {
+                        classes.addAll(findMetaAnnotatedClasses((Class<? extends Annotation>) clazz, classes));
+                    }
+                } catch (ClassNotFoundException e) {
+                    classesNotLoaded.add(classInfo.getName());
+                }
+            }
+        }
+        return classes;
+    }
+
     /**
      * Naive implementation - works extremelly slow O(n^3)
      *
      * @param annotation
      * @return list of directly or indirectly (inherited) annotated classes
      */
-    public List<Class<?>> findInheritedAnnotatedClasses(Class<? extends Annotation> annotation) {
+    public List<AnnotatedTarget<Class<?>>> findInheritedAnnotatedClasses(Class<? extends Annotation> annotation) {
         classesNotLoaded.clear();
         List<Class<?>> classes = new ArrayList<Class<?>>();
         List<Info> infos = getAnnotationInfos(annotation.getName());
         for (Info info : infos) {
             try {
-            	if(info instanceof ClassInfo){
-                   classes.add(((ClassInfo) info).get());
-            	}
+                if (info instanceof ClassInfo) {
+                    classes.add(((ClassInfo) info).get());
+                }
             } catch (ClassNotFoundException cnfe) {
                 // TODO: ignored, but a log message would be appropriate
             }
@@ -248,9 +359,9 @@ public abstract class AbstractFinder {
                     }
                     // check whether any interface is annotated
                     List<String> interfces = classInfo.getInterfaces();
-                    for (String interfce: interfces) {
+                    for (String interfce : interfces) {
                         for (Class clazz : classes) {
-                            if (interfce.replaceFirst("<.*>","").equals(clazz.getName())) {
+                            if (interfce.replaceFirst("<.*>", "").equals(clazz.getName())) {
                                 classes.add(classInfo.get());
                                 tempClassInfos.remove(pos);
                                 annClassFound = true;
@@ -265,7 +376,7 @@ public abstract class AbstractFinder {
                 }
             }
         } while (annClassFound);
-        return classes;
+        return null;
     }
 
     public List<Method> findAnnotatedMethods(Class<? extends Annotation> annotation) {
@@ -297,7 +408,66 @@ public abstract class AbstractFinder {
         return methods;
     }
 
-    public List<Constructor> findAnnotatedConstructors(Class<? extends Annotation> annotation) {
+    public List<AnnotatedMethod<Method>> findMetaAnnotatedMethods(Class<? extends Annotation> annotation) {
+        classesNotLoaded.clear();
+
+        Set<Method> methods = findMetaAnnotatedMethods(annotation, new HashSet<Method>(), new HashSet<String>());
+
+        List<AnnotatedMethod<Method>> targets = new ArrayList<AnnotatedMethod<Method>>();
+
+        for (Method method : methods) {
+            targets.add(new MetaAnnotatedMethod(method));
+        }
+
+        return targets;
+    }
+
+    private Set<Method> findMetaAnnotatedMethods(Class<? extends Annotation> annotation, Set<Method> methods, Set<String> seen) {
+        List<Info> infos = getAnnotationInfos(annotation.getName());
+
+        for (Info info : infos) {
+
+            String meta = info.getMetaAnnotationName();
+            if (meta != null) {
+                if (meta.equals(annotation.getName())) continue;
+                if (!seen.add(meta)) continue;
+                
+
+                ClassInfo metaInfo = classInfos.get(meta);
+
+                Class<?> clazz;
+                try {
+                    clazz = metaInfo.get();
+                } catch (ClassNotFoundException e) {
+                    classesNotLoaded.add(metaInfo.getName());
+                    continue;
+                }
+
+                findMetaAnnotatedMethods((Class<? extends Annotation>) clazz, methods, seen);
+
+            } else if (info instanceof MethodInfo && !((MethodInfo) info).isConstructor()) {
+
+                MethodInfo methodInfo = (MethodInfo) info;
+
+                ClassInfo classInfo = methodInfo.getDeclaringClass();
+
+                try {
+                    Class clazz = classInfo.get();
+                    for (Method method : clazz.getDeclaredMethods()) {
+                        if (method.isAnnotationPresent(annotation)) {
+                            methods.add(method);
+                        }
+                    }
+                } catch (ClassNotFoundException e) {
+                    classesNotLoaded.add(classInfo.getName());
+                }
+            }
+        }
+
+        return methods;
+    }
+
+    public List<AnnotatedMethod<Constructor>> findAnnotatedConstructors(Class<? extends Annotation> annotation) {
         classesNotLoaded.clear();
         List<ClassInfo> seen = new ArrayList<ClassInfo>();
         List<Constructor> constructors = new ArrayList<Constructor>();
@@ -323,10 +493,10 @@ public abstract class AbstractFinder {
                 }
             }
         }
-        return constructors;
+        return null;
     }
 
-    public List<Field> findAnnotatedFields(Class<? extends Annotation> annotation) {
+    public List<AnnotatedMember<Field>> findAnnotatedFields(Class<? extends Annotation> annotation) {
         classesNotLoaded.clear();
         List<ClassInfo> seen = new ArrayList<ClassInfo>();
         List<Field> fields = new ArrayList<Field>();
@@ -352,7 +522,7 @@ public abstract class AbstractFinder {
                 }
             }
         }
-        return fields;
+        return null;
     }
 
     public List<Class<?>> findClassesInPackage(String packageName, boolean recursive) {
@@ -360,9 +530,9 @@ public abstract class AbstractFinder {
         List<Class<?>> classes = new ArrayList<Class<?>>();
         for (ClassInfo classInfo : classInfos.values()) {
             try {
-                if (recursive && classInfo.getPackageName().startsWith(packageName)){
+                if (recursive && classInfo.getPackageName().startsWith(packageName)) {
                     classes.add(classInfo.get());
-                } else if (classInfo.getPackageName().equals(packageName)){
+                } else if (classInfo.getPackageName().equals(packageName)) {
                     classes.add(classInfo.get());
                 }
             } catch (ClassNotFoundException e) {
@@ -455,7 +625,6 @@ public abstract class AbstractFinder {
                     // Optimization: Don't need to call this method if parent class was already searched
 
 
-
                     classes.addAll(_findSubclasses(impl));
                 }
 
@@ -484,7 +653,7 @@ public abstract class AbstractFinder {
                         infos.addAll(collectImplementations(classInfo.name));
 
                     }
-                    
+
                 } catch (ClassNotFoundException ignore) {
                     // we'll deal with this later
                 }
@@ -502,34 +671,9 @@ public abstract class AbstractFinder {
         return infos;
     }
 
-    protected void readClassDef(String className) {
-        int pos = className.indexOf("<");
-        if (pos > -1) {
-            className = className.substring(0, pos);
-        }
-        pos = className.indexOf(">");
-        if (pos > -1) {
-            className = className.substring(0, pos);
-        }
-        if (!className.endsWith(".class")) {
-            className = className.replace('.', '/') + ".class";
-        }
-        try {
-            URL resource = getResource(className);
-            if (resource != null) {
-                InputStream in = resource.openStream();
-                try {
-                    readClassDef(in);
-                } finally {
-                    in.close();
-                }
-            } else {
-                new Exception("Could not load " + className).printStackTrace();
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-
+    protected void readClassDef(String className) throws ClassNotFoundException, IOException {
+        if (classInfos.containsKey(className)) return;
+        readClassDef(archive.getBytecode(className));
     }
 
     protected void readClassDef(InputStream in) throws IOException {
@@ -541,7 +685,7 @@ public abstract class AbstractFinder {
         List<Info> infos = new ArrayList<Info>();
 
         Package aPackage = clazz.getPackage();
-        if (aPackage != null){
+        if (aPackage != null) {
             final PackageInfo info = new PackageInfo(aPackage);
             for (AnnotationInfo annotation : info.getAnnotations()) {
                 List<Info> annotationInfos = getAnnotationInfos(annotation.getName());
@@ -586,27 +730,34 @@ public abstract class AbstractFinder {
         public Annotatable() {
         }
 
+        public Annotation[] getDeclaredAnnotations() {
+            return new Annotation[0];
+        }
+
         public List<AnnotationInfo> getAnnotations() {
             return annotations;
         }
-        
+
+        public String getMetaAnnotationName() {
+            return null;
+        }
+
         /**
-         * Utility method to get around some errors caused by 
-         * interactions between the Equinox class loaders and 
-         * the OpenJPA transformation process.  There is a window 
-         * where the OpenJPA transformation process can cause 
-         * an annotation being processed to get defined in a 
-         * classloader during the actual defineClass call for 
-         * that very class (e.g., recursively).  This results in 
-         * a LinkageError exception.  If we see one of these, 
-         * retry the request.  Since the annotation will be 
-         * defined on the second pass, this should succeed.  If 
-         * we get a second exception, then it's likely some 
-         * other problem. 
-         * 
+         * Utility method to get around some errors caused by
+         * interactions between the Equinox class loaders and
+         * the OpenJPA transformation process.  There is a window
+         * where the OpenJPA transformation process can cause
+         * an annotation being processed to get defined in a
+         * classloader during the actual defineClass call for
+         * that very class (e.g., recursively).  This results in
+         * a LinkageError exception.  If we see one of these,
+         * retry the request.  Since the annotation will be
+         * defined on the second pass, this should succeed.  If
+         * we get a second exception, then it's likely some
+         * other problem.
+         *
          * @param element The AnnotatedElement we need information for.
-         * 
-         * @return An array of the Annotations defined on the element. 
+         * @return An array of the Annotations defined on the element.
          */
         private Annotation[] getAnnotations(AnnotatedElement element) {
             try {
@@ -619,9 +770,14 @@ public abstract class AbstractFinder {
     }
 
     public static interface Info {
+
+        String getMetaAnnotationName();
+
         String getName();
 
         List<AnnotationInfo> getAnnotations();
+
+        Annotation[] getDeclaredAnnotations();
     }
 
     public class PackageInfo extends Annotatable implements Info {
@@ -629,7 +785,7 @@ public abstract class AbstractFinder {
         private final ClassInfo info;
         private final Package pkg;
 
-        public PackageInfo(Package pkg){
+        public PackageInfo(Package pkg) {
             super(pkg);
             this.pkg = pkg;
             this.name = pkg.getName();
@@ -647,7 +803,7 @@ public abstract class AbstractFinder {
         }
 
         public Package get() throws ClassNotFoundException {
-            return (pkg != null)?pkg:info.get().getPackage();
+            return (pkg != null) ? pkg : info.get().getPackage();
         }
 
         @Override
@@ -679,12 +835,13 @@ public abstract class AbstractFinder {
         private final List<FieldInfo> fields = new SingleLinkedList<FieldInfo>();
         private Class<?> clazz;
 
+
         public ClassInfo(Class clazz) {
             super(clazz);
             this.clazz = clazz;
             this.name = clazz.getName();
             Class superclass = clazz.getSuperclass();
-            this.superType = superclass != null ? superclass.getName(): null;
+            this.superType = superclass != null ? superclass.getName() : null;
             for (Class intrface : clazz.getInterfaces()) {
                 this.interfaces.add(intrface.getName());
             }
@@ -695,8 +852,24 @@ public abstract class AbstractFinder {
             this.superType = superType;
         }
 
-        public String getPackageName(){
-            return name.indexOf(".") > 0 ? name.substring(0, name.lastIndexOf(".")) : "" ;
+        @Override
+        public String getMetaAnnotationName() {
+            for (AnnotationInfo info : getAnnotations()) {
+                if (info.getName().equals(Metatype.class.getName())) return name;
+            }
+
+            if (name.endsWith("$$")) {
+                ClassInfo info = classInfos.get(name.substring(0, name.length() - 2));
+                if (info != null) {
+                    return info.getMetaAnnotationName();
+                }
+            }
+
+            return null;
+        }
+
+        public String getPackageName() {
+            return name.indexOf(".") > 0 ? name.substring(0, name.lastIndexOf(".")) : "";
         }
 
         public List<MethodInfo> getConstructors() {
@@ -723,11 +896,15 @@ public abstract class AbstractFinder {
             return superType;
         }
 
+        public boolean isAnnotation() {
+            return "java.lang.Object".equals(superType) && interfaces.size() == 1 && "java.lang.annotation.Annotation".equals(interfaces.get(0));
+        }
+
         public Class<?> get() throws ClassNotFoundException {
             if (clazz != null) return clazz;
             try {
                 String fixedName = name.replaceFirst("<.*>", "");
-                this.clazz = loadClass(fixedName);
+                this.clazz = archive.loadClass(fixedName);
                 return clazz;
             } catch (ClassNotFoundException notFound) {
                 classesNotLoaded.add(name);
@@ -742,28 +919,49 @@ public abstract class AbstractFinder {
 
     public class MethodInfo extends Annotatable implements Info {
         private final ClassInfo declaringClass;
-        private final String returnType;
+        private final String descriptor;
         private final String name;
         private final List<List<AnnotationInfo>> parameterAnnotations = new ArrayList<List<AnnotationInfo>>();
+        private Member method;
 
-        public MethodInfo(ClassInfo info, Constructor constructor){
+        public MethodInfo(ClassInfo info, Constructor constructor) {
             super(constructor);
             this.declaringClass = info;
             this.name = "<init>";
-            this.returnType = Void.TYPE.getName();
+            this.descriptor = null;
         }
 
-        public MethodInfo(ClassInfo info, Method method){
+        public MethodInfo(ClassInfo info, Method method) {
             super(method);
             this.declaringClass = info;
             this.name = method.getName();
-            this.returnType = method.getReturnType().getName();
+            this.descriptor = method.getReturnType().getName();
+            this.method = method;
         }
 
-        public MethodInfo(ClassInfo declarignClass, String name, String returnType) {
+        public MethodInfo(ClassInfo declarignClass, String name, String descriptor) {
             this.declaringClass = declarignClass;
             this.name = name;
-            this.returnType = returnType;
+            this.descriptor = descriptor;
+        }
+
+        @Override
+        public String getMetaAnnotationName() {
+            return declaringClass.getMetaAnnotationName();
+        }
+
+        @Override
+        public Annotation[] getDeclaredAnnotations() {
+            super.getDeclaredAnnotations();
+            try {
+                return ((AnnotatedElement) get()).getDeclaredAnnotations();
+            } catch (ClassNotFoundException e) {
+                return super.getDeclaredAnnotations();
+            }
+        }
+
+        public boolean isConstructor() {
+            return getName().equals("<init>");
         }
 
         public List<List<AnnotationInfo>> getParameterAnnotations() {
@@ -788,13 +986,50 @@ public abstract class AbstractFinder {
             return declaringClass;
         }
 
-        public String getReturnType() {
-            return returnType;
-        }
-
         public String toString() {
             return declaringClass + "@" + name;
         }
+
+        public Member get() throws ClassNotFoundException {
+            if (method == null) {
+                method = toMethod();
+            }
+
+            return method;
+        }
+
+        private Method toMethod() throws ClassNotFoundException {
+            org.objectweb.asm.commons.Method method = new org.objectweb.asm.commons.Method(name, descriptor);
+
+            Class<?> clazz = this.declaringClass.get();
+            List<Class> parameterTypes = new ArrayList<Class>();
+
+            for (Type type : method.getArgumentTypes()) {
+                String paramType = type.getClassName();
+                try {
+                    parameterTypes.add(Classes.forName(paramType, clazz.getClassLoader()));
+                } catch (ClassNotFoundException cnfe) {
+                    throw new IllegalStateException("Parameter class could not be loaded for type " + paramType, cnfe);
+                }
+            }
+
+            Class[] parameters = parameterTypes.toArray(new Class[parameterTypes.size()]);
+
+            IllegalStateException noSuchMethod = null;
+            while (clazz != null) {
+                try {
+                    return clazz.getDeclaredMethod(name, parameters);
+                } catch (NoSuchMethodException e) {
+                    if (noSuchMethod == null) {
+                        noSuchMethod = new IllegalStateException("Callback method does not exist: " + clazz.getName() + "." + name, e);
+                    }
+                    clazz = clazz.getSuperclass();
+                }
+            }
+
+            throw noSuchMethod;
+        }
+
     }
 
     public class FieldInfo extends Annotatable implements Info {
@@ -802,7 +1037,7 @@ public abstract class AbstractFinder {
         private final String type;
         private final ClassInfo declaringClass;
 
-        public FieldInfo(ClassInfo info, Field field){
+        public FieldInfo(ClassInfo info, Field field) {
             super(field);
             this.declaringClass = info;
             this.name = field.getName();
@@ -835,7 +1070,7 @@ public abstract class AbstractFinder {
     public class AnnotationInfo extends Annotatable implements Info {
         private final String name;
 
-        public AnnotationInfo(Annotation annotation){
+        public AnnotationInfo(Annotation annotation) {
             this(annotation.getClass().getName());
         }
 
@@ -844,8 +1079,7 @@ public abstract class AbstractFinder {
         }
 
         public AnnotationInfo(String name) {
-            name = name.replaceAll("^L|;$", "");
-            name = name.replace('/', '.');
+            name = Type.getType(name).getClassName();
             this.name = name.intern();
         }
 
@@ -873,6 +1107,7 @@ public abstract class AbstractFinder {
             if (name.endsWith("package-info")) {
                 info = new PackageInfo(javaName(name));
             } else {
+
                 ClassInfo classInfo = new ClassInfo(javaName(name), javaName(superName));
 
                 if (signature == null) {
@@ -884,12 +1119,23 @@ public abstract class AbstractFinder {
                     new SignatureReader(signature).accept(new GenericAwareInfoBuildingVisitor(GenericAwareInfoBuildingVisitor.TYPE.CLASS, classInfo));
                 }
                 info = classInfo;
+
                 classInfos.put(classInfo.getName(), classInfo);
             }
         }
 
         private String javaName(String name) {
-            return (name == null)? null:name.replace('/', '.');
+            return (name == null) ? null : name.replace('/', '.');
+        }
+
+        @Override
+        public void visitInnerClass(String name, String outerName, String innerName, int access) {
+            super.visitInnerClass(name, outerName, innerName, access);
+        }
+
+        @Override
+        public void visitAttribute(Attribute attribute) {
+            super.visitAttribute(attribute);
         }
 
         @Override
@@ -912,10 +1158,12 @@ public abstract class AbstractFinder {
         public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
             ClassInfo classInfo = ((ClassInfo) info);
             MethodInfo methodInfo = new MethodInfo(classInfo, name, desc);
+
             classInfo.getMethods().add(methodInfo);
             return new InfoBuildingVisitor(methodInfo);
         }
 
+
         @Override
         public AnnotationVisitor visitParameterAnnotation(int param, String desc, boolean visible) {
             MethodInfo methodInfo = ((MethodInfo) info);
@@ -1081,8 +1329,282 @@ public abstract class AbstractFinder {
         }
 
         private String javaName(String name) {
-            return (name == null)? null:name.replace('/', '.');
+            return (name == null) ? null : name.replace('/', '.');
+        }
+
+    }
+
+    /**
+     * @version $Rev$ $Date$
+     */
+    public abstract class MetaAnnotatedTarget<T> implements AnnotatedTarget<T> {
+        protected final Map<Class<? extends Annotation>, MetaAnnotation> found = new HashMap<Class<? extends Annotation>, MetaAnnotation>();
+        protected final T target;
+
+        public MetaAnnotatedTarget(T target) {
+            this.target = target;
+        }
+
+        @Override
+        public T getTarget() {
+            return target;
+        }
+
+        @Override
+        public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+            return found.containsKey(annotationClass);
+        }
+
+        @Override
+        public TypeVariable<?>[] getTypeParameters() {
+            return ((Class<?>) getTarget()).getTypeParameters();
+        }
+
+        @Override
+        public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+            MetaAnnotation<T> annotation = found.get(annotationClass);
+            return (annotation == null) ? null : annotation.getAnnotation();
+        }
+
+        @Override
+        public Annotation[] getAnnotations() {
+            Annotation[] annotations = new Annotation[found.size()];
+
+            int i = 0;
+            for (MetaAnnotation annotation : found.values()) {
+                annotations[i++] = annotation.getAnnotation();
+            }
+
+            return annotations;
+        }
+
+        protected void unroll(Class<? extends Annotation> clazz, int depth) {
+            if (!isMetaAnnotation(clazz)) return;
+            
+            for (Annotation annotation : getDeclaredMetaAnnotations(clazz)) {
+                Class<? extends Annotation> type = annotation.annotationType();
+
+                MetaAnnotation existing = found.get(type);
+
+                if (existing != null) {
+                    if (existing.getDepth() > depth) {
+//                        System.out.println("OVERWRITE " + type);
+                        //overwrite
+                        found.put(type, new MetaAnnotation(annotation, depth, clazz));
+                        unroll(type, depth + 1);
+                    } else if (existing.getDepth() < depth) {
+//                        System.out.println("IGNORE " + type);
+                        // ignore, what we have already is higher priority
+                    } else {
+//                        System.out.println("CONFLICT " + type);
+                        // They are the same depth and therefore conflicting
+                        existing.getConflicts().add(new MetaAnnotation(annotation, depth, clazz));
+                    }
+                } else {
+//                    System.out.println("NEW " + type);
+                    found.put(type, new MetaAnnotation(annotation, depth, clazz));
+                    unroll(type, depth + 1);
+                }
+            }
+        }
+
+        private Collection<Annotation> getDeclaredMetaAnnotations(Class<? extends Annotation> clazz) {
+            Map<Class, Annotation> map = new HashMap<Class, Annotation>();
+
+            for (Annotation annotation : clazz.getDeclaredAnnotations()) {
+                map.put(annotation.annotationType(), annotation);
+            }
+
+            for (Info info : annotated.get(clazz.getName())) {
+                if (!clazz.getName().equals(info.getMetaAnnotationName())) continue;
+                for (Annotation annotation : info.getDeclaredAnnotations()) {
+                    map.put(annotation.annotationType(), annotation);
+                }
+
+            }
+
+            Class[] invalid = {
+                    Target.class,
+                    Retention.class,
+                    Documented.class,
+                    Metatype.class,
+                    clazz
+            };
+
+            for (Class c : invalid) {
+                map.remove(c);
+            }
+            
+            return map.values();
+        }
+
+        private boolean isMetaAnnotation(Class<? extends Annotation> clazz) {
+            if (!clazz.isAnnotation()) return false;
+
+            for (Annotation annotation : clazz.getDeclaredAnnotations()) {
+                if (metaroots.contains(annotation.annotationType())) return true;
+            }
+            
+            return false;
+        }
+
+    }
+
+    private static class MetaAnnotation<T extends Annotation> {
+        private final Class<?> declaringClass;
+        private final T annotation;
+        private final int depth;
+
+        private final List<MetaAnnotation<T>> conflicts = new ArrayList<MetaAnnotation<T>>();
+
+        private MetaAnnotation(T annotation, int depth, Class<?> declaringClass) {
+            this.annotation = annotation;
+            this.depth = depth;
+            this.declaringClass = declaringClass;
+        }
+
+        public T getAnnotation() {
+            return annotation;
+        }
+
+        public int getDepth() {
+            return depth;
+        }
+
+        public Class<?> getDeclaringClass() {
+            return declaringClass;
+        }
+
+        public List<MetaAnnotation<T>> getConflicts() {
+            return conflicts;
+        }
+    }
+
+    private class MetaAnnotatedClass extends MetaAnnotatedTarget<Class<?>> {
+
+        private MetaAnnotatedClass(Class<?> clazz) {
+            super(clazz);
+            for (Annotation annotation : getTarget().getDeclaredAnnotations()) {
+                found.put(annotation.annotationType(), new MetaAnnotation(annotation, 0, getTarget()));
+                unroll(annotation.annotationType(), 1);
+            }
+        }
+
+        @Override
+        public Annotation[] getDeclaredAnnotations() {
+            return getTarget().getDeclaredAnnotations();
+        }
+    }
+
+
+    private class MetaAnnotatedField extends MetaAnnotatedTarget<Field> {
+
+        private MetaAnnotatedField(Field target) {
+            super(target);
+            for (Annotation annotation : target.getDeclaredAnnotations()) {
+                found.put(annotation.annotationType(), new MetaAnnotation(annotation, 0, target.getDeclaringClass()));
+                unroll(annotation.annotationType(), 1);
+            }
+        }
+
+        @Override
+        public Annotation[] getDeclaredAnnotations() {
+            return getTarget().getDeclaredAnnotations();
+        }
+    }
+
+    private class MetaAnnotatedMethod extends MetaAnnotatedTarget<Method> implements AnnotatedMethod<Method> {
+
+        private Method target;
+
+        private MetaAnnotatedMethod(Method target) {
+            super(target);
+            for (Annotation annotation : target.getDeclaredAnnotations()) {
+                found.put(annotation.annotationType(), new MetaAnnotation(annotation, 0, target.getDeclaringClass()));
+                unroll(annotation.annotationType(), 1);
+            }
+
+        }
+
+        @Override
+        public Annotation[] getDeclaredAnnotations() {
+            return getTarget().getDeclaredAnnotations();
+        }
+
+        @Override
+        public Annotation[][] getParameterAnnotations() {
+            return getTarget().getParameterAnnotations();
+        }
+
+        @Override
+        public Class<?> getDeclaringClass() {
+            return getTarget().getDeclaringClass();
+        }
+
+        @Override
+        public String getName() {
+            return getTarget().getName();
+        }
+
+        @Override
+        public int getModifiers() {
+            return getTarget().getModifiers();
+        }
+
+        @Override
+        public TypeVariable<Method>[] getTypeParameters() {
+            return getTarget().getTypeParameters();
+        }
+
+        @Override
+        public Class<?>[] getParameterTypes() {
+            return getTarget().getParameterTypes();
+        }
+
+        @Override
+        public java.lang.reflect.Type[] getGenericParameterTypes() {
+            return getTarget().getGenericParameterTypes();
+        }
+
+        @Override
+        public Class<?>[] getExceptionTypes() {
+            return getTarget().getExceptionTypes();
+        }
+
+        @Override
+        public java.lang.reflect.Type[] getGenericExceptionTypes() {
+            return getTarget().getGenericExceptionTypes();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            return getTarget().equals(obj);
+        }
+
+        @Override
+        public int hashCode() {
+            return getTarget().hashCode();
+        }
+
+        @Override
+        public String toString() {
+            return getTarget().toString();
+        }
+
+        @Override
+        public String toGenericString() {
+            return getTarget().toGenericString();
+        }
+
+        @Override
+        public boolean isVarArgs() {
+            return getTarget().isVarArgs();
+        }
+
+        @Override
+        public boolean isSynthetic() {
+            return getTarget().isSynthetic();
         }
 
     }
-}
+}
\ No newline at end of file

Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MetaAnnotationFinder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MetaAnnotationFinder.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/MetaAnnotationFinder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/Metatype.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/Metatype.java?rev=1084087&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/Metatype.java (added)
+++ geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/Metatype.java Tue Mar 22 07:35:14 2011
@@ -0,0 +1,32 @@
+/**
+ * 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.xbean.finder;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+
+/**
+ * @version $Rev$ $Date$
+ */
+@Metatype
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ANNOTATION_TYPE)
+public @interface Metatype {
+}
\ No newline at end of file

Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/Metatype.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/PackageFilteredArchive.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/PackageFilteredArchive.java?rev=1084087&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/PackageFilteredArchive.java (added)
+++ geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/PackageFilteredArchive.java Tue Mar 22 07:35:14 2011
@@ -0,0 +1,45 @@
+/**
+ * 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.xbean.finder;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class PackageFilteredArchive extends PrefixFilteredArchive {
+
+    public PackageFilteredArchive(Archive archive, String... prefixes) {
+        this(archive, Arrays.asList(prefixes));
+    }
+
+    public PackageFilteredArchive(Archive archive, Iterable<String> prefixes) {
+        super(archive, normalize(prefixes));
+    }
+
+    private static Iterable<String> normalize(Iterable<String> prefixes) {
+        List<String> list = new ArrayList<String>();
+        // Ensure the package name ends in a dot
+        for (String prefix : prefixes) {
+            if (!prefix.endsWith(".")) prefix += ".";
+            list.add(prefix);
+        }
+        return list;
+    }
+}
\ No newline at end of file

Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/PackageFilteredArchive.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/PrefixFilteredArchive.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/PrefixFilteredArchive.java?rev=1084087&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/PrefixFilteredArchive.java (added)
+++ geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/PrefixFilteredArchive.java Tue Mar 22 07:35:14 2011
@@ -0,0 +1,108 @@
+/**
+ * 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.xbean.finder;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class PrefixFilteredArchive implements Archive {
+
+    private final Set<String> prefixes = new LinkedHashSet<String>();
+
+    private final Archive archive;
+
+    public PrefixFilteredArchive(Archive archive, String... prefixes) {
+        this(archive, Arrays.asList(prefixes));
+    }
+
+    public PrefixFilteredArchive(Archive archive, Iterable<String> prefixes) {
+        this.archive = archive;
+        for (String prefix : prefixes) {
+            this.prefixes.add(prefix);
+        }
+    }
+
+    @Override
+    public InputStream getBytecode(String className) throws IOException, ClassNotFoundException {
+        return archive.getBytecode(className);
+    }
+
+    @Override
+    public Class<?> loadClass(String className) throws ClassNotFoundException {
+        return archive.loadClass(className);
+    }
+
+    @Override
+    public Iterator<String> iterator() {
+        return new Filter(archive.iterator());
+    }
+
+    private final class Filter implements Iterator<String> {
+        private final Iterator<String> it;
+
+        private String next;
+
+        private Filter(Iterator<String> it) {
+            this.it = it;
+        }
+
+        @Override
+        public boolean hasNext() {
+            if (next != null) return true;
+            if (!it.hasNext()) return false;
+            seek();
+            return hasNext();
+        }
+
+        @Override
+        public String next() {
+            if (!hasNext()) throw new NoSuchElementException();
+
+            String s = next;
+            next = null;
+
+            return s;
+        }
+
+        @Override
+        public void remove() {
+            it.remove();
+        }
+
+        private void seek() {
+            while (next == null && it.hasNext()) {
+                next = it.next();
+
+                for (String prefix : prefixes) {
+                    if (next.startsWith(prefix)) break;
+                }
+
+                next = null;
+            }
+        }
+
+    }
+}
\ No newline at end of file

Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/PrefixFilteredArchive.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/RegexFilteredArchive.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/RegexFilteredArchive.java?rev=1084087&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/RegexFilteredArchive.java (added)
+++ geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/RegexFilteredArchive.java Tue Mar 22 07:35:14 2011
@@ -0,0 +1,105 @@
+/**
+ * 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.xbean.finder;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.regex.Pattern;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class RegexFilteredArchive implements Archive {
+
+    private final Pattern include;
+    private final Pattern exclude;
+
+    private final Archive archive;
+
+    public RegexFilteredArchive(Archive archive, String include, String exclude) {
+        this.archive = archive;
+        this.include = (".*".equals(include)) ? null : Pattern.compile(include);
+        this.exclude = ("".equals(exclude)) ? null : Pattern.compile(exclude);
+    }
+
+    public RegexFilteredArchive(Archive archive, Pattern include, Pattern exclude) {
+        this.archive = archive;
+        this.include = include;
+        this.exclude = exclude;
+    }
+
+    @Override
+    public InputStream getBytecode(String className) throws IOException, ClassNotFoundException {
+        return archive.getBytecode(className);
+    }
+
+    @Override
+    public Class<?> loadClass(String className) throws ClassNotFoundException {
+        return archive.loadClass(className);
+    }
+
+    @Override
+    public Iterator<String> iterator() {
+        return new Filter(archive.iterator());
+    }
+
+    private final class Filter implements Iterator<String> {
+        private final Iterator<String> it;
+
+        private String next;
+
+        private Filter(Iterator<String> it) {
+            this.it = it;
+        }
+
+        @Override
+        public boolean hasNext() {
+            if (next != null) return true;
+            if (!it.hasNext()) return false;
+            seek();
+            return hasNext();
+        }
+
+        @Override
+        public String next() {
+            if (!hasNext()) throw new NoSuchElementException();
+
+            String s = next;
+            next = null;
+
+            return s;
+        }
+
+        @Override
+        public void remove() {
+            it.remove();
+        }
+
+        private void seek() {
+            while (next == null && it.hasNext()) {
+                next = it.next();
+
+                if (include != null && include.matcher(next).matches()) break;
+                if (exclude != null && exclude.matcher(next).matches()) next = null;
+
+            }
+        }
+
+    }
+}

Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/RegexFilteredArchive.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message