001    /*
002     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003     *
004     * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
005     *
006     * The contents of this file are subject to the terms of either the GNU
007     * General Public License Version 2 only ("GPL") or the Common Development
008     * and Distribution License("CDDL") (collectively, the "License").  You
009     * may not use this file except in compliance with the License.  You can
010     * obtain a copy of the License at
011     * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
012     * or packager/legal/LICENSE.txt.  See the License for the specific
013     * language governing permissions and limitations under the License.
014     *
015     * When distributing the software, include this License Header Notice in each
016     * file and include the License file at packager/legal/LICENSE.txt.
017     *
018     * GPL Classpath Exception:
019     * Oracle designates this particular file as subject to the "Classpath"
020     * exception as provided by Oracle in the GPL Version 2 section of the License
021     * file that accompanied this code.
022     *
023     * Modifications:
024     * If applicable, add the following below the License Header, with the fields
025     * enclosed by brackets [] replaced by your own identifying information:
026     * "Portions Copyright [year] [name of copyright owner]"
027     *
028     * Contributor(s):
029     * If you wish your version of this file to be governed by only the CDDL or
030     * only the GPL Version 2, indicate your decision by adding "[Contributor]
031     * elects to include this software in this distribution under the [CDDL or GPL
032     * Version 2] license."  If you don't indicate a single choice of license, a
033     * recipient has the option to distribute your version of this file under
034     * either the CDDL, the GPL Version 2 or to extend the choice of license to
035     * its licensees as provided above.  However, if you add GPL Version 2 code
036     * and therefore, elected the GPL Version 2 license, then the option applies
037     * only if the new code is made subject to such option by the copyright
038     * holder.
039     */
040    
041    package com.sun.enterprise.admin.cli.schemadoc;
042    
043    import java.util.ArrayList;
044    import java.util.List;
045    
046    import org.objectweb.asm.AnnotationVisitor;
047    import org.objectweb.asm.Attribute;
048    import org.objectweb.asm.ClassVisitor;
049    import org.objectweb.asm.FieldVisitor;
050    import org.objectweb.asm.MethodVisitor;
051    import org.objectweb.asm.Opcodes;
052    
053    public class DocClassVisitor implements ClassVisitor {
054        private boolean hasConfiguredAnnotation = false;
055        private String className;
056        private List<String> interfaces;
057        private ClassDef classDef;
058        private boolean showDeprecated;
059    
060        public DocClassVisitor(final boolean showDep) {
061            showDeprecated = showDep;
062        }
063    
064        public void visit(int version, int access, String name, String signature, String superName, String[] intfs) {
065            className = GenerateDomainSchema.toClassName(name);
066            interfaces = new ArrayList<String>();
067            for (String intf : intfs) {
068                interfaces.add(GenerateDomainSchema.toClassName(intf));
069            }
070            classDef = new ClassDef(className, interfaces);
071        }
072    
073        public List<String> getInterfaces() {
074            return interfaces;
075        }
076    
077        public void visitSource(String source, String debug) {
078        }
079    
080        public void visitOuterClass(String owner, String name, String desc) {
081        }
082    
083        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
084            hasConfiguredAnnotation |= "Lorg/jvnet/hk2/config/Configured;".equals(desc);
085            if ("Ljava/lang/Deprecated;".equals(desc)) {
086                classDef.setDeprecated(true);
087            }
088            return null;
089        }
090    
091        public void visitAttribute(Attribute attr) {
092        }
093    
094        public void visitInnerClass(String name, String outerName, String innerName, int access) {
095        }
096    
097        public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
098            return null;
099        }
100    
101        public MethodVisitor visitMethod(int access, String name, String desc, String signature,
102            String[] exceptions) {
103            String type = null;
104            try {
105                if (showDeprecated || ((access & Opcodes.ACC_DEPRECATED) != Opcodes.ACC_DEPRECATED)) {
106                    if (hasConfiguredAnnotation) {
107                        if (signature != null) {
108                            type = GenerateDomainSchema.toClassName(
109                                signature.substring(signature.indexOf("<") + 1, signature.lastIndexOf(">") - 1));
110                        } else {
111                            type = GenerateDomainSchema.toClassName(desc);
112                        }
113                    }
114                }
115            } catch (StringIndexOutOfBoundsException e) {
116                throw new RuntimeException(e.getMessage());
117            }
118            return name.startsWith("get") && type != null ? new AttributeMethodVisitor(classDef, name, type)
119                : null;
120        }
121    
122        /**
123         * Visits the end of the class. This method, which is the last one to be called, is used to inform the visitor that
124         * all the fields and methods of the class have been visited.
125         */
126        public void visitEnd() {
127        }
128    
129        public boolean isConfigured() {
130            return hasConfiguredAnnotation;
131        }
132    
133        public ClassDef getClassDef() {
134            return hasConfiguredAnnotation ? classDef : null;
135        }
136    
137        @Override
138        public String toString() {
139            return "DocClassVisitor{" +
140                "className='" + className + '\'' +
141                ", hasConfiguredAnnotation=" + hasConfiguredAnnotation +
142                '}';
143        }
144    }