alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Commons Attributes example source code file (AttributeIndex.java)

This example Commons Attributes source code file (AttributeIndex.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Commons Attributes tags/keywords

class, class, collection, collection, constructor, constructorparameter, hashset, indexnode, indexnode, io, iterator, iterator, method, methodparameter, net, network, reflection, string, util

The Commons Attributes AttributeIndex.java source code

/*
 * Copyright 2003-2005 The Apache Software Foundation
 * 
 * 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.attributes;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.StringTokenizer;

/**
 * An index providing a list of elements with given attributes. This
 * requires that the attribute is {@link Indexed} and that the
 * attribute indexer tool has been run on the jar file containing the
 * classes.
 *
 * @since 2.1
 */
public class AttributeIndex {
    
    /**
     * Reference to a method parameter. A method parameter
     * is defined by the Method object it is defined in, and the index
     * of the parameter in the method's parameter list.
     *
     * @since 2.1
     */
    public static class MethodParameter {
        
        private final Method method;
        private final int index;
        
        /**
         * Constructs a new MethodParameter.
         *
         * @since 2.1
         */
        public MethodParameter (Method method, int index) {
            this.method = method;
            this.index = index;
        }
        
        /**
         * Get the method this parameter is defined in.
         *
         * @since 2.1
         */
        public Method getMethod () {
            return method;
        }
        
        /**
         * Get the index of this parameter in the parameter list of the method.
         *
         * @since 2.1
         */
        public int getIndex () {
            return index;
        }
        
        /**
         * Compares two <code>MethodParameters for equality.
         * They must point to the same method and have the same index.
         *
         * @since 2.1
         */
        public boolean equals (Object o) {
            return o != null && o instanceof MethodParameter &&
                method.equals (((MethodParameter) o).method) &&
                index == ((MethodParameter) o).index;
        }
        
        /**
         * Computes the hashCode.
         *
         * @since 2.1
         */        
        public int hashCode () {
            return method.hashCode () + index;
        }
        
        /**
         * Converts this method parameter into a human-readable string.
         *
         * @since 2.1
         */
        public String toString () {
            return method.toString () + ":" + index;
        }
    }
    
    /**
     * A constructor parameter. A method parameter
     * is defined by the Method object it is defined in, and the index
     * of the parameter in the method's parameter list.
     *
     * @since 2.1
     */
    public static class ConstructorParameter {
        
        private final Constructor ctor;
        private final int index;
        
        
        /**
         * Constructs a new ConstructorParameter.
         *
         * @since 2.1
         */
        public ConstructorParameter (Constructor ctor, int index) {
            this.ctor = ctor;
            this.index = index;
        }
        
        /**
         * Get the constructor this parameter is defined in.
         *
         * @since 2.1
         */
        public Constructor getConstructor () {
            return ctor;
        }
        
        /**
         * Get the index of this parameter in the parameter list of the constructor.
         *
         * @since 2.1
         */
        public int getIndex () {
            return index;
        }
        
        /**
         * Compares two <code>ConstructorParameters for equality.
         * They must point to the same constructor and have the same index.
         *
         * @since 2.1
         */
        public boolean equals (Object o) {
            return o != null && o instanceof ConstructorParameter &&
                ctor.equals (((ConstructorParameter) o).ctor) &&
                index == ((ConstructorParameter) o).index;
        }
        
        /**
         * Computes the hashCode.
         *
         * @since 2.1
         */    
        public int hashCode () {
            return ctor.hashCode () + index;
        }
        
        /**
         * Converts this constructor parameter into a human-readable string.
         *
         * @since 2.1
         */
        public String toString () {
            return ctor.toString () + ":" + index;
        }
    }
    
    private static class IndexNode {
        public Collection classes = new HashSet ();
        public Collection fields = new HashSet ();
        public Collection methods = new HashSet ();
        public Collection constructors = new HashSet ();
        public Collection returnValues = new HashSet ();
        public Collection constructorParameters = new HashSet ();
        public Collection methodParameters = new HashSet ();
        
        public void seal () {
            classes = seal (classes);
            fields = seal (fields);
            methods = seal (methods);
            constructors = seal (constructors);
            returnValues = seal (returnValues);
            constructorParameters = seal (constructorParameters);
            methodParameters = seal (methodParameters);
        }
        
        private Collection seal (Collection coll) {
            return Collections.unmodifiableCollection (coll);
        }
    }
    
    private final HashMap index = new HashMap ();
    private final ClassLoader classLoader;
    
    /**
     * Creates a new AttributeIndex for the given ClassLoader.
     *
     * @since 2.1
     */
    public AttributeIndex (ClassLoader cl) throws Exception {
        this.classLoader = cl;
        Enumeration e = cl.getResources ("META-INF/attrs.index");
        while (e.hasMoreElements ()) {
            URL url = (URL) e.nextElement ();
            loadFromURL (url);
        }
        
        Iterator iter = index.values ().iterator ();
        while (iter.hasNext ()) {
            ((IndexNode) iter.next ()).seal ();
        }
    }
    
    private IndexNode getNode (Class attributeClass) {
        IndexNode node = (IndexNode) index.get (attributeClass.getName ());
        if (node == null) {
            node = new IndexNode ();
            index.put (attributeClass.getName (), node);
        }
        
        return node;
    }
    
    private void addIndex (Collection attributes, Class clazz) {
        Iterator iter = attributes.iterator ();
        while (iter.hasNext ()) {
            getNode (iter.next ().getClass ()).classes.add (clazz);
        }
    }
    
    private void addIndex (Collection attributes, Field field) {
        Iterator iter = attributes.iterator ();
        while (iter.hasNext ()) {
            getNode (iter.next ().getClass ()).fields.add (field);
        }
    }
    
    private void addIndex (Collection attributes, Method method) {
        Iterator iter = attributes.iterator ();
        while (iter.hasNext ()) {
            getNode (iter.next ().getClass ()).methods.add (method);
        }
    }
    
    private void addIndex (Collection attributes, Constructor constructor) {
        Iterator iter = attributes.iterator ();
        while (iter.hasNext ()) {
            getNode (iter.next ().getClass ()).constructors.add (constructor);
        }
    }
    
    private void addReturnIndex (Collection attributes, Method method) {
        Iterator iter = attributes.iterator ();
        while (iter.hasNext ()) {
            getNode (iter.next ().getClass ()).returnValues.add (method);
        }
    }
    
    private void addIndex (Collection attributes, Method method, int parameter) {
        Iterator iter = attributes.iterator ();
        while (iter.hasNext ()) {
            getNode (iter.next ().getClass ()).methodParameters.add (new MethodParameter (method, parameter));
        }
    }
    
    private void addIndex (Collection attributes, Constructor ctor, int parameter) {
        Iterator iter = attributes.iterator ();
        while (iter.hasNext ()) {
            getNode (iter.next ().getClass ()).constructorParameters.add (new ConstructorParameter (ctor, parameter));
        }
    }
    
    /**
     * Add a class to the index.
     */
    private void addClass (String clazzName) throws Exception {
        Class clazz = classLoader.loadClass (clazzName);
        
        // Get the attributes attached to the class itself...
        Collection coll = Attributes.getAttributes (clazz);
        
        coll = AttributeUtil.getObjectsWithAttributeType (coll, Indexed.class);
        addIndex (coll, clazz);
        
        Field[] fields = clazz.getDeclaredFields ();
        for (int i = 0; i < fields.length; i++) {
            coll = Attributes.getAttributes (fields[i]);
            
            coll = AttributeUtil.getObjectsWithAttributeType (coll, Indexed.class);
            addIndex (coll, fields[i]);
        }
        
        Method[] methods = clazz.getDeclaredMethods ();
        for (int i = 0; i < methods.length; i++) {
            coll = Attributes.getAttributes (methods[i]);
            
            coll = AttributeUtil.getObjectsWithAttributeType (coll, Indexed.class);
            addIndex (coll, methods[i]);
            
            // Return values
            coll = Attributes.getReturnAttributes (methods[i]);
            
            coll = AttributeUtil.getObjectsWithAttributeType (coll, Indexed.class);
            addReturnIndex (coll, methods[i]);
            
            // Parameters
            int numParameters = methods[i].getParameterTypes().length; 
            for (int j = 0; j < numParameters; j++) {
                coll = Attributes.getParameterAttributes (methods[i], j);
                
                coll = AttributeUtil.getObjectsWithAttributeType (coll, Indexed.class);
                addIndex (coll, methods[i], j);
            }
        }
        
        Constructor[] ctors = clazz.getDeclaredConstructors ();
        for (int i = 0; i < ctors.length; i++) {
            coll = Attributes.getAttributes (ctors[i]);
            
            coll = AttributeUtil.getObjectsWithAttributeType (coll, Indexed.class);
            addIndex (coll, ctors[i]);
            
            // Parameters
            int numParameters = ctors[i].getParameterTypes().length; 
            for (int j = 0; j < numParameters; j++) {
                coll = Attributes.getParameterAttributes (ctors[i], j);
                
                coll = AttributeUtil.getObjectsWithAttributeType (coll, Indexed.class);
                addIndex (coll, ctors[i], j);
            }
        }
    }
    
    /**
     * Load the attrs.index from a given URL.
     *
     * @since 2.1
     */
    private void loadFromURL (URL url) throws Exception {
        URLConnection connection = url.openConnection ();
        BufferedReader br = new BufferedReader (new InputStreamReader (connection.getInputStream ()));
        try {
            String currentAttributeClass = null;
            String line = null;
            while ((line = br.readLine ()) != null) {
                if (line.startsWith ("Class: ")) {
                    String className = line.substring ("Class: ".length ()).trim ();
                    addClass (className);
                }
            }
        } finally {
            br.close ();
        }
    }
    
    /**
     * Gets a Collection of the classes that have an attribute of the specified class.
     * The Collection contains the class names (String).
     * 
     * @deprecated Use the getClasses(Class) method instead.
     *
     * @since 2.1
     */    
    public Collection getClassesWithAttribute (String attributeClass) {
        if (index.containsKey (attributeClass)) {
            Collection classes = ((IndexNode) index.get (attributeClass)).classes;
            Iterator iter = classes.iterator ();
            Collection converted = new ArrayList (classes.size ());
            while (iter.hasNext ()) {
                converted.add (((Class) iter.next ()).getName ().replace ('$', '.'));
            }
            return converted;
        } else {
            return Collections.EMPTY_SET;
        }
    }
    
    /**
     * Gets a Collection of the classes that have an attribute of the specified class.
     * The Collection contains the class names (String).
     *
     * @deprecated Use the getClasses(Class) method instead.
     */
    public Collection getClassesWithAttribute (Class attributeClass) {
        return getClassesWithAttribute (attributeClass.getName ());
    }
    
    /**
     * Gets a Collection of the <code>Classes that have an attribute of the specified class.
     * The Collection contains the classes (Class).
     *
     * @since 2.1
     */    
    public Collection getClasses (Class attributeClass) {
        if (index.containsKey (attributeClass.getName ())) {
            return ((IndexNode) index.get (attributeClass.getName ())).classes;
        } else {
            return Collections.EMPTY_SET;
        }
    }
    
    /**
     * Gets a Collection of the <code>Methods that have an attribute of the specified class.
     * The Collection contains the methods (java.lang.reflect.Method).
     *
     * @since 2.1
     */    
    public Collection getMethods (Class attributeClass) {
        if (index.containsKey (attributeClass.getName ())) {
            return ((IndexNode) index.get (attributeClass.getName ())).methods;
        } else {
            return Collections.EMPTY_SET;
        }
    }
    
    /**
     * Gets a Collection of the <code>Methods whose return value has an attribute of the specified class.
     * The Collection contains the methods (java.lang.reflect.Method).
     *
     * @since 2.1
     */    
    public Collection getMethodsReturning (Class attributeClass) {
        if (index.containsKey (attributeClass.getName ())) {
            return ((IndexNode) index.get (attributeClass.getName ())).returnValues;
        } else {
            return Collections.EMPTY_SET;
        }
    }
    
    /**
     * Gets a Collection of the <code>Fields that have an attribute of the specified class.
     * The Collection contains the methods (java.lang.reflect.Field).
     *
     * @since 2.1
     */    
    public Collection getFields (Class attributeClass) {
        if (index.containsKey (attributeClass.getName ())) {
            return ((IndexNode) index.get (attributeClass.getName ())).fields;
        } else {
            return Collections.EMPTY_SET;
        }
    }
    
    /**
     * Gets a Collection of the <code>Constructors that have an attribute of the specified class.
     * The Collection contains the methods (java.lang.reflect.Constructor).
     *
     * @since 2.1
     */    
    public Collection getConstructors (Class attributeClass) {
        if (index.containsKey (attributeClass.getName ())) {
            return ((IndexNode) index.get (attributeClass.getName ())).constructors;
        } else {
            return Collections.EMPTY_SET;
        }
    }
    
    /**
     * Gets a Collection of the <code>ConstructorParameters that have an attribute of the specified class.
     * The Collection contains the methods ({@link AttributeIndex.ConstructorParameter}).
     *
     * @since 2.1
     */    
    public Collection getConstructorParameters (Class attributeClass) {
        if (index.containsKey (attributeClass.getName ())) {
            return ((IndexNode) index.get (attributeClass.getName ())).constructorParameters;
        } else {
            return Collections.EMPTY_SET;
        }
    }
    
    /**
     * Gets a Collection of the <code>MethodParameters that have an attribute of the specified class.
     * The Collection contains the methods ({@link AttributeIndex.MethodParameter}).
     *
     * @since 2.1
     */    
    public Collection getMethodParameters (Class attributeClass) {
        if (index.containsKey (attributeClass.getName ())) {
            return ((IndexNode) index.get (attributeClass.getName ())).methodParameters;
        } else {
            return Collections.EMPTY_SET;
        }
    }
}

Other Commons Attributes examples (source code examples)

Here is a short list of links related to this Commons Attributes AttributeIndex.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.