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

Java example source code file (ClassUseMapper.java)

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

Learn more about this Java project at its project page.

Java - Java tags/keywords

classdoc, collection, fielddoc, hashmap, iterator, javadoc, list, map, packagedoc, parameterizedtype, programelementdoc, set, treeset, type, util

The ClassUseMapper.java Java example source code

/*
 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.tools.doclets.internal.toolkit.util;

import java.util.*;

import com.sun.javadoc.*;

/**
 * Map all class uses for a given class.
 *
 *  <p>This is NOT part of any supported API.
 *  If you write code that depends on this, you do so at your own risk.
 *  This code and its internal interfaces are subject to change or
 *  deletion without notice.</b>
 *
 * @since 1.2
 * @author Robert G. Field
 */
public class ClassUseMapper {

    private final ClassTree classtree;

    /**
     * Mapping of ClassDocs to set of PackageDoc used by that class.
     * Entries may be null.
     */
    public Map<String,Set classToPackage = new HashMap>();

    /**
     * Mapping of Annotations to set of PackageDoc that use the annotation.
     */
    public Map<String,List classToPackageAnnotations = new HashMap>();

    /**
     * Mapping of ClassDocs to set of ClassDoc used by that class.
     * Entries may be null.
     */
    public Map<String,Set classToClass = new HashMap>();

    /**
     * Mapping of ClassDocs to list of ClassDoc which are direct or
     * indirect subclasses of that class.
     * Entries may be null.
     */
    public Map<String,List classToSubclass = new HashMap>();

    /**
     * Mapping of ClassDocs to list of ClassDoc which are direct or
     * indirect subinterfaces of that interface.
     * Entries may be null.
     */
    public Map<String,List classToSubinterface = new HashMap>();

    /**
     * Mapping of ClassDocs to list of ClassDoc which implement
     * this interface.
     * Entries may be null.
     */
    public Map<String,List classToImplementingClass = new HashMap>();

    /**
     * Mapping of ClassDocs to list of FieldDoc declared as that class.
     * Entries may be null.
     */
    public Map<String,List classToField = new HashMap>();

    /**
     * Mapping of ClassDocs to list of MethodDoc returning that class.
     * Entries may be null.
     */
    public Map<String,List classToMethodReturn = new HashMap>();

    /**
     * Mapping of ClassDocs to list of MethodDoc having that class
     * as an arg.
     * Entries may be null.
     */
    public Map<String,List classToMethodArgs = new HashMap>();

    /**
     * Mapping of ClassDocs to list of MethodDoc which throws that class.
     * Entries may be null.
     */
    public Map<String,List classToMethodThrows = new HashMap>();

    /**
     * Mapping of ClassDocs to list of ConstructorDoc having that class
     * as an arg.
     * Entries may be null.
     */
    public Map<String,List classToConstructorArgs = new HashMap>();

    /**
     * Mapping of ClassDocs to list of ConstructorDoc which throws that class.
     * Entries may be null.
     */
    public Map<String,List classToConstructorThrows = new HashMap>();

    /**
     * The mapping of AnnotationTypeDocs to constructors that use them.
     */
    public Map<String,List classToConstructorAnnotations = new HashMap>();

    /**
     * The mapping of AnnotationTypeDocs to Constructor parameters that use them.
     */
    public Map<String,List classToConstructorParamAnnotation = new HashMap>();

    /**
     * The mapping of ClassDocs to Constructor arguments that use them as type parameters.
     */
    public Map<String,List classToConstructorDocArgTypeParam = new HashMap>();

    /**
     * The mapping of ClassDocs to ClassDocs that use them as type parameters.
     */
    public Map<String,List classToClassTypeParam = new HashMap>();

    /**
     * The mapping of AnnotationTypeDocs to ClassDocs that use them.
     */
    public Map<String,List classToClassAnnotations = new HashMap>();

    /**
     * The mapping of ClassDocs to ExecutableMemberDocs that use them as type parameters.
     */
    public Map<String,List classToExecMemberDocTypeParam = new HashMap>();

    /**
     * The mapping of ClassDocs to ExecutableMemberDocs arguments that use them as type parameters.
     */
    public Map<String,List classToExecMemberDocArgTypeParam = new HashMap>();

