You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ch...@apache.org on 2012/07/05 04:48:38 UTC
svn commit: r1357447 [3/4] - in /commons/sandbox/classscan/trunk: ./ api/
api/src/ api/src/main/ api/src/main/java/ api/src/main/java/org/
api/src/main/java/org/apache/ api/src/main/java/org/apache/commons/
api/src/main/java/org/apache/commons/classsca...
Added: commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/NameSet.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/NameSet.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/NameSet.java (added)
+++ commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/NameSet.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,87 @@
+/*
+ * Licensed 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.commons.classscan.util;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+
+import org.apache.commons.classscan.HasName;
+import org.apache.commons.classscan.spi.model.HasResolve;
+
+public class NameSet<V extends HasName & HasResolve> extends ResolveSet<V> {
+
+ private final static Comparator<HasName> REVERSE_COMPARE = new Comparator<HasName>() {
+ @Override
+ public int compare(HasName l, HasName r) {
+ String left = l.getName();
+ String right = r.getName();
+
+ // "quick" compare
+ int diff = left.length() - right.length();
+ if (diff != 0) {
+ return diff;
+ }
+ // compare from end of strings - the names probably have long equivalent prefixes
+ for (int i = left.length(); --i > 0;) {
+ int d = left.charAt(i) - right.charAt(i);
+ if (d != 0) {
+ return d;
+ }
+ }
+ return 0;
+ }
+ };
+
+ public NameSet(V[] values) {
+ super(values);
+ if(values!=null && values.length>0) {
+ Arrays.sort(values, REVERSE_COMPARE);
+ }
+ }
+
+ public NameSet(Class<V> clss, Collection<? extends V> workValues) {
+ this(collectionToArray(clss, workValues));
+ }
+
+ private static <D extends HasName> D[] collectionToArray(Class<D> collectionType, Collection<? extends D> workValues) {
+ if(workValues.isEmpty()) {
+ return null;
+ }
+ @SuppressWarnings("unchecked")
+ D[] newInstance = (D[]) Array.newInstance(collectionType, workValues.size());
+ return workValues.toArray(newInstance);
+ }
+
+ public V getValue(final String name) {
+ int idx= Arrays.binarySearch(values, new HasName() {
+ @Override
+ public String getName() {
+ return name;
+ }
+ }, REVERSE_COMPARE);
+ return idx<0 ? null : values[idx];
+ }
+
+ private static interface NameResolve extends HasName, HasResolve {};
+ private static NameSet<NameResolve> EMPTY_SET = new NameSet<NameResolve>(new NameResolve[0]);
+
+ public static <V extends HasName & HasResolve> NameSet<V> emptyNameSet() {
+ NameSet<?> qrc = (NameSet<?>) EMPTY_SET;
+ @SuppressWarnings("unchecked")
+ NameSet<V> rc = (NameSet<V>) qrc;
+ return rc;
+ }
+}
Added: commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/ReadOnlySet.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/ReadOnlySet.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/ReadOnlySet.java (added)
+++ commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/ReadOnlySet.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,164 @@
+/*
+ * Licensed 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.commons.classscan.util;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * Set of immutable instances.
+ *
+ * @param <V>
+ * The contained type
+ */
+public class ReadOnlySet<V> implements Set<V> {
+
+ protected V[] values;
+
+ public ReadOnlySet(V[] values) {
+ if(values==null) {
+ throw new UnsupportedOperationException();
+ }
+ else {
+ this.values = values;
+ }
+ }
+
+ /**
+ * Subclasses may use this constructor to delay initialization of values.
+ * The derived class must call setValues before general use.
+ */
+ protected ReadOnlySet() {
+ }
+
+ /**
+ * @param values
+ * The array to view
+ */
+ protected void setValues(V[] values) {
+ this.values = values;
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ for (V t : values) {
+ if (t.equals(o)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> collection) {
+ for (Object single : collection) {
+ if (!contains(single)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return values.length == 0;
+ }
+
+ @Override
+ public Iterator<V> iterator() {
+ return new Iterator<V>() {
+ int i;
+
+ @Override
+ public boolean hasNext() {
+ return i < values.length;
+ }
+
+ @Override
+ public V next() {
+ if (i == values.length) {
+ throw new NoSuchElementException("Reading past end of iterator");
+ }
+ return values[i++];
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("Read only iterator");
+ }
+ };
+ }
+
+ @Override
+ public int size() {
+ return values.length;
+ }
+
+ @Override
+ public Object[] toArray() {
+ return values.clone();
+ }
+
+ @Override
+ public <T> T[] toArray(T[] a) {
+ int numberToNull = a.length - values.length;
+ if (numberToNull >= 0) {
+ System.arraycopy(values, 0, a, 0, values.length);
+ if (numberToNull > 0) {
+ Arrays.fill(a, values.length, a.length, null);
+ }
+ return a;
+ }
+
+ @SuppressWarnings("unchecked")
+ T[] rv = (T[]) Array.newInstance(a.getClass().getComponentType(), values.length);
+ System.arraycopy(values, 0, rv, 0, values.length);
+ return rv;
+ }
+
+ @Override
+ final public boolean add(V e) {
+ throw new UnsupportedOperationException("Set is readonly");
+ }
+
+ @Override
+ final public boolean addAll(Collection<? extends V> c) {
+ throw new UnsupportedOperationException("Set is readonly");
+ }
+
+ @Override
+ final public void clear() {
+ throw new UnsupportedOperationException("Set is readonly");
+ }
+
+ @Override
+ final public boolean remove(Object e) {
+ throw new UnsupportedOperationException("Set is readonly");
+ }
+
+ @Override
+ final public boolean removeAll(Collection<?> c) {
+ throw new UnsupportedOperationException("Set is readonly");
+ }
+
+ @Override
+ final public boolean retainAll(Collection<?> c) {
+ throw new UnsupportedOperationException("Set is readonly");
+ }
+
+}
Added: commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/ReapingHashMap.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/ReapingHashMap.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/ReapingHashMap.java (added)
+++ commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/ReapingHashMap.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,176 @@
+/*
+ * Licensed 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.commons.classscan.util;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+public final class ReapingHashMap<K, V> implements Map<K, V> {
+
+ private final ConcurrentMap<HashWeakReference<K>, V> innerMap = new ConcurrentHashMap<HashWeakReference<K>, V>();
+ private final ReferenceQueue<K> queue = new ReferenceQueue<K>();
+ private final Thread reaper = new ReaperThread();
+
+ public ReapingHashMap() {
+ reaper.setDaemon(true);
+ reaper.start();
+ }
+
+ private class ReaperThread extends Thread {
+ ReaperThread() {
+ super("WeakConcurrentHashMap-" + System.identityHashCode(ReapingHashMap.this) + "-reaper");
+ }
+
+ @Override
+ public void run() {
+ for (;;) {
+ try {
+ Reference<? extends K> ref = queue.remove();
+ HashWeakReference<? extends K> key = (HashWeakReference<? extends K>) ref;
+ innerMap.remove(key);
+ }
+ catch (InterruptedException ignore) {
+ }
+ }
+ }
+ }
+
+ @Override
+ public V put(K key, V value) {
+ HashWeakReference<K> innerKey = new HashWeakReference<K>(key, queue);
+ return innerMap.put(innerKey, value);
+ }
+
+ @Override
+ public V get(Object key) {
+ KeyReference<Object> innerKey = new KeyReference<Object>(key);
+ return innerMap.get(innerKey);
+ }
+
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean containsValue(Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<Map.Entry<K, V>> entrySet() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<K> keySet() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void putAll(Map<? extends K, ? extends V> m) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public V remove(Object key) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int size() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Collection<V> values() {
+ throw new UnsupportedOperationException();
+ }
+
+ static class HashWeakReference<T> extends WeakReference<T> {
+ private final int hashCode;
+
+ HashWeakReference(T referent, ReferenceQueue<? super T> queue) {
+ super(referent, queue);
+ hashCode = System.identityHashCode(referent);
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(this==obj) {
+ return true;
+ }
+ if(obj instanceof KeyReference) {
+ @SuppressWarnings("unchecked")
+ KeyReference<T> key= (KeyReference<T>)obj;
+ return key.compare(this);
+ }
+ throw new UnsupportedOperationException(obj.getClass().getCanonicalName());
+ }
+ }
+
+ static class KeyReference<T> {
+ private final T key;
+ private final int keyHash;
+
+ public KeyReference(T key) {
+ this.key= key;
+ keyHash= System.identityHashCode(key);
+ }
+
+ @Override
+ public int hashCode() {
+ return keyHash;
+ }
+
+ /**
+ * HashMap should only compare KeyReference with HashWeakReference
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if(obj instanceof HashWeakReference) {
+ @SuppressWarnings("unchecked")
+ HashWeakReference<T> weakKey = (HashWeakReference<T>)obj;
+ return compare(weakKey);
+ }
+ throw new UnsupportedOperationException(obj.getClass().getCanonicalName());
+ }
+
+ boolean compare(HashWeakReference<T> ref) {
+ T t = ref.get();
+ return key==t;
+ }
+ }
+}
Added: commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/ResolveSet.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/ResolveSet.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/ResolveSet.java (added)
+++ commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/ResolveSet.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,41 @@
+/*
+ * Licensed 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.commons.classscan.util;
+
+import org.apache.commons.classscan.spi.model.HasResolve;
+import org.apache.commons.classscan.spi.model.SpiMetaClassLoader;
+
+public class ResolveSet<V extends HasResolve> extends ReadOnlySet<V> {
+
+ public ResolveSet(V[] values) {
+ super(values);
+ }
+
+ public boolean resolve(SpiMetaClassLoader mcl) {
+ for(V value : values) {
+ if(!value.resolve(mcl)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static ResolveSet<HasResolve> EMPTY_SET = new ResolveSet<HasResolve>(new HasResolve[0]);
+
+ public static <V extends HasResolve> ResolveSet<V> emptyResolveSet() {
+ @SuppressWarnings("unchecked")
+ ResolveSet<V> rc = (ResolveSet<V>) EMPTY_SET;
+ return rc;
+ }
+}
Added: commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/ServiceVisitor.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/ServiceVisitor.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/ServiceVisitor.java (added)
+++ commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/ServiceVisitor.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,65 @@
+/*
+ * Licensed 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.commons.classscan.util;
+
+import java.util.Iterator;
+import java.util.ServiceConfigurationError;
+import java.util.ServiceLoader;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Visit the provider instances specified in the META-INF/services directories
+ *
+ * @param <T> The type of the provider
+ */
+public abstract class ServiceVisitor<T> {
+
+ private static final Logger logger = LoggerFactory.getLogger(ServiceVisitor.class);
+
+ /**
+ * Visit the service provider available for the given interface and ClassLoader
+ *
+ * @param serviceInterface The interface of the service
+ * @param classLoader The ClassLoader which will load the service
+ */
+ public void visitProviders(Class<T> factoryClass, ClassLoader classLoader) {
+ Iterator<T> factories = ServiceLoader.load(factoryClass, classLoader).iterator();
+ for(;;) {
+ // this odd loop is due to the possibility of the iterator throwing
+ // ServiceConfigurationError from either hasNext() or next()
+ try {
+ if(!factories.hasNext()) {
+ break;
+ }
+ T factory = factories.next();
+ if(!visit(factory)) {
+ break;
+ }
+ }
+ catch(ServiceConfigurationError error) {
+ logger.warn("Ignoring configuration error", error);
+ }
+ }
+ }
+
+ /**
+ * The callback method which is invoked upon finding a service provider
+ *
+ * @param serviceProvider An instance of the service provider
+ * @return true, if additional service providers desired; false, stop the visiting
+ */
+ abstract protected boolean visit(T serviceProvider);
+}
Added: commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/package-info.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/package-info.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/package-info.java (added)
+++ commons/sandbox/classscan/trunk/api/src/main/java/org/apache/commons/classscan/util/package-info.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,18 @@
+/*
+ * Licensed 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.
+ */
+/**
+ * <p>The util package consists of utility collection implementations to support the {@link org.apache.commons.classscan.bcel} package.</p>
+ * <p><b>These classes are subject to change in any release.</b></p>
+ */
+package org.apache.commons.classscan.util;
\ No newline at end of file
Added: commons/sandbox/classscan/trunk/api/src/main/resources/META-INF/services/org.apache.commons.classscan.spi.ClassPathElementFactory
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/main/resources/META-INF/services/org.apache.commons.classscan.spi.ClassPathElementFactory?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/main/resources/META-INF/services/org.apache.commons.classscan.spi.ClassPathElementFactory (added)
+++ commons/sandbox/classscan/trunk/api/src/main/resources/META-INF/services/org.apache.commons.classscan.spi.ClassPathElementFactory Thu Jul 5 02:48:34 2012
@@ -0,0 +1,15 @@
+#
+# Licensed 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.
+#
+
+org.apache.commons.classscan.builtin.DefaultClassPathElementFactory
Added: commons/sandbox/classscan/trunk/api/src/main/resources/META-INF/services/org.apache.commons.classscan.spi.ClassPathFactory
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/main/resources/META-INF/services/org.apache.commons.classscan.spi.ClassPathFactory?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/main/resources/META-INF/services/org.apache.commons.classscan.spi.ClassPathFactory (added)
+++ commons/sandbox/classscan/trunk/api/src/main/resources/META-INF/services/org.apache.commons.classscan.spi.ClassPathFactory Thu Jul 5 02:48:34 2012
@@ -0,0 +1,15 @@
+#
+# Licensed 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.
+#
+
+org.apache.commons.classscan.builtin.DefaultClassPathFactory
Added: commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/AnnotationAnnotation.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/AnnotationAnnotation.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/AnnotationAnnotation.java (added)
+++ commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/AnnotationAnnotation.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,22 @@
+/*
+ * Licensed 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.commons.classscan.test.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target(ElementType.ANNOTATION_TYPE)
+public @interface AnnotationAnnotation {
+
+}
Added: commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/ConstructorAnnotation.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/ConstructorAnnotation.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/ConstructorAnnotation.java (added)
+++ commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/ConstructorAnnotation.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,22 @@
+/*
+ * Licensed 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.commons.classscan.test.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target(ElementType.CONSTRUCTOR)
+public @interface ConstructorAnnotation {
+
+}
Added: commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/FieldAnnotation.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/FieldAnnotation.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/FieldAnnotation.java (added)
+++ commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/FieldAnnotation.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,22 @@
+/*
+ * Licensed 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.commons.classscan.test.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target(ElementType.FIELD)
+public @interface FieldAnnotation {
+
+}
Added: commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/MethodAnnotation.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/MethodAnnotation.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/MethodAnnotation.java (added)
+++ commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/MethodAnnotation.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,22 @@
+/*
+ * Licensed 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.commons.classscan.test.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target(ElementType.METHOD)
+public @interface MethodAnnotation {
+
+}
Added: commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/ParameterAnnotation.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/ParameterAnnotation.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/ParameterAnnotation.java (added)
+++ commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/ParameterAnnotation.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,22 @@
+/*
+ * Licensed 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.commons.classscan.test.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target(ElementType.PARAMETER)
+public @interface ParameterAnnotation {
+
+}
Added: commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/TestEnum.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/TestEnum.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/TestEnum.java (added)
+++ commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/TestEnum.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,18 @@
+/*
+ * Licensed 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.commons.classscan.test.annotations;
+
+public enum TestEnum {
+ One, Two, Three
+}
Added: commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/TypeAnnotation.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/TypeAnnotation.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/TypeAnnotation.java (added)
+++ commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/annotations/TypeAnnotation.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,48 @@
+/*
+ * Licensed 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.commons.classscan.test.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+
+@Target(ElementType.TYPE)
+public @interface TypeAnnotation {
+
+ double doubleValue();
+
+ int longValue();
+
+ int shortValue();
+
+ String stringValue();
+
+ boolean booleanValue();
+
+ String[] stringArrayValue();
+
+ Class<Object> classValue();
+
+ AnnotationAnnotation annotationValue();
+
+ float floatValue();
+
+ char charValue();
+
+ int intValue();
+
+ int byteValue();
+
+ TestEnum enumValue();
+}
Added: commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/classes/BadPackage.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/classes/BadPackage.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/classes/BadPackage.java (added)
+++ commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/classes/BadPackage.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,30 @@
+/*
+ * Licensed 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.commons.wrong.test.classes; // intentionally wrong package to force error condition
+
+public class BadPackage {
+ String field;
+
+ public BadPackage(String field) {
+ this.field = field;
+ }
+
+ public String getField() {
+ return field;
+ }
+
+ public void setField(String field) {
+ this.field = field;
+ }
+}
Added: commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/classes/FullInterface.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/classes/FullInterface.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/classes/FullInterface.java (added)
+++ commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/classes/FullInterface.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,26 @@
+/*
+ * Licensed 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.commons.classscan.test.classes;
+
+import org.apache.commons.classscan.test.annotations.MethodAnnotation;
+import org.apache.commons.classscan.test.annotations.ParameterAnnotation;
+
+public interface FullInterface {
+
+ @MethodAnnotation
+ int[] getField();
+
+ void setField(@ParameterAnnotation int[] field);
+
+}
\ No newline at end of file
Added: commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/classes/FullyDecorated.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/classes/FullyDecorated.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/classes/FullyDecorated.java (added)
+++ commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/classes/FullyDecorated.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,53 @@
+/*
+ * Licensed 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.commons.classscan.test.classes;
+
+import java.io.Serializable;
+
+import org.apache.commons.classscan.test.annotations.AnnotationAnnotation;
+import org.apache.commons.classscan.test.annotations.ConstructorAnnotation;
+import org.apache.commons.classscan.test.annotations.FieldAnnotation;
+import org.apache.commons.classscan.test.annotations.MethodAnnotation;
+import org.apache.commons.classscan.test.annotations.ParameterAnnotation;
+import org.apache.commons.classscan.test.annotations.TestEnum;
+import org.apache.commons.classscan.test.annotations.TypeAnnotation;
+
+@TypeAnnotation(byteValue = 1, charValue = '&', doubleValue = Math.PI, floatValue = (float) Math.E, intValue = 42, longValue = 3360, shortValue = 1895, booleanValue = true, stringValue = "testing", stringArrayValue = {
+ "one", "two" }, enumValue = TestEnum.Three, classValue = Object.class, annotationValue = @AnnotationAnnotation)
+public class FullyDecorated implements Serializable, FullInterface {
+ private static final long serialVersionUID = 1L;
+
+ @FieldAnnotation
+ private int[] field;
+
+ public static long getSerialVersion() {
+ return serialVersionUID;
+ }
+
+ @ConstructorAnnotation
+ public FullyDecorated(int[] field) {
+ this.field = field;
+ }
+
+ @Override
+ @MethodAnnotation
+ public int[] getField() {
+ return field;
+ }
+
+ @Override
+ public void setField(@ParameterAnnotation int[] field) {
+ this.field = field;
+ }
+}
Added: commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/classes/ValidateFullyDecorated.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/classes/ValidateFullyDecorated.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/classes/ValidateFullyDecorated.java (added)
+++ commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/test/classes/ValidateFullyDecorated.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,331 @@
+/*
+ * Licensed 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.commons.classscan.test.classes;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import org.apache.commons.classscan.model.MetaAnnotation;
+import org.apache.commons.classscan.model.MetaAnnotation.Property;
+import org.apache.commons.classscan.model.MetaArray;
+import org.apache.commons.classscan.model.MetaClass;
+import org.apache.commons.classscan.model.MetaField;
+import org.apache.commons.classscan.model.MetaMethod;
+import org.apache.commons.classscan.model.MetaParameter;
+import org.apache.commons.classscan.model.MetaType;
+import org.apache.commons.classscan.test.annotations.AnnotationAnnotation;
+import org.apache.commons.classscan.test.annotations.ConstructorAnnotation;
+import org.apache.commons.classscan.test.annotations.FieldAnnotation;
+import org.apache.commons.classscan.test.annotations.MethodAnnotation;
+import org.apache.commons.classscan.test.annotations.ParameterAnnotation;
+import org.apache.commons.classscan.test.annotations.TestEnum;
+import org.apache.commons.classscan.test.annotations.TypeAnnotation;
+
+public class ValidateFullyDecorated {
+
+ public ValidateFullyDecorated(MetaClass fdClass) {
+ assertClassParent(fdClass.getParent());
+ assertInterfaces(fdClass.getInterfaces());
+ assertClassAnnotations(fdClass.getAnnotations());
+ assertClassAnnotation(fdClass.getAnnotation(TypeAnnotation.class.getCanonicalName()));
+ assertMethods(fdClass.getMethods());
+ assertFields(fdClass.getFields());
+ }
+
+ private void assertClassParent(MetaClass objectClass) {
+ assertEquals(Object.class.getCanonicalName(), objectClass.getName());
+ assertNull(objectClass.getParent());
+ }
+
+ private void assertInterfaces(Set<? extends MetaClass> set) {
+ assertEquals(2, set.size());
+ for (MetaClass iface : set) {
+ String interfaceName = iface.getName();
+ if(interfaceName.equals(Serializable.class.getCanonicalName())) {
+ continue;
+ }
+ else if(interfaceName.equals(FullInterface.class.getCanonicalName())) {
+ continue;
+ }
+ else {
+ fail("unexpected interface " + interfaceName);
+ }
+ }
+ assertReadOnlySet(set);
+ }
+
+ private void assertClassAnnotations(Set<? extends MetaAnnotation> collection) {
+ assertEquals(1, collection.size());
+ for (MetaAnnotation annotation : collection) {
+ assertEquals(TypeAnnotation.class.getCanonicalName(), annotation.getName());
+ assertClassAnnotation(annotation);
+ }
+ assertReadOnlySet(collection);
+ }
+
+ private void assertClassAnnotation(MetaAnnotation annotation) {
+ Collection<? extends Property> properties = annotation.getProperties();
+ assertEquals(13, properties.size());
+ for (MetaAnnotation.Property property : properties) {
+ String propertyName = property.getName();
+ if (propertyName.equals("byteValue")) {
+ assertEquals(new Byte((byte) 1), property.getValue());
+ }
+ else if (propertyName.equals("charValue")) {
+ assertEquals(new Character('&'), property.getValue());
+ }
+ else if (propertyName.equals("doubleValue")) {
+ assertEquals(new Double(Math.PI), property.getValue());
+ }
+ else if (propertyName.equals("floatValue")) {
+ assertEquals(new Float(Math.E), property.getValue());
+ }
+ else if (propertyName.equals("intValue")) {
+ assertEquals(new Integer(42), property.getValue());
+ }
+ else if (propertyName.equals("longValue")) {
+ assertEquals(new Long(3360), property.getValue());
+ }
+ else if (propertyName.equals("shortValue")) {
+ assertEquals(new Short((short) 1895), property.getValue());
+ }
+ else if (propertyName.equals("booleanValue")) {
+ assertEquals(Boolean.TRUE, property.getValue());
+ }
+ else if (propertyName.equals("stringValue")) {
+ assertEquals("testing", property.getValue());
+ }
+ else if (propertyName.equals("stringArrayValue")) {
+ assertTrue(Arrays.deepEquals(new String[] { "one", "two" }, (Object[]) property.getValue()));
+ }
+ else if (propertyName.equals("annotationValue")) {
+ MetaAnnotation ma = (MetaAnnotation) property.getValue();
+ assertEquals(AnnotationAnnotation.class.getCanonicalName(), ma.getName());
+ }
+ else if (propertyName.equals("enumValue")) {
+ MetaAnnotation.EnumValue ev = (MetaAnnotation.EnumValue) property.getValue();
+ assertEquals(TestEnum.class.getCanonicalName(), ev.getEnumType().getName());
+ assertEquals("Three", ev.getEnumValue());
+ }
+ else if (propertyName.equals("classValue")) {
+ MetaClass mc = (MetaClass) property.getValue();
+ assertEquals(Object.class.getCanonicalName(), mc.getName());
+ }
+ else {
+ fail("unexpected property " + propertyName);
+ }
+ }
+
+ MetaAnnotation.Property byteValue = annotation.getProperty("byteValue");
+ assertEquals(new Byte((byte) 1), byteValue.getValue());
+ assertNull(annotation.getProperty("freddy"));
+ }
+
+ private void assertFields(Set<? extends MetaField> set) {
+ assertEquals(2, set.size());
+ for (MetaField field : set) {
+ if (field.getName().equals("field")) {
+ assertField(field);
+ }
+ else if (field.getName().equals("serialVersionUID")) {
+ assertSerialVersionField(field);
+ }
+ else {
+ fail("unexpected field " + field.getName());
+ }
+ }
+ assertReadOnlySet(set);
+ }
+
+ private void assertField(MetaField field) {
+ assertEquals(false, field.isStatic());
+ assertIntegerArrayType(field.getType());
+ assertAnnotation(FieldAnnotation.class.getCanonicalName(), field.getAnnotations());
+ }
+
+ private void assertLongType(MetaType mt) {
+ MetaClass mc = (MetaClass)mt;
+ assertEquals(Long.TYPE.getCanonicalName(), mc.getName());
+ }
+
+ private void assertIntegerArrayType(MetaType mt) {
+ MetaArray ma = (MetaArray)mt;
+ MetaClass mc = (MetaClass)ma.getArrayType();
+ assertEquals(Integer.TYPE.getCanonicalName(), mc.getName());
+ }
+
+ private void assertSerialVersionField(MetaField field) {
+ assertEquals(true, field.isStatic());
+ assertLongType(field.getType());
+ Set<? extends MetaAnnotation> annotations = field.getAnnotations();
+ assertTrue(annotations.isEmpty());
+ assertReadOnlySet(annotations);
+ }
+
+ private void assertMethods(Set<? extends MetaMethod> set) {
+ assertEquals(4, set.size());
+ for (MetaMethod method : set) {
+ String methodName = method.getName();
+ if (methodName.equals("<init>")) {
+ assertConstructor(method);
+ }
+ else if (methodName.equals("getField")) {
+ assertGetFieldMethod(method);
+ }
+ else if (methodName.equals("getSerialVersion")) {
+ assertGetSerialVersionMethod(method);
+ }
+ else if (methodName.equals("setField")) {
+ assertSetFieldMethod(method);
+ }
+ else {
+ fail("unexpected method " + methodName);
+ }
+ }
+ assertReadOnlySet(set);
+ }
+
+ private void assertAnnotation(String annotationName, Set<? extends MetaAnnotation> set) {
+ assertEquals(1, set.size());
+ for (MetaAnnotation annotation : set) {
+ assertEquals(annotationName, annotation.getName());
+ }
+ }
+
+ private void assertGetFieldMethod(MetaMethod method) {
+ assertEquals(false, method.isStatic());
+ assertIntegerArrayType(method.getType());
+ assertAnnotation(MethodAnnotation.class.getCanonicalName(), method.getAnnotations());
+ }
+
+ private void assertGetSerialVersionMethod(MetaMethod method) {
+ assertEquals(true, method.isStatic());
+ assertLongType(method.getType());
+ assertTrue(method.getAnnotations().isEmpty());
+ }
+
+ private void assertConstructor(MetaMethod method) {
+ assertAnnotation(ConstructorAnnotation.class.getCanonicalName(), method.getAnnotations());
+ }
+
+ private void assertSetFieldMethod(MetaMethod method) {
+ Set<? extends MetaParameter> parameters = method.getParameters();
+ assertEquals(1, parameters.size());
+
+ for (MetaParameter parameter : parameters) {
+ assertAnnotation(ParameterAnnotation.class.getCanonicalName(), parameter.getAnnotations());
+ assertIntegerArrayType(parameter.getType());
+ }
+ assertReadOnlySet(parameters);
+ }
+
+ private <T> void assertReadOnlySet(Set<T> collection) {
+ Object[] cpy = collection.toArray();
+ Object[] allocatedArray = new Object[2];
+ Object[] cpy2 = collection.toArray(allocatedArray);
+ if (collection.size() <= 2) {
+ assertSame(allocatedArray, cpy2);
+ if (collection.size() == 1) {
+ assertNull(cpy2[1]);
+ }
+ }
+ int i = 0;
+ for (T element : collection) {
+ assertEquals(element, cpy[i++]);
+ }
+ if(collection.isEmpty()) {
+ return;
+ }
+
+ assertTrue(collection.containsAll(collection));
+ try {
+ collection.clear();
+ fail("Set not acting read-only");
+ }
+ catch (UnsupportedOperationException expected) {
+ }
+ try {
+ collection.addAll(collection);
+ fail("Set not acting read-only");
+ }
+ catch (UnsupportedOperationException expected) {
+ }
+
+ try {
+ collection.retainAll(collection);
+ fail("Set not acting read-only");
+ }
+ catch (UnsupportedOperationException expected) {
+ }
+
+ try {
+ collection.removeAll(collection);
+ fail("Set not acting read-only");
+ }
+ catch (UnsupportedOperationException expected) {
+ }
+
+ assertFalse(collection.contains(this));
+
+ Iterator<T> iterator = collection.iterator();
+ if (collection.isEmpty()) {
+ assertFalse(iterator.hasNext());
+ try {
+ iterator.next();
+ fail("Iterating past end of elements");
+ }
+ catch (NoSuchElementException expected) {
+ }
+
+ Set<T> singleValueSet = new HashSet<T>(1);
+ singleValueSet.add(null);
+
+ assertFalse(collection.containsAll(singleValueSet));
+ }
+ else {
+ T singleValue = iterator.next();
+ try {
+ iterator.remove();
+ fail("Iterator not acting read-only");
+ }
+ catch (UnsupportedOperationException expected) {
+ }
+ assertTrue(collection.contains(singleValue));
+ try {
+ collection.remove(singleValue);
+ fail("Set not acting read-only");
+ }
+ catch (UnsupportedOperationException expected) {
+ }
+ try {
+ collection.add(singleValue);
+ fail("Set not acting read-only");
+ }
+ catch (UnsupportedOperationException expected) {
+ }
+ }
+ }
+}
Added: commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/util/ReapingHashMapTest.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/util/ReapingHashMapTest.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/util/ReapingHashMapTest.java (added)
+++ commons/sandbox/classscan/trunk/api/src/test/java/org/apache/commons/classscan/util/ReapingHashMapTest.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,105 @@
+package org.apache.commons.classscan.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+public class ReapingHashMapTest {
+
+ @Test
+ public void testHashWeakReferenceIsCollected() throws InterruptedException {
+ ReferenceQueue<BigObject> queue = new ReferenceQueue<BigObject>();
+ ReapingHashMap.HashWeakReference<BigObject> hwr = new ReapingHashMap.HashWeakReference<BigObject>(new BigObject(2), queue);
+ assertNotNull(hwr.get());
+ forceWeakRefCollection(queue, hwr);
+ }
+
+ @Test
+ public void testNullReferenceIsNotCollected() throws InterruptedException {
+ ReferenceQueue<BigObject> queue = new ReferenceQueue<BigObject>();
+
+ ReapingHashMap.HashWeakReference<BigObject> nullRef = new ReapingHashMap.HashWeakReference<BigObject>(null, queue);
+ assertNull(nullRef.get());
+
+ ReapingHashMap.HashWeakReference<BigObject> nnRef = new ReapingHashMap.HashWeakReference<BigObject>(new BigObject(2), queue);
+ forceWeakRefCollection(queue, nnRef);
+
+ assertFalse(nullRef.isEnqueued());
+ assertNull(queue.poll());
+ }
+
+ @Test(timeout=10000)
+ public void testReapingHashMapIsCollected() throws InterruptedException {
+ ReapingHashMap<BigObject, Integer> rhm = new ReapingHashMap<BigObject, Integer>();
+ WeakReference<BigObject> key = notReaped(rhm);
+ do {
+ testHashWeakReferenceIsCollected();
+ }
+ while(key.get()!=null);
+ }
+
+ public WeakReference<BigObject> notReaped(ReapingHashMap<BigObject, Integer> rhm) {
+ BigObject key = new BigObject(2);
+ Integer value = new Integer(2);
+
+ assertNull(rhm.get(null));
+ assertNull(rhm.get(key));
+
+ rhm.put(key, value);
+ assertEquals(value, rhm.get(key));
+
+ Integer nullValue = new Integer(0);
+ rhm.put(null, nullValue);
+ assertEquals(nullValue, rhm.get(null));
+
+ return new WeakReference<BigObject>(key);
+ }
+
+ static class BigObject {
+ byte[][] lotsOfMemory;
+
+ BigObject(int max) {
+ byte[][] holder= new byte[max][];
+ int power= 1;
+ for(int i= 0; i<holder.length; ++i) {
+ byte[] bytes= new byte[power];
+ holder[i]= bytes;
+ power*= 2;
+ }
+ }
+ };
+
+ public <T> void forceWeakRefCollection(ReferenceQueue<T> queue, WeakReference<T> ref) throws InterruptedException {
+
+ List<BigObject> list = new ArrayList<BigObject>();
+ for (int i = 0; true; i++) {
+ try {
+ BigObject holder = new BigObject(i);
+ list.add(holder);
+ } catch (OutOfMemoryError oome) {
+ i = 0;
+ }
+
+ if(ref.isEnqueued()) {
+ assertTrue(ref.isEnqueued());
+ Reference<? extends T> pollRef = queue.remove(1000);
+ assertSame(pollRef, ref);
+ assertEquals(pollRef, ref);
+ assertFalse(ref.isEnqueued());
+ assertNull(ref.get());
+ return;
+ }
+ }
+ }
+}
\ No newline at end of file
Added: commons/sandbox/classscan/trunk/api/src/test/resources/META-INF/services/org.apache.commons.classscan.test.classes.FullInterface
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/test/resources/META-INF/services/org.apache.commons.classscan.test.classes.FullInterface?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/test/resources/META-INF/services/org.apache.commons.classscan.test.classes.FullInterface (added)
+++ commons/sandbox/classscan/trunk/api/src/test/resources/META-INF/services/org.apache.commons.classscan.test.classes.FullInterface Thu Jul 5 02:48:34 2012
@@ -0,0 +1,15 @@
+#
+# Licensed 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.
+#
+
+org.apache.commons.classcan.test.classes.FullyDecorated
Added: commons/sandbox/classscan/trunk/api/src/test/resources/logback.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/test/resources/logback.xml?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/test/resources/logback.xml (added)
+++ commons/sandbox/classscan/trunk/api/src/test/resources/logback.xml Thu Jul 5 02:48:34 2012
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed 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.
+-->
+<configuration debug="false">
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <pattern>%logger{15} %level: %message %nopex%n</pattern>
+ </layout>
+ </appender>
+
+ <root>
+ <level value="INFO" />
+ <appender-ref ref="STDOUT" />
+ </root>
+
+</configuration>
\ No newline at end of file
Added: commons/sandbox/classscan/trunk/api/src/test/resources/org/apache/commons/classscan/test/classes/--InvalidClassName--.class
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/test/resources/org/apache/commons/classscan/test/classes/--InvalidClassName--.class?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/test/resources/org/apache/commons/classscan/test/classes/--InvalidClassName--.class (added)
+++ commons/sandbox/classscan/trunk/api/src/test/resources/org/apache/commons/classscan/test/classes/--InvalidClassName--.class Thu Jul 5 02:48:34 2012
@@ -0,0 +1,2 @@
+
+This is a file that is not a class. This file exists to force error condition.
\ No newline at end of file
Added: commons/sandbox/classscan/trunk/api/src/test/resources/org/apache/commons/classscan/test/classes/NotAClass.class
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/api/src/test/resources/org/apache/commons/classscan/test/classes/NotAClass.class?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/api/src/test/resources/org/apache/commons/classscan/test/classes/NotAClass.class (added)
+++ commons/sandbox/classscan/trunk/api/src/test/resources/org/apache/commons/classscan/test/classes/NotAClass.class Thu Jul 5 02:48:34 2012
@@ -0,0 +1,2 @@
+
+This is a file that is not a class. This file exists to force error condition.
\ No newline at end of file
Added: commons/sandbox/classscan/trunk/bcel/pom.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/bcel/pom.xml?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/bcel/pom.xml (added)
+++ commons/sandbox/classscan/trunk/bcel/pom.xml Thu Jul 5 02:48:34 2012
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+ 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.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.commons.classscan</groupId>
+ <artifactId>bcel</artifactId>
+ <name>ClassScan BCEL class reader provider</name>
+ <version>0.2-SNAPSHOT</version>
+ <description>The Class Digester using BCEL to read class definitions</description>
+
+ <parent>
+ <groupId>org.apache.commons.classscan</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.2-SNAPSHOT</version>
+ <relativePath>../parent</relativePath>
+ </parent>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.commons.classscan</groupId>
+ <artifactId>api</artifactId>
+ <version>0.2-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.commons.classscan</groupId>
+ <artifactId>api</artifactId>
+ <version>0.2-SNAPSHOT</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.bcel</groupId>
+ <artifactId>bcel</artifactId>
+ <version>6.0-SNAPSHOT</version>
+ </dependency>
+
+ </dependencies>
+
+</project>
Added: commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/AnnotationMap.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/AnnotationMap.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/AnnotationMap.java (added)
+++ commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/AnnotationMap.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,42 @@
+/*
+ * Licensed 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.commons.classscan.bcel;
+
+import org.apache.bcel.classfile.AnnotationEntry;
+import org.apache.commons.classscan.util.NameSet;
+
+public class AnnotationMap extends NameSet<BcelAnnotation> {
+
+ private static AnnotationMap EMPTY_ANNOTATIONS= new AnnotationMap(new AnnotationEntry[0]);
+
+ public static AnnotationMap createAnnotations(AnnotationEntry[] annotationEntries) {
+ if(annotationEntries==null || annotationEntries.length==0) {
+ return EMPTY_ANNOTATIONS;
+ }
+ return new AnnotationMap(annotationEntries);
+ }
+
+ private AnnotationMap(AnnotationEntry[] entries) {
+ super(transformEntries(entries));
+ }
+
+ static private BcelAnnotation[] transformEntries(AnnotationEntry[] entries) {
+
+ BcelAnnotation[] annotations = new BcelAnnotation[entries.length];
+ for(int i = 0; i<entries.length; ++i) {
+ annotations[i]= new BcelAnnotation(entries[i]);
+ }
+ return annotations;
+ }
+}
Added: commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelAnnotation.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelAnnotation.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelAnnotation.java (added)
+++ commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelAnnotation.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,69 @@
+/*
+ * Licensed 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.commons.classscan.bcel;
+
+import java.util.Set;
+
+import org.apache.bcel.classfile.AnnotationEntry;
+import org.apache.bcel.classfile.ElementValuePair;
+import org.apache.commons.classscan.builtin.ClassNameHelper;
+import org.apache.commons.classscan.spi.model.SpiMetaAnnotation;
+import org.apache.commons.classscan.spi.model.SpiMetaClassLoader;
+import org.apache.commons.classscan.util.NameSet;
+
+public class BcelAnnotation implements SpiMetaAnnotation {
+
+ private final String name;
+ private final NameSet<SpiProperty> properties;
+
+ public BcelAnnotation(AnnotationEntry annotation) {
+ name = ClassNameHelper.internalToCanonicalName(annotation.getAnnotationType());
+
+ ElementValuePair[] elementValuePairs = annotation.getElementValuePairs();
+ if (elementValuePairs.length == 0) {
+ properties = NameSet.emptyNameSet();
+ }
+ else {
+ properties = new NameSet<SpiProperty>(fillMapAndArray(elementValuePairs));
+ }
+ }
+
+ @Override
+ public boolean resolve(SpiMetaClassLoader classLoader) {
+ return properties.resolve(classLoader);
+ }
+
+ private SpiProperty[] fillMapAndArray(ElementValuePair[] evPairs) {
+ SpiProperty[] values = new SpiProperty[evPairs.length];
+ for (int i = 0; i < evPairs.length; ++i) {
+ values[i] = new BcelProperty(evPairs[i]);
+ }
+ return values;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public Set<? extends Property> getProperties() {
+ return properties;
+ }
+
+ @Override
+ public Property getProperty(String propertyName) {
+ return properties.getValue(propertyName);
+ }
+}
Added: commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelClass.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelClass.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelClass.java (added)
+++ commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelClass.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,239 @@
+/*
+ * Licensed 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.commons.classscan.bcel;
+
+import java.io.IOException;
+import java.util.Set;
+
+import org.apache.bcel.classfile.ClassFormatException;
+import org.apache.bcel.classfile.ClassParser;
+import org.apache.bcel.classfile.Field;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.Method;
+import org.apache.commons.classscan.MetaClassPathElement;
+import org.apache.commons.classscan.model.MetaAnnotation;
+import org.apache.commons.classscan.model.MetaClass;
+import org.apache.commons.classscan.model.MetaField;
+import org.apache.commons.classscan.model.MetaMethod;
+import org.apache.commons.classscan.spi.model.SpiMetaClass;
+import org.apache.commons.classscan.spi.model.SpiMetaClassLoader;
+import org.apache.commons.classscan.spi.model.SpiMetaField;
+import org.apache.commons.classscan.spi.model.SpiMetaMethod;
+import org.apache.commons.classscan.util.NameSet;
+import org.apache.commons.classscan.util.ReadOnlySet;
+import org.apache.commons.classscan.util.ResolveSet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BcelClass implements SpiMetaClass {
+
+ private static final Logger logger = LoggerFactory.getLogger(BcelClass.class);
+
+ private final MetaClassPathElement location;
+ private final String canonicalName;
+ private String parentName;
+ private MetaClass parent;
+ private String[] interfaceNames;
+ private Set<MetaClass> interfaces;
+ private final AnnotationMap annotations;
+ private final ResolveSet<SpiMetaMethod> methods;
+ private final ResolveSet<SpiMetaField> fields;
+ private Boolean resolutionResult;
+
+ public BcelClass(MetaClassPathElement location, ClassParser parser) throws ClassFormatException, IOException {
+ this.location = location;
+ JavaClass bcelClass = parser.parse();
+ canonicalName = bcelClass.getClassName();
+ parentName = getParentName(bcelClass);
+ interfaceNames = bcelClass.getInterfaceNames();
+ annotations = AnnotationMap.createAnnotations(bcelClass.getAnnotationEntries());
+ methods = createMethods(bcelClass);
+ fields = createFields(bcelClass);
+ }
+
+ @Override
+ public boolean resolve(SpiMetaClassLoader classLoader) {
+ if(resolutionResult == null) {
+ // set result to true to prevent re-resolution of classes involved in cyclic graphs
+ resolutionResult = Boolean.TRUE;
+ resolutionResult= Boolean.valueOf(resolveParent(classLoader)
+ && resolveInterfaces(classLoader)
+ && annotations.resolve(classLoader)
+ && methods.resolve(classLoader)
+ && fields.resolve(classLoader));
+ }
+ return resolutionResult;
+ }
+
+ private boolean resolveParent(SpiMetaClassLoader classLoader) {
+ boolean success = true;
+ if(parentName == null) {
+ // this is java.lang.Object
+ // parent should remain null
+ }
+ else {
+ parent = classLoader.resolveMetaClass(parentName);
+ if(parent == null) {
+ logger.info("Cannot find parent "+parentName+" for class "+canonicalName);
+ success= false;
+ }
+ parentName = null;
+ }
+ return success;
+ }
+
+ private static final ReadOnlySet<MetaClass> EMPTY_INTERFACES = new ReadOnlySet<MetaClass>(new MetaClass[0]);
+
+ private boolean resolveInterfaces(final SpiMetaClassLoader classLoader) {
+ boolean success= true;
+ if (interfaceNames==null || interfaceNames.length == 0) {
+ interfaces= EMPTY_INTERFACES;
+ }
+ else {
+ MetaClass[] metaClasses = new MetaClass[interfaceNames.length];
+ int i= 0;
+ for(String interfaceName : interfaceNames) {
+ MetaClass mc = classLoader.resolveMetaClass(interfaceName);
+ if(mc == null) {
+ logger.info("Cannot find interface "+interfaceName+" for class "+canonicalName);
+ success= false;
+ }
+ metaClasses[i++] = mc;
+ }
+ interfaces= new ReadOnlySet<MetaClass>(metaClasses);
+ }
+ interfaceNames= null;
+ return success;
+ }
+
+ @Override
+ public MetaClassPathElement getClassLocation() {
+ return location;
+ }
+
+ @Override
+ public String getName() {
+ return canonicalName;
+ }
+
+ @Override
+ public MetaClass getParent() {
+ return parent;
+ }
+
+ private String getParentName(JavaClass bcelClass) {
+ String superclassName = bcelClass.getSuperclassName();
+ if (superclassName.equals(canonicalName)) { // bcel behaves
+ // unexpectedly, Object's
+ // super class is Object
+ return null;
+ }
+ return superclassName;
+ }
+
+ @Override
+ public Set<MetaClass> getInterfaces() {
+ return interfaces;
+ }
+
+ @Override
+ public Set<? extends MetaAnnotation> getAnnotations() {
+ return annotations;
+ }
+
+ @Override
+ public MetaAnnotation getAnnotation(String annotationName) {
+ return annotations.getValue(annotationName);
+ }
+
+ @Override
+ public Set<? extends MetaMethod> getMethods() {
+ return methods;
+ }
+
+ private NameSet<SpiMetaMethod> createMethods(JavaClass bcelClass) {
+ Method[] methods = bcelClass.getMethods();
+ if (methods.length == 0) {
+ return NameSet.emptyNameSet();
+ }
+
+ SpiMetaMethod[] metaMethods = new SpiMetaMethod[methods.length];
+ for(int i = 0; i<methods.length; ++i) {
+ metaMethods[i]= new BcelMethod(methods[i]);
+ }
+
+ return new NameSet<SpiMetaMethod>(metaMethods);
+ }
+
+ @Override
+ public Set<? extends MetaField> getFields() {
+ return fields;
+ }
+
+ private ResolveSet<SpiMetaField> createFields(JavaClass bcelClass) {
+ Field[] fields = bcelClass.getFields();
+ if (fields.length == 0) {
+ return NameSet.emptyNameSet();
+ }
+
+ SpiMetaField[] metaFields = new SpiMetaField[fields.length];
+ for(int i = 0; i<fields.length; ++i) {
+ metaFields[i]= new BcelField(fields[i]);
+ }
+
+ return new ResolveSet<SpiMetaField>(metaFields);
+ }
+
+ @Override
+ public boolean isAssignableFrom(MetaClass assignor) {
+ do {
+ if (isAssignableFromAnyInterface(assignor)) {
+ return true;
+ }
+ assignor = assignor.getParent();
+ }
+ while (assignor != null);
+ return false;
+ }
+
+ private boolean isAssignableFromAnyInterface(MetaClass assignor) {
+ if (equals(assignor)) {
+ return true;
+ }
+ for (MetaClass derived : assignor.getInterfaces()) {
+ if (isAssignableFromAnyInterface(derived)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof MetaClass)) {
+ return false;
+ }
+ MetaClass other = (MetaClass) obj;
+ return canonicalName.equals(other.getName()) && location.equals(other.getClassLocation());
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 33;
+ int result = 1;
+ result = prime * result + canonicalName.hashCode();
+ result = prime * result + location.hashCode();
+ return result;
+ }
+}
Added: commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelClassDigesterFactory.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelClassDigesterFactory.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelClassDigesterFactory.java (added)
+++ commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelClassDigesterFactory.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,44 @@
+/*
+ * Licensed 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.commons.classscan.bcel;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.bcel.classfile.ClassParser;
+import org.apache.commons.classscan.MetaClassPathElement;
+import org.apache.commons.classscan.MetaRegistry;
+import org.apache.commons.classscan.spi.ClassDigesterFactory;
+import org.apache.commons.classscan.spi.model.SpiClassDigester;
+import org.apache.commons.classscan.spi.model.SpiMetaClass;
+
+/**
+ * A ClassDigesterFactory that uses BCEL to digest the class bytes
+ */
+public class BcelClassDigesterFactory implements ClassDigesterFactory {
+
+ // making digester an instance field ensures that BCEL library is loaded.
+ // If load is successful, this factory will produce a usable digester
+ private SpiClassDigester spiClassDigester = new SpiClassDigester() {
+ @Override
+ public SpiMetaClass createMetaClass(MetaClassPathElement location, String className, InputStream byteStream) throws IOException {
+ return new BcelClass(location, new ClassParser(byteStream, className));
+ }
+ };
+
+ @Override
+ public SpiClassDigester createDigester(MetaRegistry metaRegistry) {
+ return spiClassDigester;
+ }
+}
Added: commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelEnumProperty.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelEnumProperty.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelEnumProperty.java (added)
+++ commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelEnumProperty.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,37 @@
+/*
+ * Licensed 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.commons.classscan.bcel;
+
+import org.apache.commons.classscan.model.MetaAnnotation;
+import org.apache.commons.classscan.model.MetaClass;
+
+public class BcelEnumProperty implements MetaAnnotation.EnumValue {
+ final private MetaClass enumType;
+ final private String enumValue;
+
+ public BcelEnumProperty(MetaClass enumType, String enumValue) {
+ this.enumType = enumType;
+ this.enumValue = enumValue;
+ }
+
+ @Override
+ public MetaClass getEnumType() {
+ return enumType;
+ }
+
+ @Override
+ public String getEnumValue() {
+ return enumValue;
+ }
+}
Added: commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelField.java
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelField.java?rev=1357447&view=auto
==============================================================================
--- commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelField.java (added)
+++ commons/sandbox/classscan/trunk/bcel/src/main/java/org/apache/commons/classscan/bcel/BcelField.java Thu Jul 5 02:48:34 2012
@@ -0,0 +1,74 @@
+/*
+ * Licensed 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.commons.classscan.bcel;
+
+import java.util.Set;
+
+import org.apache.bcel.classfile.Field;
+import org.apache.commons.classscan.model.MetaAnnotation;
+import org.apache.commons.classscan.model.MetaType;
+import org.apache.commons.classscan.spi.model.SpiMetaClassLoader;
+import org.apache.commons.classscan.spi.model.SpiMetaField;
+
+public class BcelField implements SpiMetaField {
+
+ private final String fieldName;
+ private final boolean isStatic;
+ private String fieldSignature;
+ private MetaType metaType;
+ private final AnnotationMap annotations;
+
+ public BcelField(Field field) {
+ fieldName = field.getName();
+ isStatic = field.isStatic();
+ fieldSignature = field.getSignature();
+ annotations = AnnotationMap.createAnnotations(field.getAnnotationEntries());
+ }
+
+ @Override
+ public boolean resolve(SpiMetaClassLoader classLoader) {
+ metaType = classLoader.resolveTypeForDescriptor(fieldSignature);
+ if(metaType == null) {
+ return false;
+ }
+ fieldSignature = null;
+
+ return annotations.resolve(classLoader);
+ }
+
+ @Override
+ public String getName() {
+ return fieldName;
+ }
+
+ @Override
+ public Set<? extends MetaAnnotation> getAnnotations() {
+ return annotations;
+ }
+
+ @Override
+ public MetaAnnotation getAnnotation(String annotationName) {
+ return annotations.getValue(annotationName);
+ }
+
+ @Override
+ public boolean isStatic() {
+ return isStatic;
+ }
+
+ @Override
+ public MetaType getType() {
+ return metaType;
+ }
+}