KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > speedo > generation > enhancer > FieldModifier


1 /**
2  * Speedo: an implementation of JDO compliant personality on top of JORM generic
3  * I/O sub-system.
4  * Copyright (C) 2001-2004 France Telecom R&D
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  *
21  *
22  * Contact: speedo@objectweb.org
23  *
24  * Authors: S.Chassande-Barrioz.
25  *
26  */

27 package org.objectweb.speedo.generation.enhancer;
28
29 import org.objectweb.asm.ClassReader;
30 import org.objectweb.asm.ClassVisitor;
31 import org.objectweb.asm.ClassWriter;
32 import org.objectweb.asm.Constants;
33 import org.objectweb.asm.Attribute;
34 import org.objectweb.speedo.api.SpeedoException;
35 import org.objectweb.speedo.api.SpeedoProperties;
36 import org.objectweb.speedo.metadata.SpeedoClass;
37 import org.objectweb.speedo.metadata.SpeedoField;
38 import org.objectweb.speedo.metadata.SpeedoXMLDescriptor;
39 import org.objectweb.util.monolog.api.BasicLevel;
40 import org.objectweb.util.monolog.api.Logger;
41
42 import java.util.Collection JavaDoc;
43 import java.util.HashMap JavaDoc;
44 import java.util.Iterator JavaDoc;
45 import java.util.Map JavaDoc;
46
47 /**
48  * This class transforms the access of fields
49  * @author S.Chassande-Barrioz
50  */

51 public class FieldModifier extends EnhancerComponent {
52
53     public final static String JavaDoc LOGGER_NAME
54         = SpeedoProperties.LOGGER_NAME + ".generation.enhancer.fieldMdodifier";
55
56     boolean toProtected;
57
58     public FieldModifier(boolean toProtected) {
59         this.toProtected = toProtected;
60     }
61
62     public boolean init() throws SpeedoException {
63         logger = scp.loggerFactory.getLogger(LOGGER_NAME);
64         return !scp.getXmldescriptor().isEmpty();
65     }
66
67     public void process() throws SpeedoException {
68         if (scp.getXmldescriptor() == null || scp.getXmldescriptor().isEmpty())
69             throw new SpeedoEnhancerException("xmldescriptor not initialised");
70         Map JavaDoc fieldModifs = new HashMap JavaDoc();
71         Collection JavaDoc xmls = scp.getXmldescriptor().values();
72         for (Iterator JavaDoc itDesc = xmls.iterator(); itDesc.hasNext();) {
73             SpeedoXMLDescriptor desc = (SpeedoXMLDescriptor) itDesc.next();
74             for (Iterator JavaDoc itclass = desc.getSpeedoClasses().iterator(); itclass.hasNext();) {
75                 fieldModifs.clear();
76                 SpeedoClass jdoclass = (SpeedoClass) itclass.next();
77                 Iterator JavaDoc it = jdoclass.jdoField.values().iterator();
78                 while (it.hasNext()) {
79                     SpeedoField sf = (SpeedoField) it.next();
80                     if (sf.access == 0) {
81                         if (toProtected) {
82                             fieldModifs.put(sf.name,
83                                 new FieldModif(sf.name, 0, Constants.ACC_PROTECTED));
84                         } else {
85                             fieldModifs.put(sf.name,
86                                 new FieldModif(sf.name, Constants.ACC_PROTECTED, 0));
87                         }
88                     } else if ((sf.access & Constants.ACC_PRIVATE) != 0) {
89                         if (toProtected) {
90                             fieldModifs.put(sf.name, new FieldModif(sf.name,
91                                     Constants.ACC_PRIVATE, Constants.ACC_PROTECTED));
92                         } else {
93                             fieldModifs.put(sf.name, new FieldModif(sf.name,
94                                     Constants.ACC_PROTECTED, Constants.ACC_PRIVATE));
95                         }
96                     }
97                 }
98                 if (fieldModifs.isEmpty()) {
99                     continue;
100                 }
101                 ClassWriter cw = new ClassWriter(false);
102                 FieldAccessModifier fam = new FieldAccessModifier(
103                     cw, logger, fieldModifs);
104                 String JavaDoc name = jdoclass.getFQName();
105                 ClassReader cr = loadJavaClass(false, name, scp.output, false);
106                 cr.accept(fam, false);
107                 writeJavaClass(name, cw, scp.output);
108             }
109         }
110     }
111
112     class FieldAccessModifier extends LoggedClassAdapter {
113
114         private Map JavaDoc fieldModifs;
115
116         /**
117          * @param fieldModifs is a map:
118          * key=field name
119          * value=FieldModif instance
120          */

121         public FieldAccessModifier(ClassVisitor classVisitor,
122                                    Logger logger,
123                                    Map JavaDoc fieldModifs) {
124             super(classVisitor, logger);
125             this.fieldModifs = fieldModifs;
126         }
127
128         /**
129          * @param access
130          * @param name
131          * @param desc
132          * @param value
133          */

134         public void visitField(final int access,
135                                final String JavaDoc name,
136                                final String JavaDoc desc,
137                                final Object JavaDoc value,
138                                final Attribute attrs) {
139             FieldModif fm = (FieldModif) fieldModifs.get(name);
140             int ac;
141             if (fm != null && (((access & fm.oldAccess) != 0)
142                     || access == fm.oldAccess)) {
143                 logger.log(BasicLevel.DEBUG, "Field " + name
144                         + " old:" + access + " / new: " + fm.newAccess);
145                 ac = access - fm.oldAccess + fm.newAccess;
146             } else {
147                 ac = access;
148             }
149             super.visitField(ac, name, desc, value, attrs);
150         }
151     }
152
153     class FieldModif {
154         public String JavaDoc name;
155         public int oldAccess;
156         public int newAccess;
157
158         public FieldModif(String JavaDoc name, int oldAccess, int newAccess) {
159             this.name = name;
160             this.oldAccess = oldAccess;
161             this.newAccess = newAccess;
162         }
163
164         public boolean equals(Object JavaDoc obj) {
165             return (obj instanceof FieldModif)
166                     && name.equals(((FieldModif) obj).name)
167                     && oldAccess == ((FieldModif) obj).oldAccess
168                     && newAccess == ((FieldModif) obj).newAccess;
169         }
170
171         public int hashCode() {
172             return oldAccess;
173         }
174     }
175 }
176
177
Popular Tags