1 package serp.bytecode;
2
3 import java.io.*;
4 import java.net.*;
5 import java.util.*;
6
7 import serp.bytecode.lowlevel.*;
8 import serp.bytecode.visitor.*;
9 import serp.util.*;
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 public class BCClass extends Annotated implements VisitAcceptor {
32 private Project _project = null;
33 private State _state = null;
34 private ClassLoader _loader = null;
35
36
37
38
39 BCClass(Project project) {
40 _project = project;
41 }
42
43
44
45
46 void setState(State state) {
47 _state = state;
48 }
49
50
51
52
53 void invalidate() {
54 _project = null;
55 _state = State.INVALID;
56 }
57
58
59
60
61
62
63
64
65
66 void read(File classFile, ClassLoader loader) throws IOException {
67 InputStream in = new FileInputStream(classFile);
68 try {
69 read(in, loader);
70 } finally {
71 in.close();
72 }
73 }
74
75
76
77
78
79 void read(InputStream instream, ClassLoader loader)
80 throws IOException {
81 DataInput in = new DataInputStream(instream);
82
83
84 _state.setMagic(in.readInt());
85 _state.setMinorVersion(in.readUnsignedShort());
86 _state.setMajorVersion(in.readUnsignedShort());
87
88
89 _state.getPool().read(in);
90
91
92 _state.setAccessFlags(in.readUnsignedShort());
93
94
95 _state.setIndex(in.readUnsignedShort());
96 _state.setSuperclassIndex(in.readUnsignedShort());
97
98 Collection interfaces = _state.getInterfacesHolder();
99 interfaces.clear();
100 int interfaceCount = in.readUnsignedShort();
101 for (int i = 0; i < interfaceCount; i++)
102 interfaces.add(Numbers.valueOf(in.readUnsignedShort()));
103
104
105 Collection fields = _state.getFieldsHolder();
106 fields.clear();
107 int fieldCount = in.readUnsignedShort();
108 BCField field;
109 for (int i = 0; i < fieldCount; i++) {
110 field = new BCField(this);
111 fields.add(field);
112 field.read(in);
113 }
114
115
116 Collection methods = _state.getMethodsHolder();
117 methods.clear();
118 int methodCount = in.readUnsignedShort();
119 BCMethod method;
120 for (int i = 0; i < methodCount; i++) {
121 method = new BCMethod(this);
122 methods.add(method);
123 method.read(in);
124 }
125
126 readAttributes(in);
127 _loader = loader;
128 }
129
130
131
132
133
134 void read(Class type) throws IOException {
135
136 int dotIndex = type.getName().lastIndexOf('.') + 1;
137
138
139 String className = type.getName().substring(dotIndex);
140
141
142 InputStream in = type.getResourceAsStream(className + ".class");
143 try {
144 read(in, type.getClassLoader());
145 } finally {
146 in.close();
147 }
148 }
149
150
151
152
153
154 void read(BCClass orig) {
155 try {
156 ByteArrayInputStream in = new ByteArrayInputStream
157 (orig.toByteArray());
158 read(in, orig.getClassLoader());
159 in.close();
160 } catch (IOException ioe) {
161 throw new RuntimeException(ioe.toString());
162 }
163 }
164
165
166
167
168
169
170 public void write() throws IOException {
171 String name = getName();
172 int dotIndex = name.lastIndexOf('.') + 1;
173 name = name.substring(dotIndex);
174 Class type = getType();
175
176
177
178
179 OutputStream out = new FileOutputStream(URLDecoder.decode
180 (type.getResource(name + ".class").getFile()));
181 try {
182 write(out);
183 } finally {
184 out.close();
185 }
186 }
187
188
189
190
191 public void write(File classFile) throws IOException {
192 OutputStream out = new FileOutputStream(classFile);
193 try {
194 write(out);
195 } finally {
196 out.close();
197 }
198 }
199
200
201
202
203 public void write(OutputStream outstream) throws IOException {
204 DataOutput out = new DataOutputStream(outstream);
205
206
207 out.writeInt(_state.getMagic());
208 out.writeShort(_state.getMinorVersion());
209 out.writeShort(_state.getMajorVersion());
210
211
212 _state.getPool().write(out);
213
214
215 out.writeShort(_state.getAccessFlags());
216
217
218 out.writeShort(_state.getIndex());
219 out.writeShort(_state.getSuperclassIndex());
220
221
222 Collection interfaces = _state.getInterfacesHolder();
223 out.writeShort(interfaces.size());
224 for (Iterator itr = interfaces.iterator(); itr.hasNext();)
225 out.writeShort(((Number) itr.next()).intValue());
226
227
228 Collection fields = _state.getFieldsHolder();
229 out.writeShort(fields.size());
230 for (Iterator itr = fields.iterator(); itr.hasNext();)
231 ((BCField) itr.next()).write(out);
232
233
234 Collection methods = _state.getMethodsHolder();
235 out.writeShort(methods.size());
236 for (Iterator itr = methods.iterator(); itr.hasNext();)
237 ((BCMethod) itr.next()).write(out);
238
239
240 writeAttributes(out);
241 }
242
243
244
245
246
247 public byte[] toByteArray() {
248 ByteArrayOutputStream out = new ByteArrayOutputStream();
249 try {
250 write(out);
251 out.flush();
252 return out.toByteArray();
253 } catch (IOException ioe) {
254 throw new RuntimeException(ioe.toString());
255 } finally {
256 try { out.close(); } catch (IOException ioe) {}
257 }
258 }
259
260
261
262
263
264
265
266
267
268 public int getMagic() {
269 return _state.getMagic();
270 }
271
272
273
274
275
276 public void setMagic(int magic) {
277 _state.setMagic(magic);
278 }
279
280
281
282
283
284
285 public int getMajorVersion() {
286 return _state.getMajorVersion();
287 }
288
289
290
291
292
293
294 public void setMajorVersion(int majorVersion) {
295 _state.setMajorVersion(majorVersion);
296 }
297
298
299
300
301
302
303 public int getMinorVersion() {
304 return _state.getMinorVersion();
305 }
306
307
308
309
310
311
312 public void setMinorVersion(int minorVersion) {
313 _state.setMinorVersion(minorVersion);
314 }
315
316
317
318
319
320
321
322 public int getAccessFlags() {
323 return _state.getAccessFlags();
324 }
325
326
327
328
329
330
331
332 public void setAccessFlags(int access) {
333 _state.setAccessFlags(access);
334 }
335
336
337
338
339 public boolean isPublic() {
340 return (getAccessFlags() & Constants.ACCESS_PUBLIC) > 0;
341 }
342
343
344
345
346 public void makePublic() {
347 setAccessFlags(getAccessFlags() | Constants.ACCESS_PUBLIC);
348 }
349
350
351
352
353 public boolean isPackage() {
354 return !isPublic();
355 }
356
357
358
359
360 public void makePackage() {
361 setAccessFlags(getAccessFlags() & ~Constants.ACCESS_PUBLIC);
362 }
363
364
365
366
367 public boolean isFinal() {
368 return (getAccessFlags() & Constants.ACCESS_FINAL) > 0;
369 }
370
371
372
373
374 public void setFinal(boolean on) {
375 if (on)
376 setAccessFlags(getAccessFlags() | Constants.ACCESS_FINAL);
377 else
378 setAccessFlags(getAccessFlags() & ~Constants.ACCESS_FINAL);
379 }
380
381
382
383
384 public boolean isInterface() {
385 return (getAccessFlags() & Constants.ACCESS_INTERFACE) > 0;
386 }
387
388
389
390
391 public void setInterface(boolean on) {
392 if (on) {
393 setAccessFlags(getAccessFlags() | Constants.ACCESS_INTERFACE);
394 setAbstract(true);
395 } else
396 setAccessFlags(getAccessFlags() & ~Constants.ACCESS_INTERFACE);
397 }
398
399
400
401
402 public boolean isAbstract() {
403 return (getAccessFlags() & Constants.ACCESS_ABSTRACT) > 0;
404 }
405
406
407
408
409 public void setAbstract(boolean on) {
410 if (on)
411 setAccessFlags(getAccessFlags() | Constants.ACCESS_ABSTRACT);
412 else
413 setAccessFlags(getAccessFlags() & ~Constants.ACCESS_ABSTRACT);
414 }
415
416
417
418
419 public boolean isSynthetic() {
420 return (getAccessFlags() & Constants.ACCESS_SYNTHETIC) > 0;
421 }
422
423
424
425
426 public void setSynthetic(boolean on) {
427 if (on)
428 setAccessFlags(getAccessFlags() | Constants.ACCESS_SYNTHETIC);
429 else
430 setAccessFlags(getAccessFlags() & ~Constants.ACCESS_SYNTHETIC);
431 }
432
433
434
435
436 public boolean isAnnotation() {
437 return (getAccessFlags() & Constants.ACCESS_ANNOTATION) > 0;
438 }
439
440
441
442
443
444 public void setAnnotation(boolean on) {
445 if (on) {
446 setAccessFlags(getAccessFlags() | Constants.ACCESS_ANNOTATION);
447 setAccessFlags(getAccessFlags() | Constants.ACCESS_INTERFACE);
448 } else
449 setAccessFlags(getAccessFlags() & ~Constants.ACCESS_ANNOTATION);
450 }
451
452
453
454
455 public boolean isEnum() {
456 return (getAccessFlags() & Constants.ACCESS_ENUM) > 0;
457 }
458
459
460
461
462 public void setEnum(boolean on) {
463 if (on)
464 setAccessFlags(getAccessFlags() | Constants.ACCESS_ENUM);
465 else
466 setAccessFlags(getAccessFlags() & ~Constants.ACCESS_ENUM);
467 }
468
469
470
471
472 public boolean isPrimitive() {
473 return _state.isPrimitive();
474 }
475
476
477
478
479 public boolean isArray() {
480 return _state.isArray();
481 }
482
483
484
485
486
487
488
489
490
491
492 public int getIndex() {
493 return _state.getIndex();
494 }
495
496
497
498
499
500
501
502 public void setIndex(int index) {
503 String oldName = getName();
504 String newName = ((ClassEntry) getPool().getEntry(index)).
505 getNameEntry().getValue();
506 beforeRename(oldName, newName);
507 _state.setIndex(index);
508 }
509
510
511
512
513
514 public String getName() {
515 return _state.getName();
516 }
517
518
519
520
521 public String getClassName() {
522 String name = _project.getNameCache().getExternalForm(getName(), true);
523 return name.substring(name.lastIndexOf('.') + 1);
524 }
525
526
527
528
529 public String getPackageName() {
530 String name = _project.getNameCache().getExternalForm(getName(), true);
531 int index = name.lastIndexOf('.');
532 if (index == -1)
533 return null;
534 return name.substring(0, index);
535 }
536
537
538
539
540 public void setName(String name) {
541 name = _project.getNameCache().getExternalForm(name, false);
542 String oldName = getName();
543
544
545 int index = getIndex();
546 if (index == 0)
547 index = getPool().findClassEntry(name, true);
548 ClassEntry entry = (ClassEntry) getPool().getEntry(index);
549
550
551 beforeRename(oldName, name);
552
553
554 int nameIndex = getPool().findUTF8Entry(_project.getNameCache().
555 getInternalForm(name, false), true);
556 entry.setNameIndex(nameIndex);
557
558
559 _state.setIndex(index);
560 }
561
562
563
564
565 public Class getType() {
566 return Strings.toClass(getName(), getClassLoader());
567 }
568
569
570
571
572
573 public String getComponentName() {
574 return _state.getComponentName();
575 }
576
577
578
579
580 public Class getComponentType() {
581 String componentName = getComponentName();
582 if (componentName == null)
583 return null;
584 return Strings.toClass(componentName, getClassLoader());
585 }
586
587
588
589
590 public BCClass getComponentBC() {
591 String componentName = getComponentName();
592 if (componentName == null)
593 return null;
594 return getProject().loadClass(componentName, getClassLoader());
595 }
596
597
598
599
600
601
602
603
604
605
606 public int getSuperclassIndex() {
607 return _state.getSuperclassIndex();
608 }
609
610
611
612
613
614 public void setSuperclassIndex(int index) {
615 _state.setSuperclassIndex(index);
616 }
617
618
619
620
621
622
623 public String getSuperclassName() {
624 return _state.getSuperclassName();
625 }
626
627
628
629
630
631 public Class getSuperclassType() {
632 String name = getSuperclassName();
633 if (name == null)
634 return null;
635 return Strings.toClass(name, getClassLoader());
636 }
637
638
639
640
641
642 public BCClass getSuperclassBC() {
643 String name = getSuperclassName();
644 if (name == null)
645 return null;
646 return getProject().loadClass(name, getClassLoader());
647 }
648
649
650
651
652 public void setSuperclass(String name) {
653 if (name == null)
654 setSuperclassIndex(0);
655 else
656 setSuperclassIndex(getPool().findClassEntry(_project.getNameCache().
657 getInternalForm(name, false), true));
658 }
659
660
661
662
663 public void setSuperclass(Class type) {
664 if (type == null)
665 setSuperclass((String) null);
666 else
667 setSuperclass(type.getName());
668 }
669
670
671
672
673 public void setSuperclass(BCClass type) {
674 if (type == null)
675 setSuperclass((String) null);
676 else
677 setSuperclass(type.getName());
678 }
679
680
681
682
683
684
685
686
687
688
689
690
691 public int[] getDeclaredInterfaceIndexes() {
692 Collection interfaces = _state.getInterfacesHolder();
693 int[] indexes = new int[interfaces.size()];
694 Iterator itr = interfaces.iterator();
695 for (int i = 0, max = interfaces.size(); i < max; i++)
696 indexes[i] = ((Number) itr.next()).intValue();
697 return indexes;
698 }
699
700
701
702
703
704
705 public void setDeclaredInterfaceIndexes(int[] interfaceIndexes) {
706 Collection stateIndexes = _state.getInterfacesHolder();
707 stateIndexes.clear();
708 Integer idx;
709 for (int i = 0; i < interfaceIndexes.length; i++) {
710 idx = Numbers.valueOf(interfaceIndexes[i]);
711 if (!stateIndexes.contains(idx))
712 stateIndexes.add(idx);
713 }
714 }
715
716
717
718
719
720
721 public String[] getDeclaredInterfaceNames() {
722 int[] indexes = getDeclaredInterfaceIndexes();
723 String[] names = new String[indexes.length];
724 ClassEntry entry;
725 for (int i = 0; i < indexes.length; i++) {
726 entry = (ClassEntry) getPool().getEntry(indexes[i]);
727 names[i] = _project.getNameCache().getExternalForm
728 (entry.getNameEntry().getValue(), false);
729 }
730 return names;
731 }
732
733
734
735
736
737 public Class[] getDeclaredInterfaceTypes() {
738 String[] names = getDeclaredInterfaceNames();
739 Class[] types = new Class[names.length];
740 for (int i = 0; i < names.length; i++)
741 types[i] = Strings.toClass(names[i], getClassLoader());
742 return types;
743 }
744
745
746
747
748
749 public BCClass[] getDeclaredInterfaceBCs() {
750 String[] names = getDeclaredInterfaceNames();
751 BCClass[] types = new BCClass[names.length];
752 for (int i = 0; i < names.length; i++)
753 types[i] = getProject().loadClass(names[i], getClassLoader());
754 return types;
755 }
756
757
758
759
760
761 public void setDeclaredInterfaces(String[] interfaces) {
762 clearDeclaredInterfaces();
763 if (interfaces != null)
764 for (int i = 0; i < interfaces.length; i++)
765 declareInterface(interfaces[i]);
766 }
767
768
769
770
771
772 public void setDeclaredInterfaces(Class[] interfaces) {
773 String[] names = null;
774 if (interfaces != null) {
775 names = new String[interfaces.length];
776 for (int i = 0; i < interfaces.length; i++)
777 names[i] = interfaces[i].getName();
778 }
779 setDeclaredInterfaces(names);
780 }
781
782
783
784
785
786 public void setDeclaredInterfaces(BCClass[] interfaces) {
787 String[] names = null;
788 if (interfaces != null) {
789 names = new String[interfaces.length];
790 for (int i = 0; i < interfaces.length; i++)
791 names[i] = interfaces[i].getName();
792 }
793 setDeclaredInterfaces(names);
794 }
795
796
797
798
799
800
801
802 public String[] getInterfaceNames() {
803 Collection allNames = new LinkedList();
804 String[] names;
805 for (BCClass type = this; type != null; type = type.getSuperclassBC()) {
806 names = type.getDeclaredInterfaceNames();
807 for (int i = 0; i < names.length; i++)
808 allNames.add(names[i]);
809 }
810 return (String[]) allNames.toArray(new String[allNames.size()]);
811 }
812
813
814
815
816
817
818 public Class[] getInterfaceTypes() {
819 Collection allTypes = new LinkedList();
820 Class[] types;
821 for (BCClass type = this; type != null; type = type.getSuperclassBC()) {
822 types = type.getDeclaredInterfaceTypes();
823 for (int i = 0; i < types.length; i++)
824 allTypes.add(types[i]);
825 }
826 return (Class[]) allTypes.toArray(new Class[allTypes.size()]);
827 }
828
829
830
831
832
833
834 public BCClass[] getInterfaceBCs() {
835 Collection allTypes = new LinkedList();
836 BCClass[] types;
837 for (BCClass type = this; type != null; type = type.getSuperclassBC()) {
838 types = type.getDeclaredInterfaceBCs();
839 for (int i = 0; i < types.length; i++)
840 allTypes.add(types[i]);
841 }
842 return (BCClass[]) allTypes.toArray(new BCClass[allTypes.size()]);
843 }
844
845
846
847
848 public void clearDeclaredInterfaces() {
849 _state.getInterfacesHolder().clear();
850 }
851
852
853
854
855
856
857 public boolean removeDeclaredInterface(String name) {
858 String[] names = getDeclaredInterfaceNames();
859 Iterator itr = _state.getInterfacesHolder().iterator();
860 for (int i = 0; i < names.length; i++) {
861 itr.next();
862 if (names[i].equals(name)) {
863 itr.remove();
864 return true;
865 }
866 }
867 return false;
868 }
869
870
871
872
873
874
875 public boolean removeDeclaredInterface(Class type) {
876 if (type == null)
877 return false;
878 return removeDeclaredInterface(type.getName());
879 }
880
881
882
883
884
885
886 public boolean removeDeclaredInterface(BCClass type) {
887 if (type == null)
888 return false;
889 return removeDeclaredInterface(type.getName());
890 }
891
892
893
894
895 public void declareInterface(String name) {
896 Integer index = Numbers.valueOf(getPool().findClassEntry(_project.
897 getNameCache().getInternalForm(name, false), true));
898 Collection interfaces = _state.getInterfacesHolder();
899 if (!interfaces.contains(index))
900 interfaces.add(index);
901 }
902
903
904
905
906 public void declareInterface(Class type) {
907 declareInterface(type.getName());
908 }
909
910
911
912
913 public void declareInterface(BCClass type) {
914 declareInterface(type.getName());
915 }
916
917
918
919
920
921
922 public boolean isInstanceOf(String name) {
923 name = _project.getNameCache().getExternalForm(name, false);
924 String[] interfaces = getInterfaceNames();
925 for (int i = 0; i < interfaces.length; i++)
926 if (interfaces[i].equals(name))
927 return true;
928 for (BCClass type = this; type != null; type = type.getSuperclassBC())
929 if (type.getName().equals(name))
930 return true;
931 return false;
932 }
933
934
935
936
937
938
939 public boolean isInstanceOf(Class type) {
940 if (type == null)
941 return false;
942 return isInstanceOf(type.getName());
943 }
944
945
946
947
948
949
950 public boolean isInstanceOf(BCClass type) {
951 if (type == null)
952 return false;
953 return isInstanceOf(type.getName());
954 }
955
956
957
958
959
960
961
962
963 public BCField[] getDeclaredFields() {
964 Collection fields = _state.getFieldsHolder();
965 return (BCField[]) fields.toArray(new BCField[fields.size()]);
966 }
967
968
969
970
971 public BCField getDeclaredField(String name) {
972 BCField[] fields = getDeclaredFields();
973 for (int i = 0; i < fields.length; i++)
974 if (fields[i].getName().equals(name))
975 return fields[i];
976 return null;
977 }
978
979
980
981
982
983 public BCField[] getFields() {
984 Collection allFields = new LinkedList();
985 BCField[] fields;
986 for (BCClass type = this; type != null; type = type.getSuperclassBC()) {
987 fields = type.getDeclaredFields();
988 for (int i = 0; i < fields.length; i++)
989 allFields.add(fields[i]);
990 }
991 return (BCField[]) allFields.toArray(new BCField[allFields.size()]);
992 }
993
994
995
996
997
998 public BCField[] getFields(String name) {
999 List matches = new LinkedList();
1000 BCField[] fields = getFields();
1001 for (int i = 0; i < fields.length; i++)
1002 if (fields[i].getName().equals(name))
1003 matches.add(fields[i]);
1004 return (BCField[]) matches.toArray(new BCField[matches.size()]);
1005 }
1006
1007
1008
1009
1010
1011 public void setDeclaredFields(BCField[] fields) {
1012 clearDeclaredFields();
1013 if (fields != null)
1014 for (int i = 0; i < fields.length; i++)
1015 declareField(fields[i]);
1016 }
1017
1018
1019
1020
1021
1022
1023 public BCField declareField(BCField field) {
1024 BCField newField = declareField(field.getName(), field.getTypeName());
1025 newField.setAccessFlags(field.getAccessFlags());
1026 newField.setAttributes(field.getAttributes());
1027 return newField;
1028 }
1029
1030
1031
1032
1033
1034
1035 public BCField declareField(String name, String type) {
1036 BCField field = new BCField(this);
1037 _state.getFieldsHolder().add(field);
1038 field.initialize(name, _project.getNameCache().getInternalForm(type,
1039 true));
1040 return field;
1041 }
1042
1043
1044
1045
1046
1047
1048 public BCField declareField(String name, Class type) {
1049 String typeName = (type == null) ? null : type.getName();
1050 return declareField(name, typeName);
1051 }
1052
1053
1054
1055
1056
1057
1058 public BCField declareField(String name, BCClass type) {
1059 String typeName = (type == null) ? null : type.getName();
1060 return declareField(name, typeName);
1061 }
1062
1063
1064
1065
1066 public void clearDeclaredFields() {
1067 Collection fields = _state.getFieldsHolder();
1068 BCField field;
1069 for (Iterator itr = fields.iterator(); itr.hasNext();) {
1070 field = (BCField) itr.next();
1071 itr.remove();
1072 field.invalidate();
1073 }
1074 }
1075
1076
1077
1078
1079
1080
1081
1082 public boolean removeDeclaredField(String name) {
1083 Collection fields = _state.getFieldsHolder();
1084 BCField field;
1085 for (Iterator itr = fields.iterator(); itr.hasNext();) {
1086 field = (BCField) itr.next();
1087 if (field.getName().equals(name)) {
1088 itr.remove();
1089 field.invalidate();
1090 return true;
1091 }
1092 }
1093 return false;
1094 }
1095
1096
1097
1098
1099
1100
1101
1102 public boolean removeDeclaredField(BCField field) {
1103 if (field == null)
1104 return false;
1105 return removeDeclaredField(field.getName());
1106 }
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116 public BCMethod[] getDeclaredMethods() {
1117 Collection methods = _state.getMethodsHolder();
1118 return (BCMethod[]) methods.toArray(new BCMethod[methods.size()]);
1119 }
1120
1121
1122
1123
1124
1125
1126
1127
1128 public BCMethod getDeclaredMethod(String name) {
1129 BCMethod[] methods = getDeclaredMethods();
1130 for (int i = 0; i < methods.length; i++)
1131 if (methods[i].getName().equals(name))
1132 return methods[i];
1133 return null;
1134 }
1135
1136
1137
1138
1139
1140
1141
1142 public BCMethod[] getDeclaredMethods(String name) {
1143 Collection matches = new LinkedList();
1144 BCMethod[] methods = getDeclaredMethods();
1145 for (int i = 0; i < methods.length; i++)
1146 if (methods[i].getName().equals(name))
1147 matches.add(methods[i]);
1148 return (BCMethod[]) matches.toArray(new BCMethod[matches.size()]);
1149 }
1150
1151
1152
1153
1154
1155
1156
1157 public BCMethod getDeclaredMethod(String name, String[] paramTypes) {
1158 if (paramTypes == null)
1159 paramTypes = new String[0];
1160
1161 String[] curParams;
1162 boolean match;
1163 BCMethod[] methods = getDeclaredMethods();
1164 for (int i = 0; i < methods.length; i++) {
1165 if (!methods[i].getName().equals(name))
1166 continue;
1167 curParams = methods[i].getParamNames();
1168 if (curParams.length != paramTypes.length)
1169 continue;
1170
1171 match = true;
1172 for (int j = 0; j < paramTypes.length; j++) {
1173 if (!curParams[j].equals(_project.getNameCache().
1174 getExternalForm(paramTypes[j], false))) {
1175 match = false;
1176 break;
1177 }
1178 }
1179 if (match)
1180 return methods[i];
1181 }
1182 return null;
1183 }
1184
1185
1186
1187
1188
1189
1190
1191 public BCMethod getDeclaredMethod(String name, Class[] paramTypes) {
1192 if (paramTypes == null)
1193 return getDeclaredMethod(name, (String[]) null);
1194
1195 String[] paramNames = new String[paramTypes.length];
1196 for (int i = 0; i < paramTypes.length; i++)
1197 paramNames[i] = paramTypes[i].getName();
1198 return getDeclaredMethod(name, paramNames);
1199 }
1200
1201
1202
1203
1204
1205
1206
1207 public BCMethod getDeclaredMethod(String name, BCClass[] paramTypes) {
1208 if (paramTypes == null)
1209 return getDeclaredMethod(name, (String[]) null);
1210
1211 String[] paramNames = new String[paramTypes.length];
1212 for (int i = 0; i < paramTypes.length; i++)
1213 paramNames[i] = paramTypes[i].getName();
1214 return getDeclaredMethod(name, paramNames);
1215 }
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225 public BCMethod[] getMethods() {
1226 Collection allMethods = new LinkedList();
1227 BCMethod[] methods;
1228 for (BCClass type = this; type != null; type = type.getSuperclassBC()) {
1229 methods = type.getDeclaredMethods();
1230 for (int i = 0; i < methods.length; i++)
1231 allMethods.add(methods[i]);
1232 }
1233 return (BCMethod[]) allMethods.toArray(new BCMethod[allMethods.size()]);
1234 }
1235
1236
1237
1238
1239
1240
1241
1242 public BCMethod[] getMethods(String name) {
1243 Collection matches = new LinkedList();
1244 BCMethod[] methods = getMethods();
1245 for (int i = 0; i < methods.length; i++)
1246 if (methods[i].getName().equals(name))
1247 matches.add(methods[i]);
1248 return (BCMethod[]) matches.toArray(new BCMethod[matches.size()]);
1249 }
1250
1251
1252
1253
1254
1255
1256
1257 public BCMethod[] getMethods(String name, String[] paramTypes) {
1258 if (paramTypes == null)
1259 paramTypes = new String[0];
1260
1261 String[] curParams;
1262 boolean match;
1263 BCMethod[] methods = getMethods();
1264 Collection matches = new LinkedList();
1265 for (int i = 0; i < methods.length; i++) {
1266 if (!methods[i].getName().equals(name))
1267 continue;
1268 curParams = methods[i].getParamNames();
1269 if (curParams.length != paramTypes.length)
1270 continue;
1271
1272 match = true;
1273 for (int j = 0; j < paramTypes.length; j++) {
1274 if (!curParams[j].equals(_project.getNameCache().
1275 getExternalForm(paramTypes[j], false))) {
1276 match = false;
1277 break;
1278 }
1279 }
1280 if (match)
1281 matches.add(methods[i]);
1282 }
1283 return (BCMethod[]) matches.toArray(new BCMethod[matches.size()]);
1284 }
1285
1286
1287
1288
1289
1290
1291
1292 public BCMethod[] getMethods(String name, Class[] paramTypes) {
1293 if (paramTypes == null)
1294 return getMethods(name, (String[]) null);
1295
1296 String[] paramNames = new String[paramTypes.length];
1297 for (int i = 0; i < paramTypes.length; i++)
1298 paramNames[i] = paramTypes[i].getName();
1299 return getMethods(name, paramNames);
1300 }
1301
1302
1303
1304
1305
1306
1307
1308 public BCMethod[] getMethods(String name, BCClass[] paramTypes) {
1309 if (paramTypes == null)
1310 return getMethods(name, (String[]) null);
1311
1312 String[] paramNames = new String[paramTypes.length];
1313 for (int i = 0; i < paramTypes.length; i++)
1314 paramNames[i] = paramTypes[i].getName();
1315 return getMethods(name, paramNames);
1316 }
1317
1318
1319
1320
1321
1322 public void setDeclaredMethods(BCMethod[] methods) {
1323 clearDeclaredMethods();
1324 if (methods != null)
1325 for (int i = 0; i < methods.length; i++)
1326 declareMethod(methods[i]);
1327 }
1328
1329
1330
1331
1332
1333
1334 public BCMethod declareMethod(BCMethod method) {
1335 BCMethod newMethod = declareMethod(method.getName(),
1336 method.getReturnName(), method.getParamNames());
1337 newMethod.setAccessFlags(method.getAccessFlags());
1338 newMethod.setAttributes(method.getAttributes());
1339 return newMethod;
1340 }
1341
1342
1343
1344
1345
1346
1347
1348
1349 public BCMethod declareMethod(String name, String returnType,
1350 String[] paramTypes) {
1351 BCMethod method = new BCMethod(this);
1352 _state.getMethodsHolder().add(method);
1353 method.initialize(name, _project.getNameCache().
1354 getDescriptor(returnType, paramTypes));
1355 return method;
1356 }
1357
1358
1359
1360
1361
1362
1363
1364
1365 public BCMethod declareMethod(String name, Class returnType,
1366 Class[] paramTypes) {
1367 String[] paramNames = null;
1368 if (paramTypes != null) {
1369 paramNames = new String[paramTypes.length];
1370 for (int i = 0; i < paramTypes.length; i++)
1371 paramNames[i] = paramTypes[i].getName();
1372 }
1373 String returnName = (returnType == null) ? null : returnType.getName();
1374 return declareMethod(name, returnName, paramNames);
1375 }
1376
1377
1378
1379
1380
1381
1382
1383
1384 public BCMethod declareMethod(String name, BCClass returnType,
1385 BCClass[] paramTypes) {
1386 String[] paramNames = null;
1387 if (paramTypes != null) {
1388 paramNames = new String[paramTypes.length];
1389 for (int i = 0; i < paramTypes.length; i++)
1390 paramNames[i] = paramTypes[i].getName();
1391 }
1392 String returnName = (returnType == null) ? null : returnType.getName();
1393 return declareMethod(name, returnName, paramNames);
1394 }
1395
1396
1397
1398
1399 public void clearDeclaredMethods() {
1400 Collection methods = _state.getMethodsHolder();
1401 BCMethod method;
1402 for (Iterator itr = methods.iterator(); itr.hasNext();) {
1403 method = (BCMethod) itr.next();
1404 itr.remove();
1405 method.invalidate();
1406 }
1407 }
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418 public boolean removeDeclaredMethod(String name) {
1419 Collection methods = _state.getMethodsHolder();
1420 BCMethod method;
1421 for (Iterator itr = methods.iterator(); itr.hasNext();) {
1422 method = (BCMethod) itr.next();
1423 if (method.getName().equals(name)) {
1424 itr.remove();
1425 method.invalidate();
1426 return true;
1427 }
1428 }
1429 return false;
1430 }
1431
1432
1433
1434
1435
1436
1437
1438 public boolean removeDeclaredMethod(BCMethod method) {
1439 if (method == null)
1440 return false;
1441 return removeDeclaredMethod(method.getName(), method.getParamNames());
1442 }
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452 public boolean removeDeclaredMethod(String name, String[] paramTypes) {
1453 if (paramTypes == null)
1454 paramTypes = new String[0];
1455
1456 String[] curParams;
1457 boolean match;
1458 Collection methods = _state.getMethodsHolder();
1459 BCMethod method;
1460 for (Iterator itr = methods.iterator(); itr.hasNext();) {
1461 method = (BCMethod) itr.next();
1462 if (!method.getName().equals(name))
1463 continue;
1464 curParams = method.getParamNames();
1465 if (curParams.length != paramTypes.length)
1466 continue;
1467
1468 match = true;
1469 for (int j = 0; j < paramTypes.length; j++) {
1470 if (!curParams[j].equals(_project.getNameCache().
1471 getExternalForm(paramTypes[j], false))) {
1472 match = false;
1473 break;
1474 }
1475 }
1476 if (match) {
1477 itr.remove();
1478 method.invalidate();
1479 return true;
1480 }
1481 }
1482 return false;
1483 }
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493 public boolean removeDeclaredMethod(String name, Class[] paramTypes) {
1494 if (paramTypes == null)
1495 return removeDeclaredMethod(name, (String[]) null);
1496
1497 String[] paramNames = new String[paramTypes.length];
1498 for (int i = 0; i < paramTypes.length; i++)
1499 paramNames[i] = paramTypes[i].getName();
1500 return removeDeclaredMethod(name, paramNames);
1501 }
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511 public boolean removeDeclaredMethod(String name, BCClass[] paramTypes) {
1512 if (paramTypes == null)
1513 return removeDeclaredMethod(name, (String[]) null);
1514
1515 String[] paramNames = new String[paramTypes.length];
1516 for (int i = 0; i < paramTypes.length; i++)
1517 paramNames[i] = paramTypes[i].getName();
1518 return removeDeclaredMethod(name, paramNames);
1519 }
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533 public BCMethod addDefaultConstructor() {
1534 BCMethod method = getDeclaredMethod("<init>", (String[]) null);
1535 if (method != null)
1536 return method;
1537
1538 method = declareMethod("<init>", void.class, null);
1539 Code code = method.getCode(true);
1540 code.setMaxStack(1);
1541 code.setMaxLocals(1);
1542
1543 code.xload().setThis();
1544 code.invokespecial()
1545 .setMethod(getSuperclassName(), "<init>", "void", null);
1546 code.vreturn();
1547 return method;
1548 }
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559 public SourceFile getSourceFile(boolean add) {
1560 SourceFile source = (SourceFile) getAttribute(Constants.ATTR_SOURCE);
1561 if (!add || (source != null))
1562 return source;
1563 return (SourceFile) addAttribute(Constants.ATTR_SOURCE);
1564 }
1565
1566
1567
1568
1569
1570
1571
1572 public boolean removeSourceFile() {
1573 return removeAttribute(Constants.ATTR_SOURCE);
1574 }
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585 public InnerClasses getInnerClasses(boolean add) {
1586 InnerClasses inner = (InnerClasses) getAttribute
1587 (Constants.ATTR_INNERCLASS);
1588 if (!add || (inner != null))
1589 return inner;
1590 return (InnerClasses) addAttribute(Constants.ATTR_INNERCLASS);
1591 }
1592
1593
1594
1595
1596
1597
1598
1599 public boolean removeInnerClasses() {
1600 return removeAttribute(Constants.ATTR_INNERCLASS);
1601 }
1602
1603
1604
1605
1606
1607 public boolean isDeprecated() {
1608 return getAttribute(Constants.ATTR_DEPRECATED) != null;
1609 }
1610
1611
1612
1613
1614
1615 public void setDeprecated(boolean on) {
1616 if (!on)
1617 removeAttribute(Constants.ATTR_DEPRECATED);
1618 else if (!isDeprecated())
1619 addAttribute(Constants.ATTR_DEPRECATED);
1620 }
1621
1622
1623
1624
1625
1626 public void acceptVisit(BCVisitor visit) {
1627 visit.enterBCClass(this);
1628
1629 ConstantPool pool = null;
1630 try {
1631 pool = _state.getPool();
1632 } catch (UnsupportedOperationException uoe) {
1633 }
1634 if (pool != null)
1635 pool.acceptVisit(visit);
1636
1637 BCField[] fields = getDeclaredFields();
1638 for (int i = 0; i < fields.length; i++) {
1639 visit.enterBCMember(fields[i]);
1640 fields[i].acceptVisit(visit);
1641 visit.exitBCMember(fields[i]);
1642 }
1643
1644 BCMethod[] methods = getDeclaredMethods();
1645 for (int i = 0; i < methods.length; i++) {
1646 visit.enterBCMember(methods[i]);
1647 methods[i].acceptVisit(visit);
1648 visit.exitBCMember(methods[i]);
1649 }
1650
1651 visitAttributes(visit);
1652 visit.exitBCClass(this);
1653 }
1654
1655
1656
1657
1658
1659 public Project getProject() {
1660 return _project;
1661 }
1662
1663 public ConstantPool getPool() {
1664 return _state.getPool();
1665 }
1666
1667 public ClassLoader getClassLoader() {
1668 if (_loader != null)
1669 return _loader;
1670 return Thread.currentThread().getContextClassLoader();
1671 }
1672
1673 public boolean isValid() {
1674 return _project != null;
1675 }
1676
1677 Collection getAttributesHolder() {
1678 return _state.getAttributesHolder();
1679 }
1680
1681
1682
1683
1684
1685 BCClass getBCClass() {
1686 return this;
1687 }
1688
1689
1690
1691
1692
1693
1694
1695 private void beforeRename(String oldName, String newName) {
1696 if ((_project != null) && (oldName != null))
1697 _project.renameClass(oldName, newName, this);
1698 }
1699 }