1
17 package org.apache.catalina.deploy;
18
19 import java.beans.PropertyChangeListener;
20 import java.beans.PropertyChangeSupport;
21 import java.io.Serializable;
22 import java.lang.reflect.Field;
23 import java.lang.reflect.InvocationTargetException;
24 import java.lang.reflect.Method;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30
31 import javax.naming.NamingException;
32
33 import org.apache.catalina.Container;
34 import org.apache.catalina.Context;
35 import org.apache.catalina.Engine;
36 import org.apache.catalina.JmxEnabled;
37 import org.apache.catalina.LifecycleException;
38 import org.apache.catalina.LifecycleState;
39 import org.apache.catalina.Server;
40 import org.apache.catalina.mbeans.MBeanUtils;
41 import org.apache.catalina.util.Introspection;
42 import org.apache.catalina.util.LifecycleMBeanBase;
43 import org.apache.juli.logging.Log;
44 import org.apache.juli.logging.LogFactory;
45 import org.apache.naming.ContextBindings;
46 import org.apache.tomcat.util.ExceptionUtils;
47 import org.apache.tomcat.util.descriptor.web.ContextEjb;
48 import org.apache.tomcat.util.descriptor.web.ContextEnvironment;
49 import org.apache.tomcat.util.descriptor.web.ContextLocalEjb;
50 import org.apache.tomcat.util.descriptor.web.ContextResource;
51 import org.apache.tomcat.util.descriptor.web.ContextResourceEnvRef;
52 import org.apache.tomcat.util.descriptor.web.ContextResourceLink;
53 import org.apache.tomcat.util.descriptor.web.ContextService;
54 import org.apache.tomcat.util.descriptor.web.ContextTransaction;
55 import org.apache.tomcat.util.descriptor.web.InjectionTarget;
56 import org.apache.tomcat.util.descriptor.web.MessageDestinationRef;
57 import org.apache.tomcat.util.descriptor.web.NamingResources;
58 import org.apache.tomcat.util.descriptor.web.ResourceBase;
59 import org.apache.tomcat.util.res.StringManager;
60
61
62
68 public class NamingResourcesImpl extends LifecycleMBeanBase
69 implements Serializable, NamingResources {
70
71 private static final long serialVersionUID = 1L;
72
73 private static final Log log = LogFactory.getLog(NamingResourcesImpl.class);
74
75 private static final StringManager sm = StringManager.getManager(NamingResourcesImpl.class);
76
77 private volatile boolean resourceRequireExplicitRegistration = false;
78
79
80
81
82
85 public NamingResourcesImpl() {
86
87 }
88
89
90
91
92
93
96 private Object container = null;
97
98
99
102 private final Set<String> entries = new HashSet<>();
103
104
105
108 private final Map<String, ContextEjb> ejbs = new HashMap<>();
109
110
111
114 private final Map<String, ContextEnvironment> envs = new HashMap<>();
115
116
117
121 private final Map<String, ContextLocalEjb> localEjbs = new HashMap<>();
122
123
124
128 private final Map<String, MessageDestinationRef> mdrs = new HashMap<>();
129
130
131
135 private final HashMap<String, ContextResourceEnvRef> resourceEnvRefs =
136 new HashMap<>();
137
138
139
142 private final HashMap<String, ContextResource> resources =
143 new HashMap<>();
144
145
146
149 private final HashMap<String, ContextResourceLink> resourceLinks =
150 new HashMap<>();
151
152
153
156 private final HashMap<String, ContextService> services =
157 new HashMap<>();
158
159
160
163 private ContextTransaction transaction = null;
164
165
166
169 protected final PropertyChangeSupport support =
170 new PropertyChangeSupport(this);
171
172
173
174
175
176
179 @Override
180 public Object getContainer() {
181 return container;
182 }
183
184
185
189 public void setContainer(Object container) {
190 this.container = container;
191 }
192
193
194
198 public void setTransaction(ContextTransaction transaction) {
199 this.transaction = transaction;
200 }
201
202
203
206 public ContextTransaction getTransaction() {
207 return transaction;
208 }
209
210
211
216 public void addEjb(ContextEjb ejb) {
217
218
219 String ejbLink = ejb.getLink();
220 String lookupName = ejb.getLookupName();
221
222 if (ejbLink != null && ejbLink.length() > 0 && lookupName != null && lookupName.length() > 0) {
223 throw new IllegalArgumentException(
224 sm.getString("namingResources.ejbLookupLink", ejb.getName()));
225 }
226
227 if (entries.contains(ejb.getName())) {
228 return;
229 } else {
230 entries.add(ejb.getName());
231 }
232
233 synchronized (ejbs) {
234 ejb.setNamingResources(this);
235 ejbs.put(ejb.getName(), ejb);
236 }
237 support.firePropertyChange("ejb", null, ejb);
238
239 }
240
241
242
247 @Override
248 public void addEnvironment(ContextEnvironment environment) {
249
250 if (entries.contains(environment.getName())) {
251 ContextEnvironment ce = findEnvironment(environment.getName());
252 ContextResourceLink rl = findResourceLink(environment.getName());
253 if (ce != null) {
254 if (ce.getOverride()) {
255 removeEnvironment(environment.getName());
256 } else {
257 return;
258 }
259 } else if (rl != null) {
260
261 NamingResourcesImpl global = getServer().getGlobalNamingResources();
262 if (global.findEnvironment(rl.getGlobal()) != null) {
263 if (global.findEnvironment(rl.getGlobal()).getOverride()) {
264 removeResourceLink(environment.getName());
265 } else {
266 return;
267 }
268 }
269 } else {
270
271 return;
272 }
273 }
274
275 List<InjectionTarget> injectionTargets = environment.getInjectionTargets();
276 String value = environment.getValue();
277 String lookupName = environment.getLookupName();
278
279
280 if (injectionTargets != null && injectionTargets.size() > 0 &&
281 (value == null || value.length() == 0)) {
282 return;
283 }
284
285
286 if (value != null && value.length() > 0 && lookupName != null && lookupName.length() > 0) {
287 throw new IllegalArgumentException(
288 sm.getString("namingResources.envEntryLookupValue", environment.getName()));
289 }
290
291 if (!checkResourceType(environment)) {
292 throw new IllegalArgumentException(sm.getString(
293 "namingResources.resourceTypeFail", environment.getName(),
294 environment.getType()));
295 }
296
297 entries.add(environment.getName());
298
299 synchronized (envs) {
300 environment.setNamingResources(this);
301 envs.put(environment.getName(), environment);
302 }
303 support.firePropertyChange("environment", null, environment);
304
305
306 if (resourceRequireExplicitRegistration) {
307 try {
308 MBeanUtils.createMBean(environment);
309 } catch (Exception e) {
310 log.warn(sm.getString("namingResources.mbeanCreateFail",
311 environment.getName()), e);
312 }
313 }
314 }
315
316
317
318 private Server getServer() {
319 if (container instanceof Server) {
320 return (Server) container;
321 }
322 if (container instanceof Context) {
323
324 Engine engine =
325 (Engine) ((Context) container).getParent().getParent();
326 return engine.getService().getServer();
327 }
328 return null;
329 }
330
331
336 public void addLocalEjb(ContextLocalEjb ejb) {
337
338 if (entries.contains(ejb.getName())) {
339 return;
340 } else {
341 entries.add(ejb.getName());
342 }
343
344 synchronized (localEjbs) {
345 ejb.setNamingResources(this);
346 localEjbs.put(ejb.getName(), ejb);
347 }
348 support.firePropertyChange("localEjb", null, ejb);
349
350 }
351
352
353
358 public void addMessageDestinationRef(MessageDestinationRef mdr) {
359
360 if (entries.contains(mdr.getName())) {
361 return;
362 } else {
363 if (!checkResourceType(mdr)) {
364 throw new IllegalArgumentException(sm.getString(
365 "namingResources.resourceTypeFail", mdr.getName(),
366 mdr.getType()));
367 }
368 entries.add(mdr.getName());
369 }
370
371 synchronized (mdrs) {
372 mdr.setNamingResources(this);
373 mdrs.put(mdr.getName(), mdr);
374 }
375 support.firePropertyChange("messageDestinationRef", null, mdr);
376
377 }
378
379
380
385 public void addPropertyChangeListener(PropertyChangeListener listener) {
386
387 support.addPropertyChangeListener(listener);
388
389 }
390
391
392
397 @Override
398 public void addResource(ContextResource resource) {
399
400 if (entries.contains(resource.getName())) {
401 return;
402 } else {
403 if (!checkResourceType(resource)) {
404 throw new IllegalArgumentException(sm.getString(
405 "namingResources.resourceTypeFail", resource.getName(),
406 resource.getType()));
407 }
408 entries.add(resource.getName());
409 }
410
411 synchronized (resources) {
412 resource.setNamingResources(this);
413 resources.put(resource.getName(), resource);
414 }
415 support.firePropertyChange("resource", null, resource);
416
417
418 if (resourceRequireExplicitRegistration) {
419 try {
420 MBeanUtils.createMBean(resource);
421 } catch (Exception e) {
422 log.warn(sm.getString("namingResources.mbeanCreateFail",
423 resource.getName()), e);
424 }
425 }
426 }
427
428
429
434 public void addResourceEnvRef(ContextResourceEnvRef resource) {
435
436 if (entries.contains(resource.getName())) {
437 return;
438 } else {
439 if (!checkResourceType(resource)) {
440 throw new IllegalArgumentException(sm.getString(
441 "namingResources.resourceTypeFail", resource.getName(),
442 resource.getType()));
443 }
444 entries.add(resource.getName());
445 }
446
447 synchronized (resourceEnvRefs) {
448 resource.setNamingResources(this);
449 resourceEnvRefs.put(resource.getName(), resource);
450 }
451 support.firePropertyChange("resourceEnvRef", null, resource);
452
453 }
454
455
456
461 @Override
462 public void addResourceLink(ContextResourceLink resourceLink) {
463
464 if (entries.contains(resourceLink.getName())) {
465 return;
466 } else {
467 entries.add(resourceLink.getName());
468 }
469
470 synchronized (resourceLinks) {
471 resourceLink.setNamingResources(this);
472 resourceLinks.put(resourceLink.getName(), resourceLink);
473 }
474 support.firePropertyChange("resourceLink", null, resourceLink);
475
476
477 if (resourceRequireExplicitRegistration) {
478 try {
479 MBeanUtils.createMBean(resourceLink);
480 } catch (Exception e) {
481 log.warn(sm.getString("namingResources.mbeanCreateFail",
482 resourceLink.getName()), e);
483 }
484 }
485 }
486
487
488
493 public void addService(ContextService service) {
494
495 if (entries.contains(service.getName())) {
496 return;
497 } else {
498 entries.add(service.getName());
499 }
500
501 synchronized (services) {
502 service.setNamingResources(this);
503 services.put(service.getName(), service);
504 }
505 support.firePropertyChange("service", null, service);
506
507 }
508
509
510
516 public ContextEjb findEjb(String name) {
517
518 synchronized (ejbs) {
519 return ejbs.get(name);
520 }
521
522 }
523
524
525
529 public ContextEjb[] findEjbs() {
530
531 synchronized (ejbs) {
532 ContextEjb results[] = new ContextEjb[ejbs.size()];
533 return ejbs.values().toArray(results);
534 }
535
536 }
537
538
539
545 public ContextEnvironment findEnvironment(String name) {
546
547 synchronized (envs) {
548 return envs.get(name);
549 }
550
551 }
552
553
554
559 public ContextEnvironment[] findEnvironments() {
560
561 synchronized (envs) {
562 ContextEnvironment results[] = new ContextEnvironment[envs.size()];
563 return envs.values().toArray(results);
564 }
565
566 }
567
568
569
575 public ContextLocalEjb findLocalEjb(String name) {
576
577 synchronized (localEjbs) {
578 return localEjbs.get(name);
579 }
580
581 }
582
583
584
588 public ContextLocalEjb[] findLocalEjbs() {
589
590 synchronized (localEjbs) {
591 ContextLocalEjb results[] = new ContextLocalEjb[localEjbs.size()];
592 return localEjbs.values().toArray(results);
593 }
594
595 }
596
597
598
604 public MessageDestinationRef findMessageDestinationRef(String name) {
605
606 synchronized (mdrs) {
607 return mdrs.get(name);
608 }
609
610 }
611
612
613
617 public MessageDestinationRef[] findMessageDestinationRefs() {
618
619 synchronized (mdrs) {
620 MessageDestinationRef results[] =
621 new MessageDestinationRef[mdrs.size()];
622 return mdrs.values().toArray(results);
623 }
624
625 }
626
627
628
634 public ContextResource findResource(String name) {
635
636 synchronized (resources) {
637 return resources.get(name);
638 }
639
640 }
641
642
643
649 public ContextResourceLink findResourceLink(String name) {
650
651 synchronized (resourceLinks) {
652 return resourceLinks.get(name);
653 }
654
655 }
656
657
658
662 public ContextResourceLink[] findResourceLinks() {
663
664 synchronized (resourceLinks) {
665 ContextResourceLink results[] =
666 new ContextResourceLink[resourceLinks.size()];
667 return resourceLinks.values().toArray(results);
668 }
669
670 }
671
672
673
677 public ContextResource[] findResources() {
678
679 synchronized (resources) {
680 ContextResource results[] = new ContextResource[resources.size()];
681 return resources.values().toArray(results);
682 }
683
684 }
685
686
687
693 public ContextResourceEnvRef findResourceEnvRef(String name) {
694
695 synchronized (resourceEnvRefs) {
696 return resourceEnvRefs.get(name);
697 }
698
699 }
700
701
702
707 public ContextResourceEnvRef[] findResourceEnvRefs() {
708
709 synchronized (resourceEnvRefs) {
710 ContextResourceEnvRef results[] = new ContextResourceEnvRef[resourceEnvRefs.size()];
711 return resourceEnvRefs.values().toArray(results);
712 }
713
714 }
715
716
717
723 public ContextService findService(String name) {
724
725 synchronized (services) {
726 return services.get(name);
727 }
728
729 }
730
731
732
736 public ContextService[] findServices() {
737
738 synchronized (services) {
739 ContextService results[] = new ContextService[services.size()];
740 return services.values().toArray(results);
741 }
742
743 }
744
745
746
751 public void removeEjb(String name) {
752
753 entries.remove(name);
754
755 ContextEjb ejb = null;
756 synchronized (ejbs) {
757 ejb = ejbs.remove(name);
758 }
759 if (ejb != null) {
760 support.firePropertyChange("ejb", ejb, null);
761 ejb.setNamingResources(null);
762 }
763
764 }
765
766
767
772 @Override
773 public void removeEnvironment(String name) {
774
775 entries.remove(name);
776
777 ContextEnvironment environment = null;
778 synchronized (envs) {
779 environment = envs.remove(name);
780 }
781 if (environment != null) {
782 support.firePropertyChange("environment", environment, null);
783
784 if (resourceRequireExplicitRegistration) {
785 try {
786 MBeanUtils.destroyMBean(environment);
787 } catch (Exception e) {
788 log.warn(sm.getString("namingResources.mbeanDestroyFail",
789 environment.getName()), e);
790 }
791 }
792 environment.setNamingResources(null);
793 }
794 }
795
796
797
802 public void removeLocalEjb(String name) {
803
804 entries.remove(name);
805
806 ContextLocalEjb localEjb = null;
807 synchronized (localEjbs) {
808 localEjb = localEjbs.remove(name);
809 }
810 if (localEjb != null) {
811 support.firePropertyChange("localEjb", localEjb, null);
812 localEjb.setNamingResources(null);
813 }
814
815 }
816
817
818
823 public void removeMessageDestinationRef(String name) {
824
825 entries.remove(name);
826
827 MessageDestinationRef mdr = null;
828 synchronized (mdrs) {
829 mdr = mdrs.remove(name);
830 }
831 if (mdr != null) {
832 support.firePropertyChange("messageDestinationRef",
833 mdr, null);
834 mdr.setNamingResources(null);
835 }
836
837 }
838
839
840
845 public void removePropertyChangeListener(PropertyChangeListener listener) {
846
847 support.removePropertyChangeListener(listener);
848
849 }
850
851
852
857 @Override
858 public void removeResource(String name) {
859
860 entries.remove(name);
861
862 ContextResource resource = null;
863 synchronized (resources) {
864 resource = resources.remove(name);
865 }
866 if (resource != null) {
867 support.firePropertyChange("resource", resource, null);
868
869 if (resourceRequireExplicitRegistration) {
870 try {
871 MBeanUtils.destroyMBean(resource);
872 } catch (Exception e) {
873 log.warn(sm.getString("namingResources.mbeanDestroyFail",
874 resource.getName()), e);
875 }
876 }
877 resource.setNamingResources(null);
878 }
879 }
880
881
882
887 public void removeResourceEnvRef(String name) {
888
889 entries.remove(name);
890
891 ContextResourceEnvRef resourceEnvRef = null;
892 synchronized (resourceEnvRefs) {
893 resourceEnvRef =
894 resourceEnvRefs.remove(name);
895 }
896 if (resourceEnvRef != null) {
897 support.firePropertyChange("resourceEnvRef", resourceEnvRef, null);
898 resourceEnvRef.setNamingResources(null);
899 }
900
901 }
902
903
904
909 @Override
910 public void removeResourceLink(String name) {
911
912 entries.remove(name);
913
914 ContextResourceLink resourceLink = null;
915 synchronized (resourceLinks) {
916 resourceLink = resourceLinks.remove(name);
917 }
918 if (resourceLink != null) {
919 support.firePropertyChange("resourceLink", resourceLink, null);
920
921 if (resourceRequireExplicitRegistration) {
922 try {
923 MBeanUtils.destroyMBean(resourceLink);
924 } catch (Exception e) {
925 log.warn(sm.getString("namingResources.mbeanDestroyFail",
926 resourceLink.getName()), e);
927 }
928 }
929 resourceLink.setNamingResources(null);
930 }
931 }
932
933
934
939 public void removeService(String name) {
940
941 entries.remove(name);
942
943 ContextService service = null;
944 synchronized (services) {
945 service = services.remove(name);
946 }
947 if (service != null) {
948 support.firePropertyChange("service", service, null);
949 service.setNamingResources(null);
950 }
951
952 }
953
954
955
956
957 @Override
958 protected void initInternal() throws LifecycleException {
959 super.initInternal();
960
961
962
963 resourceRequireExplicitRegistration = true;
964
965 for (ContextResource cr : resources.values()) {
966 try {
967 MBeanUtils.createMBean(cr);
968 } catch (Exception e) {
969 log.warn(sm.getString(
970 "namingResources.mbeanCreateFail", cr.getName()), e);
971 }
972 }
973
974 for (ContextEnvironment ce : envs.values()) {
975 try {
976 MBeanUtils.createMBean(ce);
977 } catch (Exception e) {
978 log.warn(sm.getString(
979 "namingResources.mbeanCreateFail", ce.getName()), e);
980 }
981 }
982
983 for (ContextResourceLink crl : resourceLinks.values()) {
984 try {
985 MBeanUtils.createMBean(crl);
986 } catch (Exception e) {
987 log.warn(sm.getString(
988 "namingResources.mbeanCreateFail", crl.getName()), e);
989 }
990 }
991 }
992
993
994 @Override
995 protected void startInternal() throws LifecycleException {
996 fireLifecycleEvent(CONFIGURE_START_EVENT, null);
997 setState(LifecycleState.STARTING);
998 }
999
1000
1001 @Override
1002 protected void stopInternal() throws LifecycleException {
1003 cleanUp();
1004 setState(LifecycleState.STOPPING);
1005 fireLifecycleEvent(CONFIGURE_STOP_EVENT, null);
1006 }
1007
1008
1011 private void cleanUp() {
1012 if (resources.size() == 0) {
1013 return;
1014 }
1015 javax.naming.Context ctxt;
1016 try {
1017 if (container instanceof Server) {
1018 ctxt = ((Server) container).getGlobalNamingContext();
1019 } else {
1020 ctxt = ContextBindings.getClassLoader();
1021 ctxt = (javax.naming.Context) ctxt.lookup("comp/env");
1022 }
1023 } catch (NamingException e) {
1024 log.warn(sm.getString("namingResources.cleanupNoContext",
1025 container), e);
1026 return;
1027 }
1028 for (ContextResource cr: resources.values()) {
1029 if (cr.getSingleton()) {
1030 String closeMethod = cr.getCloseMethod();
1031 if (closeMethod != null && closeMethod.length() > 0) {
1032 String name = cr.getName();
1033 Object resource;
1034 try {
1035 resource = ctxt.lookup(name);
1036 } catch (NamingException e) {
1037 log.warn(sm.getString(
1038 "namingResources.cleanupNoResource",
1039 cr.getName(), container), e);
1040 continue;
1041 }
1042 cleanUp(resource, name, closeMethod);
1043 }
1044 }
1045 }
1046 }
1047
1048
1049
1057 private void cleanUp(Object resource, String name, String closeMethod) {
1058
1059 Method m = null;
1060 try {
1061 m = resource.getClass().getMethod(closeMethod, (Class<?>[]) null);
1062 } catch (SecurityException e) {
1063 log.debug(sm.getString("namingResources.cleanupCloseSecurity",
1064 closeMethod, name, container));
1065 return;
1066 } catch (NoSuchMethodException e) {
1067 log.debug(sm.getString("namingResources.cleanupNoClose",
1068 name, container, closeMethod));
1069 return;
1070 }
1071 try {
1072 m.invoke(resource, (Object[]) null);
1073 } catch (IllegalArgumentException | IllegalAccessException e) {
1074 log.warn(sm.getString("namingResources.cleanupCloseFailed",
1075 closeMethod, name, container), e);
1076 } catch (InvocationTargetException e) {
1077 Throwable t = ExceptionUtils.unwrapInvocationTargetException(e);
1078 ExceptionUtils.handleThrowable(t);
1079 log.warn(sm.getString("namingResources.cleanupCloseFailed",
1080 closeMethod, name, container), t);
1081 }
1082 }
1083
1084 @Override
1085 protected void destroyInternal() throws LifecycleException {
1086
1087
1088
1089 resourceRequireExplicitRegistration = false;
1090
1091
1092 for (ContextResourceLink crl : resourceLinks.values()) {
1093 try {
1094 MBeanUtils.destroyMBean(crl);
1095 } catch (Exception e) {
1096 log.warn(sm.getString(
1097 "namingResources.mbeanDestroyFail", crl.getName()), e);
1098 }
1099 }
1100
1101 for (ContextEnvironment ce : envs.values()) {
1102 try {
1103 MBeanUtils.destroyMBean(ce);
1104 } catch (Exception e) {
1105 log.warn(sm.getString(
1106 "namingResources.mbeanDestroyFail", ce.getName()), e);
1107 }
1108 }
1109
1110 for (ContextResource cr : resources.values()) {
1111 try {
1112 MBeanUtils.destroyMBean(cr);
1113 } catch (Exception e) {
1114 log.warn(sm.getString(
1115 "namingResources.mbeanDestroyFail", cr.getName()), e);
1116 }
1117 }
1118
1119 super.destroyInternal();
1120 }
1121
1122
1123 @Override
1124 protected String getDomainInternal() {
1125
1126 Object c = getContainer();
1127
1128 if (c instanceof JmxEnabled) {
1129 return ((JmxEnabled) c).getDomain();
1130 }
1131
1132 return null;
1133 }
1134
1135
1136 @Override
1137 protected String getObjectNameKeyProperties() {
1138 Object c = getContainer();
1139 if (c instanceof Container) {
1140 return "type=NamingResources" +
1141 ((Container) c).getMBeanKeyProperties();
1142 }
1143
1144 return "type=NamingResources";
1145 }
1146
1147
1159 private boolean checkResourceType(ResourceBase resource) {
1160 if (!(container instanceof Context)) {
1161
1162 return true;
1163 }
1164
1165 if (resource.getInjectionTargets() == null ||
1166 resource.getInjectionTargets().size() == 0) {
1167
1168 return true;
1169 }
1170
1171 Context context = (Context) container;
1172
1173 String typeName = resource.getType();
1174 Class<?> typeClass = null;
1175 if (typeName != null) {
1176 typeClass = Introspection.loadClass(context, typeName);
1177 if (typeClass == null) {
1178
1179
1180 return true;
1181 }
1182 }
1183
1184 Class<?> compatibleClass =
1185 getCompatibleType(context, resource, typeClass);
1186 if (compatibleClass == null) {
1187
1188
1189 return false;
1190 }
1191
1192 resource.setType(compatibleClass.getCanonicalName());
1193 return true;
1194 }
1195
1196 private Class<?> getCompatibleType(Context context,
1197 ResourceBase resource, Class<?> typeClass) {
1198
1199 Class<?> result = null;
1200
1201 for (InjectionTarget injectionTarget : resource.getInjectionTargets()) {
1202 Class<?> clazz = Introspection.loadClass(
1203 context, injectionTarget.getTargetClass());
1204 if (clazz == null) {
1205
1206 continue;
1207 }
1208
1209
1210 String targetName = injectionTarget.getTargetName();
1211
1212 Class<?> targetType = getSetterType(clazz, targetName);
1213 if (targetType == null) {
1214
1215 targetType = getFieldType(clazz,targetName);
1216 }
1217 if (targetType == null) {
1218
1219 continue;
1220 }
1221 targetType = Introspection.convertPrimitiveType(targetType);
1222
1223 if (typeClass == null) {
1224
1225 if (result == null) {
1226 result = targetType;
1227 } else if (targetType.isAssignableFrom(result)) {
1228
1229 } else if (result.isAssignableFrom(targetType)) {
1230
1231 result = targetType;
1232 } else {
1233
1234 return null;
1235 }
1236 } else {
1237
1238
1239 if (targetType.isAssignableFrom(typeClass)) {
1240 result = typeClass;
1241 } else {
1242
1243 return null;
1244 }
1245 }
1246 }
1247 return result;
1248 }
1249
1250 private Class<?> getSetterType(Class<?> clazz, String name) {
1251 Method[] methods = Introspection.getDeclaredMethods(clazz);
1252 if (methods != null && methods.length > 0) {
1253 for (Method method : methods) {
1254 if (Introspection.isValidSetter(method) &&
1255 Introspection.getPropertyName(method).equals(name)) {
1256 return method.getParameterTypes()[0];
1257 }
1258 }
1259 }
1260 return null;
1261 }
1262
1263 private Class<?> getFieldType(Class<?> clazz, String name) {
1264 Field[] fields = Introspection.getDeclaredFields(clazz);
1265 if (fields != null && fields.length > 0) {
1266 for (Field field : fields) {
1267 if (field.getName().equals(name)) {
1268 return field.getType();
1269 }
1270 }
1271 }
1272 return null;
1273 }
1274 }
1275