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  import it.imolinfo.jbi4ejb.Logger;
11  import it.imolinfo.jbi4ejb.LoggerFactory;
12  
13  import org.objectweb.asm.ClassVisitor;
14  import org.objectweb.asm.FieldVisitor;
15  import org.objectweb.asm.Opcodes;
16  import org.objectweb.asm.Type;
17  
18  /**
19   * This adapter makes a class Serializable and add a serial version UID.
20   */
21  public class SerializableDecorationAdapter
22    extends SerializableInspectorAdapter {
23  
24    /**
25     * Logger.
26     */
27    private static final Logger LOG
28      = LoggerFactory.getLogger(SerializableDecorationAdapter.class);
29  
30    /**
31     * The new serial version UID for the class inspected.
32     */
33    private Long newSerialVersionUid = 0L;
34  
35    /**
36     * SerializableDecorationAdapter Constructor.
37     *
38     * @param        cv                        The class visitor instance.
39     * @param        aNewSerialVersionUid      The serialVersionUID value to add.
40     */
41    public SerializableDecorationAdapter(ClassVisitor cv,
42                                         Long aNewSerialVersionUid) {
43      super(cv);
44      if (aNewSerialVersionUid != null) {
45          newSerialVersionUid = aNewSerialVersionUid;
46      } else {
47          newSerialVersionUid = Long.valueOf(0L);
48      }    
49    }
50     
51    /**
52       * Class visitro, adds the <code>java.io.Serializable</code> interface if not already present.
53       * 
54       * @param version
55       *          The class version
56       * @param access
57       *          The access modifier
58       * @param name
59       *          The class name
60       * @param signature
61       *          The signature
62       * @param superName
63       *          The superclass name
64       * @param interfaces
65       *          The interfaces implemented
66       */
67    public void visit(int version, int access, String name, String signature,
68      String superName, String [] interfaces) {
69  
70      String [] implementsArray = interfaces;
71  
72      if (! implementsSerializable(interfaces)) {
73        LOG.debug("The class " + name + " does not implement Serializable.");
74  
75        int implementsSize = 0;
76        if (interfaces != null) {
77            implementsSize = interfaces.length;
78        }
79  
80        implementsArray = new String[implementsSize + 1];
81  
82        if (implementsSize == 0 ) {
83  
84          implementsArray[0]
85            = SerializableInspectorAdapter.INTERNAL_NAME_OF_SERIALIZABLE;
86  
87        } else {
88  
89          System.arraycopy(interfaces, 0, implementsArray, 0, implementsSize);
90          implementsArray[implementsSize]
91            = SerializableInspectorAdapter.INTERNAL_NAME_OF_SERIALIZABLE;
92  
93        }
94  
95      }
96  
97      super.visit(version, access, name, signature, superName, implementsArray);
98    }
99  
100   
101   /**
102      * Field Visitor. Test if the field is a serialVersionUID field and adds the
103      * newSerialVersionUid.
104      * 
105      * @param access
106      *          The access modifier
107      * @param name
108      *          The field name
109      * @param desc
110      *          The field desc
111      * @param signature
112      *          The signature
113      * @param value
114      *          The field value
115      * 
116      * @return
117      *          The FieldVisitor
118      */
119   public FieldVisitor visitField(int access, String name, String desc,
120     String signature, Object value) {
121 
122     Object retValue = value; 
123     LOG.debug("visitField. access=" + access + "; name=" + name
124       + "; desc=" + desc + "; signature=" + signature + "; value=" + value);
125 
126     if (hasSerialVersionUIDField(name, desc)) {
127       LOG.debug("The class " + name + " has a serial version UID:" + value);
128 
129       retValue = newSerialVersionUid;
130     }
131 
132     return super.visitField(access, name, desc, signature, retValue);
133   }
134 
135 
136   /**
137    * Adds the 'private final static' access modifier to the serialVersionUID field. 
138    * @see org.objectweb.asm.ClassAdapter#visitEnd()
139    */
140   public void visitEnd() {
141     if (getClassMetaInfo().getClassSerialVersionUid() == null) {
142       super.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC,
143         SerializableInspectorAdapter.FIELDNAME_SERIAL_VERSION_UID,
144         Type.LONG_TYPE.getDescriptor(),
145         null,
146         newSerialVersionUid);
147 
148       getClassMetaInfo().setClassSerialVersionUid(newSerialVersionUid);
149     }
150   }
151 }