    /**
     * The mapping of AnnotationTypeDocs to ExecutableMemberDocs that use them.
     */
    public Map<String,List classToExecMemberDocAnnotations = new HashMap>();

    /**
     * The mapping of ClassDocs to ExecutableMemberDocs that have return type
     * with type parameters of that class.
     */
    public Map<String,List classToExecMemberDocReturnTypeParam = new HashMap>();

    /**
     * The mapping of AnnotationTypeDocs to MethodDoc parameters that use them.
     */
    public Map<String,List classToExecMemberDocParamAnnotation = new HashMap>();

    /**
     * The mapping of ClassDocs to FieldDocs that use them as type parameters.
     */
    public Map<String,List classToFieldDocTypeParam = new HashMap>();

    /**
     * The mapping of AnnotationTypeDocs to FieldDocs that use them.
     */
    public Map<String,List annotationToFieldDoc = new HashMap>();


    public ClassUseMapper(RootDoc root, ClassTree classtree) {
        this.classtree = classtree;

        // Map subclassing, subinterfacing implementing, ...
        for (Iterator<ClassDoc> it = classtree.baseclasses().iterator(); it.hasNext();) {
            subclasses(it.next());
        }
        for (Iterator<ClassDoc> it = classtree.baseinterfaces().iterator(); it.hasNext();) {
            // does subinterfacing as side-effect
            implementingClasses(it.next());
        }
        // Map methods, fields, constructors using a class.
        ClassDoc[] classes = root.classes();
        for (int i = 0; i < classes.length; i++) {
            PackageDoc pkg = classes[i].containingPackage();
            mapAnnotations(classToPackageAnnotations, pkg, pkg);
            ClassDoc cd = classes[i];
            mapTypeParameters(classToClassTypeParam, cd, cd);
            mapAnnotations(classToClassAnnotations, cd, cd);
            FieldDoc[] fields = cd.fields();
            for (int j = 0; j < fields.length; j++) {
                FieldDoc fd = fields[j];
                mapTypeParameters(classToFieldDocTypeParam, fd, fd);
                mapAnnotations(annotationToFieldDoc, fd, fd);
                if (! fd.type().isPrimitive()) {
                    add(classToField, fd.type().asClassDoc(), fd);
                }
            }
            ConstructorDoc[] cons = cd.constructors();
            for (int j = 0; j < cons.length; j++) {
                mapAnnotations(classToConstructorAnnotations, cons[j], cons[j]);
                mapExecutable(cons[j]);
            }
            MethodDoc[] meths = cd.methods();
            for (int j = 0; j < meths.length; j++) {
                MethodDoc md = meths[j];
                mapExecutable(md);
                mapTypeParameters(classToExecMemberDocTypeParam, md, md);
                mapAnnotations(classToExecMemberDocAnnotations, md, md);
                if (! (md.returnType().isPrimitive() || md.returnType() instanceof TypeVariable)) {
                    mapTypeParameters(classToExecMemberDocReturnTypeParam,
                        md.returnType(), md);
                    add(classToMethodReturn, md.returnType().asClassDoc(), md);
                }
            }
        }
    }

    /**
     * Return all subclasses of a class AND fill-in classToSubclass map.
     */
    private Collection<ClassDoc> subclasses(ClassDoc cd) {
        Collection<ClassDoc> ret = classToSubclass.get(cd.qualifiedName());
        if (ret == null) {
            ret = new TreeSet<ClassDoc>();
            List<ClassDoc> subs = classtree.subclasses(cd);
            if (subs != null) {
                ret.addAll(subs);
                for (Iterator<ClassDoc> it = subs.iterator(); it.hasNext();) {
                    ret.addAll(subclasses(it.next()));
                }
            }
            addAll(classToSubclass, cd, ret);
        }
        return ret;
    }

    /**
     * Return all subinterfaces of an interface AND fill-in classToSubinterface map.
     */
    private Collection<ClassDoc> subinterfaces(ClassDoc cd) {
        Collection<ClassDoc> ret = classToSubinterface.get(cd.qualifiedName());
        if (ret == null) {
            ret = new TreeSet<ClassDoc>();
            List<ClassDoc> subs = classtree.subinterfaces(cd);
            if (subs != null) {
                ret.addAll(subs);
                for (Iterator<ClassDoc> it = subs.iterator(); it.hasNext();) {
                    ret.addAll(subinterfaces(it.next()));
                }
            }
            addAll(classToSubinterface, cd, ret);
        }
        return ret;
    }

