001    package org.apache.maven.tools.plugin.annotations.scanner.visitors;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotatedClass;
023    import org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotationsScanner;
024    import org.codehaus.plexus.logging.Logger;
025    import org.codehaus.plexus.util.StringUtils;
026    import org.objectweb.asm.AnnotationVisitor;
027    import org.objectweb.asm.Attribute;
028    import org.objectweb.asm.ClassVisitor;
029    import org.objectweb.asm.FieldVisitor;
030    import org.objectweb.asm.MethodVisitor;
031    import org.objectweb.asm.Type;
032    
033    import java.util.ArrayList;
034    import java.util.HashMap;
035    import java.util.List;
036    import java.util.Map;
037    
038    /**
039     * @author Olivier Lamy
040     * @since 3.0
041     */
042    public class MojoClassVisitor
043        implements ClassVisitor
044    {
045        private Logger logger;
046    
047        private MojoAnnotatedClass mojoAnnotatedClass;
048    
049        private Map<String, MojoAnnotationVisitor> annotationVisitorMap = new HashMap<String, MojoAnnotationVisitor>();
050    
051        private List<MojoFieldVisitor> fieldVisitors = new ArrayList<MojoFieldVisitor>();
052    
053        public MojoClassVisitor( Logger logger )
054        {
055            this.logger = logger;
056        }
057    
058        public MojoAnnotatedClass getMojoAnnotatedClass()
059        {
060            return mojoAnnotatedClass;
061        }
062    
063        public void setMojoAnnotatedClass( MojoAnnotatedClass mojoAnnotatedClass )
064        {
065            this.mojoAnnotatedClass = mojoAnnotatedClass;
066        }
067    
068        public Map<String, MojoAnnotationVisitor> getAnnotationVisitorMap()
069        {
070            return annotationVisitorMap;
071        }
072    
073        public void setAnnotationVisitorMap( Map<String, MojoAnnotationVisitor> annotationVisitorMap )
074        {
075            this.annotationVisitorMap = annotationVisitorMap;
076        }
077    
078        public List<MojoFieldVisitor> getFieldVisitors()
079        {
080            return fieldVisitors;
081        }
082    
083        public void setFieldVisitors( List<MojoFieldVisitor> fieldVisitors )
084        {
085            this.fieldVisitors = fieldVisitors;
086        }
087    
088        public List<MojoFieldVisitor> findFieldWithAnnotationClass( String annotationClassName )
089        {
090            List<MojoFieldVisitor> mojoFieldVisitors = new ArrayList<MojoFieldVisitor>();
091    
092            for ( MojoFieldVisitor mojoFieldVisitor : this.fieldVisitors )
093            {
094                MojoAnnotationVisitor mojoAnnotationVisitor = mojoFieldVisitor.getMojoAnnotationVisitor();
095                if ( mojoAnnotationVisitor != null && StringUtils.equals( annotationClassName,
096                                                                          mojoAnnotationVisitor.getAnnotationClassName() ) )
097                {
098                    mojoFieldVisitors.add( mojoFieldVisitor );
099                }
100            }
101    
102            return mojoFieldVisitors;
103        }
104    
105        public void visit( int version, int access, String name, String signature, String superName, String[] interfaces )
106        {
107            mojoAnnotatedClass = new MojoAnnotatedClass();
108            mojoAnnotatedClass.setClassName( Type.getObjectType( name ).getClassName() ).setParentClassName(
109                Type.getObjectType( superName ).getClassName() );
110            logger.debug( "MojoClassVisitor#visit" );
111        }
112    
113        public AnnotationVisitor visitAnnotation( String desc, boolean visible )
114        {
115            logger.debug( "MojoClassVisitor#visitAnnotation" );
116            String annotationClassName = Type.getType( desc ).getClassName();
117            if ( !MojoAnnotationsScanner.CLASS_LEVEL_ANNOTATIONS.contains( annotationClassName ) )
118            {
119                return null;
120            }
121            MojoAnnotationVisitor mojoAnnotationVisitor = new MojoAnnotationVisitor( logger, annotationClassName );
122            annotationVisitorMap.put( annotationClassName, mojoAnnotationVisitor );
123            return mojoAnnotationVisitor;
124        }
125    
126        public FieldVisitor visitField( int access, String name, String desc, String signature, Object value )
127        {
128            logger.debug( "MojoClassVisitor#visitField" );
129            MojoFieldVisitor mojoFieldVisitor = new MojoFieldVisitor( logger, name, Type.getType( desc ).getClassName() );
130            fieldVisitors.add( mojoFieldVisitor );
131            return mojoFieldVisitor;
132        }
133    
134        public MethodVisitor visitMethod( int access, String name, String desc, String signature, String[] exceptions )
135        {
136            // we don't need methods informations
137            return null;
138        }
139    
140        public void visitAttribute( Attribute attr )
141        {
142            // no op
143        }
144    
145        public void visitSource( String source, String debug )
146        {
147            // no op
148        }
149    
150        public void visitOuterClass( String owner, String name, String desc )
151        {
152            // no op
153        }
154    
155        public void visitInnerClass( String name, String outerName, String innerName, int access )
156        {
157            // no op
158        }
159    
160        public void visitEnd()
161        {
162            // no op
163        }
164    
165    }