View Javadoc

1   /*******************************************************************************
2    *  Copyright (c) 2005, 2006, 2007 Imola Informatica.
3    *  All rights reserved. This program and the accompanying materials
4    *  are made available under the terms of the LGPL License v2.1
5    *  which accompanies this distribution, and is available at
6    *  http://www.gnu.org/licenses/lgpl.html
7    *******************************************************************************/
8   package it.imolinfo.jbi4ejb.webservice.generator.bcm;
9   
10  
11  import it.imolinfo.jbi4ejb.Logger;
12  import it.imolinfo.jbi4ejb.LoggerFactory;
13  import it.imolinfo.jbi4ejb.webservice.generator.ClassMetaInfo;
14  
15  import java.util.HashSet;
16  import java.util.Set;
17  
18  import org.objectweb.asm.ClassAdapter;
19  import org.objectweb.asm.ClassVisitor;
20  import org.objectweb.asm.FieldVisitor;
21  import org.objectweb.asm.Type;
22  
23  /**
24   * Finds if a class implements the Serializable and gets the interface serial
25   * version UIDs, putting all the informtaion a <code>ClassMetaInfo</code> instance.
26   */
27  public class SerializableInspectorAdapter extends ClassAdapter {
28  
29      /**
30       * The internal name of the java interface 'Serializable'.
31       */
32      public static final String INTERNAL_NAME_OF_SERIALIZABLE
33      = "java/io/Serializable";   
34  
35      /**
36       * The 'serialVersionUID' field.
37       */
38      public static final String FIELDNAME_SERIAL_VERSION_UID = "serialVersionUID";    
39  
40      /**
41       * Logger.
42       */
43      private static final Logger LOG
44      = LoggerFactory.getLogger(SerializableInspectorAdapter.class);
45  
46      /**
47       * The meta information of the class inspected.
48       */
49      private ClassMetaInfo classMetaInfo = new ClassMetaInfo();
50  
51      
52      /**
53       * Instantiates a new serializable inspector adapter.
54       * 
55       * @param cv The <code>ClassVisitor</code>
56       */
57      public SerializableInspectorAdapter(ClassVisitor cv) {
58          super(cv);
59      }
60  
61      
62      /**
63       * Tests if the class implements serializable.
64       * 
65       * @param version
66       *          The version
67       * @param access
68       *          The access modifier
69       * @param name
70       *          The class name
71       * @param signature
72       *          The signature
73       * @param superName
74       *          The superclass name
75       * @param interfaces
76       *          The interfaces implemented
77       */
78      public void visit(int version, int access, String name, String signature,
79              String superName, String [] interfaces) {
80  
81          LOG.debug("visit. version=" + version + "; access=" + access
82                  + "; name" + name + "; superName=" + superName);
83  
84          if (implementsSerializable(interfaces)) {
85              LOG.debug("The class " + name + " implements Serializable.");
86              classMetaInfo.setSerializable(true);
87  
88          } else {
89              LOG.debug("The class " + name + " does not implement Serializable.");
90              classMetaInfo.setSerializable(false);
91          }
92  
93          classMetaInfo.setClassName(name.replace('/', '.'));
94          classMetaInfo.setSuperClassName(superName.replace('/', '.'));
95  
96          Set<String> set = new HashSet<String>();
97          if (interfaces != null) {
98              for (String current : interfaces) {
99                  set.add(current.replace('/', '.'));
100             }
101         }
102         classMetaInfo.setInterfaces(set);
103 
104         super.visit(version, access, name, signature, superName, interfaces);
105     }
106 
107     /**
108      * If find the serialVersionUID field, gets the value.
109      * 
110      * @param access
111      *          The access modifier
112      * @param name
113      *          The field name
114      * @param desc
115      *          The field desc
116      * @param signature
117      *          The signature
118      * @param value
119      *          The field value     
120      * @return
121      *          The FieldVisitor
122      */
123     public FieldVisitor visitField(int access, String name, String desc,
124             String signature, Object value) {
125 
126         LOG.debug("visitField. access=" + access + "; name=" + name
127                 + "; desc=" + desc + "; signature=" + signature + "; value=" + value);
128 
129         if (hasSerialVersionUIDField(name, desc)) {
130             LOG.debug("The class " + name + " has a serial version UID:" + value);
131 
132             classMetaInfo.setClassSerialVersionUid((Long) value);
133         }
134 
135         return super.visitField(access, name, desc, signature, value);
136     }
137 
138 
139 
140     /**
141      * Checks if the field is a serial version UID field.
142      * 
143      * @param name
144      *          The field name
145      * @param desc
146      *          The field descriptor
147      * 
148      * @return true, if successful
149      */
150     protected boolean hasSerialVersionUIDField(String name, String desc) {
151         if (FIELDNAME_SERIAL_VERSION_UID.equals(name)
152                 && Type.LONG_TYPE.getDescriptor().equals(desc)) {
153 
154             LOG.debug(FIELDNAME_SERIAL_VERSION_UID + " found.");
155             return true;
156         }
157         // else
158         return false;
159     }
160 
161     /**
162      * Tests if Serializable is between the interfaces.
163      * 
164      * @param interfaces
165      *          The interfaaces to test
166      * 
167      * @return true, if successful
168      */
169     protected boolean implementsSerializable(String [] interfaces) {
170         if (interfaces == null || interfaces.length == 0) {
171             return false;
172         }
173         // else
174         for (String current : interfaces) {
175             if (INTERNAL_NAME_OF_SERIALIZABLE.equals(current)) {
176                 return true;
177             }
178         }
179         // else
180         return false;
181     }
182 
183     /**
184      * Gets the class meta info.
185      * 
186      * @return the class meta info
187      */
188     public ClassMetaInfo getClassMetaInfo() {
189         return classMetaInfo;
190     }
191 
192     /**
193      * Sets the class meta info.
194      * 
195      * @param classMetaInfo
196      *            the new class meta info
197      */
198     public void setClassMetaInfo(ClassMetaInfo classMetaInfo) {
199         this.classMetaInfo = classMetaInfo;
200     }
201 
202 }