    /**
     * Return all implementing classes of an interface (including
     * all subclasses of implementing classes and all classes
     * implementing subinterfaces) AND fill-in both classToImplementingClass
     * and classToSubinterface maps.
     */
    private Collection<ClassDoc> implementingClasses(ClassDoc cd) {
        Collection<ClassDoc> ret = classToImplementingClass.get(cd.qualifiedName());
        if (ret == null) {
            ret = new TreeSet<ClassDoc>();
            List<ClassDoc> impl = classtree.implementingclasses(cd);
            if (impl != null) {
                ret.addAll(impl);
                for (Iterator<ClassDoc> it = impl.iterator(); it.hasNext();) {
                    ret.addAll(subclasses(it.next()));
                }
            }
            for (Iterator<ClassDoc> it = subinterfaces(cd).iterator(); it.hasNext();) {
                ret.addAll(implementingClasses(it.next()));
            }
            addAll(classToImplementingClass, cd, ret);
        }
        return ret;
    }

    /**
     * Determine classes used by a method or constructor, so they can be
     * inverse mapped.
     */
    private void mapExecutable(ExecutableMemberDoc em) {
        Parameter[] params = em.parameters();
        boolean isConstructor = em.isConstructor();
        List<Type> classArgs = new ArrayList();
        for (int k = 0; k < params.length; k++) {
            Type pcd = params[k].type();
            // primitives don't get mapped, also avoid dups
            if ((! params[k].type().isPrimitive()) &&
                 ! classArgs.contains(pcd) &&
                 ! (pcd instanceof TypeVariable)) {
                add(isConstructor? classToConstructorArgs :classToMethodArgs,
                        pcd.asClassDoc(), em);
                classArgs.add(pcd);
                mapTypeParameters(isConstructor?
                   classToConstructorDocArgTypeParam : classToExecMemberDocArgTypeParam,
                   pcd, em);
            }
            mapAnnotations(
                isConstructor ?
                    classToConstructorParamAnnotation :
                    classToExecMemberDocParamAnnotation,
                params[k], em);
        }
        ClassDoc[] thr = em.thrownExceptions();
        for (int k = 0; k < thr.length; k++) {
            add(isConstructor? classToConstructorThrows : classToMethodThrows,
                    thr[k], em);
        }
    }

    private <T> List refList(Map> map, ClassDoc cd) {
        List<T> list = map.get(cd.qualifiedName());
        if (list == null) {
            List<T> l = new ArrayList();
            list = l;
            map.put(cd.qualifiedName(), list);
        }
        return list;
    }

    private Set<PackageDoc> packageSet(ClassDoc cd) {
        Set<PackageDoc> pkgSet = classToPackage.get(cd.qualifiedName());
        if (pkgSet == null) {
            pkgSet = new TreeSet<PackageDoc>();
            classToPackage.put(cd.qualifiedName(), pkgSet);
        }
        return pkgSet;
    }

    private Set<ClassDoc> classSet(ClassDoc cd) {
        Set<ClassDoc> clsSet = classToClass.get(cd.qualifiedName());
        if (clsSet == null) {
            Set<ClassDoc> s = new TreeSet();
            clsSet = s;
            classToClass.put(cd.qualifiedName(), clsSet);
        }
        return clsSet;
    }

    private <T extends ProgramElementDoc> void add(Map> map, ClassDoc cd, T ref) {
        // add to specified map
        refList(map, cd).add(ref);

        // add ref's package to package map and class map
        packageSet(cd).add(ref.containingPackage());

        classSet(cd).add(ref instanceof MemberDoc?
                ((MemberDoc)ref).containingClass() :
                    (ClassDoc)ref);
    }

    private void addAll(Map<String,List map, ClassDoc cd, Collection refs) {
        if (refs == null) {
            return;
        }
        // add to specified map
        refList(map, cd).addAll(refs);

        Set<PackageDoc> pkgSet = packageSet(cd);
        Set<ClassDoc> clsSet = classSet(cd);
        // add ref's package to package map and class map
        for (Iterator<ClassDoc> it = refs.iterator(); it.hasNext();) {
            ClassDoc cls = it.next();
            pkgSet.add(cls.containingPackage());
            clsSet.add(cls);

        }
    }

