author | joehw |
Sun, 13 Aug 2017 21:10:40 -0700 | |
changeset 46174 | 5611d2529b49 |
parent 45853 | bfa06be36a17 |
permissions | -rw-r--r-- |
6 | 1 |
/* |
45853
bfa06be36a17
8181154: Fix lint warnings in JAXP repo: deprecation
joehw
parents:
44797
diff
changeset
|
2 |
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. |
6 | 3 |
*/ |
44797
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
4 |
/* |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
5 |
* Licensed to the Apache Software Foundation (ASF) under one or more |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
6 |
* contributor license agreements. See the NOTICE file distributed with |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
7 |
* this work for additional information regarding copyright ownership. |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
8 |
* The ASF licenses this file to You under the Apache License, Version 2.0 |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
9 |
* (the "License"); you may not use this file except in compliance with |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
10 |
* the License. You may obtain a copy of the License at |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
11 |
* |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
12 |
* http://www.apache.org/licenses/LICENSE-2.0 |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
13 |
* |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
14 |
* Unless required by applicable law or agreed to in writing, software |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
15 |
* distributed under the License is distributed on an "AS IS" BASIS, |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
16 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
17 |
* See the License for the specific language governing permissions and |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
18 |
* limitations under the License. |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
19 |
*/ |
6 | 20 |
package com.sun.org.apache.bcel.internal.generic; |
21 |
||
46174 | 22 |
import java.util.ArrayList; |
23 |
import java.util.List; |
|
6 | 24 |
|
46174 | 25 |
import com.sun.org.apache.bcel.internal.Const; |
26 |
import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry; |
|
27 |
import com.sun.org.apache.bcel.internal.classfile.Annotations; |
|
28 |
import com.sun.org.apache.bcel.internal.classfile.Attribute; |
|
29 |
import com.sun.org.apache.bcel.internal.classfile.Constant; |
|
30 |
import com.sun.org.apache.bcel.internal.classfile.ConstantObject; |
|
31 |
import com.sun.org.apache.bcel.internal.classfile.ConstantPool; |
|
32 |
import com.sun.org.apache.bcel.internal.classfile.ConstantValue; |
|
33 |
import com.sun.org.apache.bcel.internal.classfile.Field; |
|
34 |
import com.sun.org.apache.bcel.internal.classfile.Utility; |
|
35 |
import com.sun.org.apache.bcel.internal.util.BCELComparator; |
|
6 | 36 |
|
37 |
/** |
|
46174 | 38 |
* Template class for building up a field. The only extraordinary thing one can |
39 |
* do is to add a constant value attribute to a field (which must of course be |
|
40 |
* compatible with to the declared type). |
|
6 | 41 |
* |
46174 | 42 |
* @version $Id: FieldGen.java 1749603 2016-06-21 20:50:19Z ggregory $ |
6 | 43 |
* @see Field |
44 |
*/ |
|
45 |
public class FieldGen extends FieldGenOrMethodGen { |
|
46174 | 46 |
|
47 |
private Object value = null; |
|
48 |
private static BCELComparator bcelComparator = new BCELComparator() { |
|
6 | 49 |
|
46174 | 50 |
@Override |
51 |
public boolean equals(final Object o1, final Object o2) { |
|
52 |
final FieldGen THIS = (FieldGen) o1; |
|
53 |
final FieldGen THAT = (FieldGen) o2; |
|
54 |
return THIS.getName().equals(THAT.getName()) |
|
55 |
&& THIS.getSignature().equals(THAT.getSignature()); |
|
56 |
} |
|
6 | 57 |
|
46174 | 58 |
@Override |
59 |
public int hashCode(final Object o) { |
|
60 |
final FieldGen THIS = (FieldGen) o; |
|
61 |
return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); |
|
62 |
} |
|
63 |
}; |
|
6 | 64 |
|
46174 | 65 |
/** |
66 |
* Declare a field. If it is static (isStatic() == true) and has a basic |
|
67 |
* type like int or String it may have an initial value associated with it |
|
68 |
* as defined by setInitValue(). |
|
69 |
* |
|
70 |
* @param access_flags access qualifiers |
|
71 |
* @param type field type |
|
72 |
* @param name field name |
|
73 |
* @param cp constant pool |
|
74 |
*/ |
|
75 |
public FieldGen(final int access_flags, final Type type, final String name, final ConstantPoolGen cp) { |
|
76 |
super(access_flags); |
|
77 |
setType(type); |
|
78 |
setName(name); |
|
79 |
setConstantPool(cp); |
|
6 | 80 |
} |
81 |
||
46174 | 82 |
/** |
83 |
* Instantiate from existing field. |
|
84 |
* |
|
85 |
* @param field Field object |
|
86 |
* @param cp constant pool (must contain the same entries as the field's |
|
87 |
* constant pool) |
|
88 |
*/ |
|
89 |
public FieldGen(final Field field, final ConstantPoolGen cp) { |
|
90 |
this(field.getAccessFlags(), Type.getType(field.getSignature()), field.getName(), cp); |
|
91 |
final Attribute[] attrs = field.getAttributes(); |
|
92 |
for (final Attribute attr : attrs) { |
|
93 |
if (attr instanceof ConstantValue) { |
|
94 |
setValue(((ConstantValue) attr).getConstantValueIndex()); |
|
95 |
} else if (attr instanceof Annotations) { |
|
96 |
final Annotations runtimeAnnotations = (Annotations) attr; |
|
97 |
final AnnotationEntry[] annotationEntries = runtimeAnnotations.getAnnotationEntries(); |
|
98 |
for (final AnnotationEntry element : annotationEntries) { |
|
99 |
addAnnotationEntry(new AnnotationEntryGen(element, cp, false)); |
|
100 |
} |
|
101 |
} else { |
|
102 |
addAttribute(attr); |
|
103 |
} |
|
104 |
} |
|
105 |
} |
|
6 | 106 |
|
46174 | 107 |
private void setValue(final int index) { |
108 |
final ConstantPool cp = super.getConstantPool().getConstantPool(); |
|
109 |
final Constant c = cp.getConstant(index); |
|
110 |
value = ((ConstantObject) c).getConstantValue(cp); |
|
111 |
} |
|
6 | 112 |
|
46174 | 113 |
/** |
114 |
* Set (optional) initial value of field, otherwise it will be set to |
|
115 |
* null/0/false by the JVM automatically. |
|
116 |
*/ |
|
117 |
public void setInitValue(final String str) { |
|
118 |
checkType(ObjectType.getInstance("java.lang.String")); |
|
119 |
if (str != null) { |
|
120 |
value = str; |
|
121 |
} |
|
122 |
} |
|
6 | 123 |
|
46174 | 124 |
public void setInitValue(final long l) { |
125 |
checkType(Type.LONG); |
|
126 |
if (l != 0L) { |
|
127 |
value = l; |
|
128 |
} |
|
129 |
} |
|
6 | 130 |
|
46174 | 131 |
public void setInitValue(final int i) { |
132 |
checkType(Type.INT); |
|
133 |
if (i != 0) { |
|
134 |
value = i; |
|
135 |
} |
|
136 |
} |
|
6 | 137 |
|
46174 | 138 |
public void setInitValue(final short s) { |
139 |
checkType(Type.SHORT); |
|
140 |
if (s != 0) { |
|
141 |
value = (int) s; |
|
142 |
} |
|
143 |
} |
|
6 | 144 |
|
46174 | 145 |
public void setInitValue(final char c) { |
146 |
checkType(Type.CHAR); |
|
147 |
if (c != 0) { |
|
148 |
value = (int) c; |
|
149 |
} |
|
150 |
} |
|
6 | 151 |
|
46174 | 152 |
public void setInitValue(final byte b) { |
153 |
checkType(Type.BYTE); |
|
154 |
if (b != 0) { |
|
155 |
value = (int) b; |
|
156 |
} |
|
157 |
} |
|
6 | 158 |
|
46174 | 159 |
public void setInitValue(final boolean b) { |
160 |
checkType(Type.BOOLEAN); |
|
161 |
if (b) { |
|
162 |
value = 1; |
|
163 |
} |
|
164 |
} |
|
6 | 165 |
|
46174 | 166 |
public void setInitValue(final float f) { |
167 |
checkType(Type.FLOAT); |
|
168 |
if (f != 0.0) { |
|
169 |
value = f; |
|
170 |
} |
|
171 |
} |
|
6 | 172 |
|
46174 | 173 |
public void setInitValue(final double d) { |
174 |
checkType(Type.DOUBLE); |
|
175 |
if (d != 0.0) { |
|
176 |
value = d; |
|
177 |
} |
|
178 |
} |
|
6 | 179 |
|
46174 | 180 |
/** |
181 |
* Remove any initial value. |
|
182 |
*/ |
|
183 |
public void cancelInitValue() { |
|
184 |
value = null; |
|
185 |
} |
|
6 | 186 |
|
46174 | 187 |
private void checkType(final Type atype) { |
188 |
final Type superType = super.getType(); |
|
189 |
if (superType == null) { |
|
190 |
throw new ClassGenException("You haven't defined the type of the field yet"); |
|
191 |
} |
|
192 |
if (!isFinal()) { |
|
193 |
throw new ClassGenException("Only final fields may have an initial value!"); |
|
194 |
} |
|
195 |
if (!superType.equals(atype)) { |
|
196 |
throw new ClassGenException("Types are not compatible: " + superType + " vs. " + atype); |
|
197 |
} |
|
6 | 198 |
} |
199 |
||
46174 | 200 |
/** |
201 |
* Get field object after having set up all necessary values. |
|
202 |
*/ |
|
203 |
public Field getField() { |
|
204 |
final String signature = getSignature(); |
|
205 |
final int name_index = super.getConstantPool().addUtf8(super.getName()); |
|
206 |
final int signature_index = super.getConstantPool().addUtf8(signature); |
|
207 |
if (value != null) { |
|
208 |
checkType(super.getType()); |
|
209 |
final int index = addConstant(); |
|
210 |
addAttribute(new ConstantValue(super.getConstantPool().addUtf8("ConstantValue"), 2, index, |
|
211 |
super.getConstantPool().getConstantPool())); // sic |
|
212 |
} |
|
213 |
addAnnotationsAsAttribute(super.getConstantPool()); |
|
214 |
return new Field(super.getAccessFlags(), name_index, signature_index, getAttributes(), |
|
215 |
super.getConstantPool().getConstantPool()); // sic |
|
216 |
} |
|
6 | 217 |
|
46174 | 218 |
private void addAnnotationsAsAttribute(final ConstantPoolGen cp) { |
219 |
final Attribute[] attrs = AnnotationEntryGen.getAnnotationAttributes(cp, super.getAnnotationEntries()); |
|
220 |
for (final Attribute attr : attrs) { |
|
221 |
addAttribute(attr); |
|
222 |
} |
|
223 |
} |
|
6 | 224 |
|
46174 | 225 |
private int addConstant() { |
226 |
switch (super.getType().getType()) { // sic |
|
227 |
case Const.T_INT: |
|
228 |
case Const.T_CHAR: |
|
229 |
case Const.T_BYTE: |
|
230 |
case Const.T_BOOLEAN: |
|
231 |
case Const.T_SHORT: |
|
232 |
return super.getConstantPool().addInteger(((Integer) value)); |
|
233 |
case Const.T_FLOAT: |
|
234 |
return super.getConstantPool().addFloat(((Float) value)); |
|
235 |
case Const.T_DOUBLE: |
|
236 |
return super.getConstantPool().addDouble(((Double) value)); |
|
237 |
case Const.T_LONG: |
|
238 |
return super.getConstantPool().addLong(((Long) value)); |
|
239 |
case Const.T_REFERENCE: |
|
240 |
return super.getConstantPool().addString((String) value); |
|
241 |
default: |
|
242 |
throw new RuntimeException("Oops: Unhandled : " + super.getType().getType()); // sic |
|
243 |
} |
|
6 | 244 |
} |
245 |
||
46174 | 246 |
@Override |
247 |
public String getSignature() { |
|
248 |
return super.getType().getSignature(); |
|
249 |
} |
|
250 |
||
251 |
private List<FieldObserver> observers; |
|
6 | 252 |
|
46174 | 253 |
/** |
254 |
* Add observer for this object. |
|
255 |
*/ |
|
256 |
public void addObserver(final FieldObserver o) { |
|
257 |
if (observers == null) { |
|
258 |
observers = new ArrayList<>(); |
|
259 |
} |
|
260 |
observers.add(o); |
|
261 |
} |
|
6 | 262 |
|
46174 | 263 |
/** |
264 |
* Remove observer for this object. |
|
265 |
*/ |
|
266 |
public void removeObserver(final FieldObserver o) { |
|
267 |
if (observers != null) { |
|
268 |
observers.remove(o); |
|
269 |
} |
|
270 |
} |
|
6 | 271 |
|
46174 | 272 |
/** |
273 |
* Call notify() method on all observers. This method is not called |
|
274 |
* automatically whenever the state has changed, but has to be called by the |
|
275 |
* user after he has finished editing the object. |
|
276 |
*/ |
|
277 |
public void update() { |
|
278 |
if (observers != null) { |
|
279 |
for (final FieldObserver observer : observers) { |
|
280 |
observer.notify(this); |
|
281 |
} |
|
282 |
} |
|
283 |
} |
|
284 |
||
285 |
public String getInitValue() { |
|
286 |
if (value != null) { |
|
287 |
return value.toString(); |
|
288 |
} |
|
289 |
return null; |
|
290 |
} |
|
6 | 291 |
|
46174 | 292 |
/** |
293 |
* Return string representation close to declaration format, `public static |
|
294 |
* final short MAX = 100', e.g.. |
|
295 |
* |
|
296 |
* @return String representation of field |
|
297 |
*/ |
|
298 |
@Override |
|
299 |
public final String toString() { |
|
300 |
String name; |
|
301 |
String signature; |
|
302 |
String access; // Short cuts to constant pool |
|
303 |
access = Utility.accessToString(super.getAccessFlags()); |
|
304 |
access = access.isEmpty() ? "" : (access + " "); |
|
305 |
signature = super.getType().toString(); |
|
306 |
name = getName(); |
|
307 |
final StringBuilder buf = new StringBuilder(32); // CHECKSTYLE IGNORE MagicNumber |
|
308 |
buf.append(access).append(signature).append(" ").append(name); |
|
309 |
final String value = getInitValue(); |
|
310 |
if (value != null) { |
|
311 |
buf.append(" = ").append(value); |
|
312 |
} |
|
313 |
return buf.toString(); |
|
314 |
} |
|
6 | 315 |
|
46174 | 316 |
/** |
317 |
* @return deep copy of this field |
|
318 |
*/ |
|
319 |
public FieldGen copy(final ConstantPoolGen cp) { |
|
320 |
final FieldGen fg = (FieldGen) clone(); |
|
321 |
fg.setConstantPool(cp); |
|
322 |
return fg; |
|
323 |
} |
|
6 | 324 |
|
46174 | 325 |
/** |
326 |
* @return Comparison strategy object |
|
327 |
*/ |
|
328 |
public static BCELComparator getComparator() { |
|
329 |
return bcelComparator; |
|
330 |
} |
|
331 |
||
332 |
/** |
|
333 |
* @param comparator Comparison strategy object |
|
334 |
*/ |
|
335 |
public static void setComparator(final BCELComparator comparator) { |
|
336 |
bcelComparator = comparator; |
|
337 |
} |
|
6 | 338 |
|
46174 | 339 |
/** |
340 |
* Return value as defined by given BCELComparator strategy. By default two |
|
341 |
* FieldGen objects are said to be equal when their names and signatures are |
|
342 |
* equal. |
|
343 |
* |
|
344 |
* @see java.lang.Object#equals(java.lang.Object) |
|
345 |
*/ |
|
346 |
@Override |
|
347 |
public boolean equals(final Object obj) { |
|
348 |
return bcelComparator.equals(this, obj); |
|
349 |
} |
|
6 | 350 |
|
46174 | 351 |
/** |
352 |
* Return value as defined by given BCELComparator strategy. By default |
|
353 |
* return the hashcode of the field's name XOR signature. |
|
354 |
* |
|
355 |
* @see java.lang.Object#hashCode() |
|
356 |
*/ |
|
357 |
@Override |
|
358 |
public int hashCode() { |
|
359 |
return bcelComparator.hashCode(this); |
|
360 |
} |
|
6 | 361 |
} |