    /**
     * Map the ClassDocs to the ProgramElementDocs that use them as
     * type parameters.
     *
     * @param map the map the insert the information into.
     * @param doc the doc whose type parameters are being checked.
     * @param holder the holder that owns the type parameters.
     */
    private <T extends ProgramElementDoc> void mapTypeParameters(Map> map, Object doc,
            T holder) {
        TypeVariable[] typeVariables;
        if (doc instanceof ClassDoc) {
            typeVariables = ((ClassDoc) doc).typeParameters();
        } else if (doc instanceof WildcardType) {
            Type[] extendsBounds = ((WildcardType) doc).extendsBounds();
            for (int k = 0; k < extendsBounds.length; k++) {
                addTypeParameterToMap(map, extendsBounds[k], holder);
            }
            Type[] superBounds = ((WildcardType) doc).superBounds();
            for (int k = 0; k < superBounds.length; k++) {
                addTypeParameterToMap(map, superBounds[k], holder);
            }
            return;
        } else if (doc instanceof ParameterizedType) {
            Type[] typeArguments = ((ParameterizedType) doc).typeArguments();
            for (int k = 0; k < typeArguments.length; k++) {
                addTypeParameterToMap(map, typeArguments[k], holder);
            }
            return;
        } else if (doc instanceof ExecutableMemberDoc) {
            typeVariables = ((ExecutableMemberDoc) doc).typeParameters();
        } else if (doc instanceof FieldDoc) {
            Type fieldType = ((FieldDoc) doc).type();
            mapTypeParameters(map, fieldType, holder);
            return;
        } else {
            return;
        }
        for (int i = 0; i < typeVariables.length; i++) {
            Type[] bounds = typeVariables[i].bounds();
            for (int j = 0; j < bounds.length; j++) {
                addTypeParameterToMap(map, bounds[j], holder);
            }
        }
    }

    /**
     * Map the AnnotationType to the ProgramElementDocs that use them as
     * type parameters.
     *
     * @param map the map the insert the information into.
     * @param doc the doc whose type parameters are being checked.
     * @param holder the holder that owns the type parameters.
     */
    private <T extends ProgramElementDoc> void mapAnnotations(Map> map, Object doc,
            T holder) {
        AnnotationDesc[] annotations;
        boolean isPackage = false;
        if (doc instanceof ProgramElementDoc) {
            annotations = ((ProgramElementDoc) doc).annotations();
        } else if (doc instanceof PackageDoc) {
            annotations = ((PackageDoc) doc).annotations();
            isPackage = true;
        } else if (doc instanceof Parameter) {
            annotations = ((Parameter) doc).annotations();
        } else {
            throw new DocletAbortException("should not happen");
        }
        for (int i = 0; i < annotations.length; i++) {
            AnnotationTypeDoc annotationDoc = annotations[i].annotationType();
            if (isPackage)
                refList(map, annotationDoc).add(holder);
            else
                add(map, annotationDoc, holder);
        }
    }


    /**
     * Map the AnnotationType to the ProgramElementDocs that use them as
     * type parameters.
     *
     * @param map the map the insert the information into.
     * @param doc the doc whose type parameters are being checked.
     * @param holder the holder that owns the type parameters.
     */
    private <T extends PackageDoc> void mapAnnotations(Map> map, PackageDoc doc,
            T holder) {
        AnnotationDesc[] annotations;
        annotations = doc.annotations();
        for (int i = 0; i < annotations.length; i++) {
            AnnotationTypeDoc annotationDoc = annotations[i].annotationType();
            refList(map, annotationDoc).add(holder);
        }
    }

    private <T extends ProgramElementDoc> void addTypeParameterToMap(Map> map, Type type,
            T holder) {
        if (type instanceof ClassDoc) {
            add(map, (ClassDoc) type, holder);
        } else if (type instanceof ParameterizedType) {
            add(map, ((ParameterizedType) type).asClassDoc(), holder);
        }
        mapTypeParameters(map, type, holder);
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java ClassUseMapper.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.