KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > deployment > util > EjbBundleValidator


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.deployment.util;
25
26 import java.util.*;
27 import java.util.logging.Level JavaDoc;
28 import java.lang.reflect.Method JavaDoc;
29 import java.lang.reflect.Field JavaDoc;
30 import java.security.AccessController JavaDoc;
31 import java.security.Principal JavaDoc;
32 import java.security.PrivilegedAction JavaDoc;
33 import javax.security.auth.Subject JavaDoc;
34 import com.sun.enterprise.deployment.Application;
35 import com.sun.enterprise.deployment.ApplicationClientDescriptor;
36 import com.sun.enterprise.deployment.BundleDescriptor;
37 import com.sun.enterprise.deployment.ContainerTransaction;
38 import com.sun.enterprise.deployment.Descriptor;
39 import com.sun.enterprise.deployment.DynamicAttributesDescriptor;
40 import com.sun.enterprise.deployment.EjbDescriptor;
41 import com.sun.enterprise.deployment.EjbBundleDescriptor;
42 import com.sun.enterprise.deployment.EjbEntityDescriptor;
43 import com.sun.enterprise.deployment.EjbMessageBeanDescriptor;
44 import com.sun.enterprise.deployment.EjbReferenceDescriptor;
45 import com.sun.enterprise.deployment.InjectionCapable;
46 import com.sun.enterprise.deployment.JmsDestinationReferenceDescriptor;
47 import com.sun.enterprise.deployment.MethodDescriptor;
48 import com.sun.enterprise.deployment.MessageDestinationDescriptor;
49 import com.sun.enterprise.deployment.MessageDestinationReferenceDescriptor;
50 import com.sun.enterprise.deployment.PersistenceDescriptor;
51 import com.sun.enterprise.deployment.RelationshipDescriptor;
52 import com.sun.enterprise.deployment.ResourceReferenceDescriptor;
53 import com.sun.enterprise.deployment.RunAsIdentityDescriptor;
54 import com.sun.enterprise.deployment.WebBundleDescriptor;
55 import com.sun.enterprise.deployment.WebService;
56 import com.sun.enterprise.deployment.InterceptorBindingDescriptor;
57 import com.sun.enterprise.deployment.EjbInterceptor;
58 import com.sun.enterprise.deployment.InjectionTarget;
59 import com.sun.enterprise.deployment.types.EjbReference;
60 import com.sun.enterprise.deployment.interfaces.*;
61 import com.sun.enterprise.util.LocalStringManagerImpl;
62 import com.sun.enterprise.util.TypeUtil;
63
64 /**
65  * This class validates a EJB Bundle descriptor once loaded from an .jar file
66  *
67  * @author Jerome Dochez
68  */

69 public class EjbBundleValidator extends ComponentValidator implements EjbBundleVisitor {
70     
71     protected EjbBundleDescriptor ejbBundleDescriptor=null;
72     protected EjbDescriptor ejb = null;
73     private static LocalStringManagerImpl localStrings =
74             new LocalStringManagerImpl(EjbBundleValidator.class);
75             
76     /** visits an ejb bundle descriptor
77      * @param an ejb bundle descriptor
78      */

79     public void accept(EjbBundleDescriptor bundleDescriptor) {
80         this.ejbBundleDescriptor = bundleDescriptor;
81         if (bundleDescriptor.getEjbs().size() == 0) {
82             throw new IllegalArgumentException JavaDoc(localStrings.getLocalString(
83                 "enterprise.deployment.util.no_ejb_in_ejb_jar",
84                 "Invalid ejb jar {0}: it contains zero ejb. A valid ejb jar requires at least one session/entity/message driven bean.",
85                 new Object JavaDoc[] {bundleDescriptor.getModuleDescriptor().getArchiveUri()}));
86         }
87
88     if (!bundleDescriptor.areResourceReferencesValid()) {
89             throw new RuntimeException JavaDoc("Incorrectly resolved role references");
90         }
91
92         // Now that we have a classloader, we have to check for any
93
// interceptor bindings that were specified in .xml to use
94
// the syntax that refers to all overloaded methods with a
95
// given name.
96
handleOverloadedInterceptorMethodBindings(bundleDescriptor);
97
98         InterceptorBindingTranslator bindingTranslator =
99             new InterceptorBindingTranslator(bundleDescriptor);
100
101         for(Iterator iter = bundleDescriptor.getEjbs().iterator();
102             iter.hasNext();) {
103             EjbDescriptor ejb = (EjbDescriptor) iter.next();
104             if( ejb.getType() != EjbEntityDescriptor.TYPE ) {
105                 ejb.applyInterceptors(bindingTranslator);
106             }
107         }
108     }
109
110     private void handleOverloadedInterceptorMethodBindings(EjbBundleDescriptor
111                                                            bundleDesc) {
112
113         List<InterceptorBindingDescriptor> origBindings =
114             bundleDesc.getInterceptorBindings();
115
116         if( origBindings.isEmpty() ) {
117             return;
118         }
119
120         ClassLoader JavaDoc cl = bundleDesc.getClassLoader();
121
122         List<InterceptorBindingDescriptor> newBindings =
123             new LinkedList<InterceptorBindingDescriptor>();
124
125         for(InterceptorBindingDescriptor next : origBindings) {
126
127             if( next.getNeedsOverloadResolution() ) {
128
129                 MethodDescriptor overloadedMethodDesc =
130                     next.getBusinessMethod();
131                 String JavaDoc methodName = overloadedMethodDesc.getName();
132                 // For method-specific interceptors, there must be an ejb-name.
133
String JavaDoc ejbName = next.getEjbName();
134
135                 EjbDescriptor ejbDesc = bundleDesc.getEjbByName(ejbName);
136                 Class JavaDoc ejbClass = null;
137            
138                 try {
139                     ejbClass = cl.loadClass(ejbDesc.getEjbClassName());
140                 } catch(Exception JavaDoc e) {
141                     RuntimeException JavaDoc re = new RuntimeException JavaDoc
142                         ("Error loading ejb class "+ejbDesc.getEjbClassName());
143                     re.initCause(e);
144                     throw re;
145                 }
146
147                 for(Method JavaDoc ejbClassMethod : ejbClass.getDeclaredMethods()) {
148
149                     if( ejbClassMethod.getName().equals(methodName) ) {
150
151                         InterceptorBindingDescriptor newInterceptorBinding =
152                             new InterceptorBindingDescriptor();
153
154                         MethodDescriptor newMethodDesc = new MethodDescriptor
155                             (ejbClassMethod, MethodDescriptor.EJB_BEAN);
156                         
157                         newInterceptorBinding.setEjbName(ejbName);
158                         newInterceptorBinding.setBusinessMethod
159                             (newMethodDesc);
160                         for(String JavaDoc interceptorClass :
161                                 next.getInterceptorClasses()) {
162                             newInterceptorBinding.appendInterceptorClass
163                                 (interceptorClass);
164                         }
165                         newInterceptorBinding.setIsTotalOrdering
166                             (next.getIsTotalOrdering());
167                         newInterceptorBinding.setExcludeDefaultInterceptors
168                             (next.getExcludeDefaultInterceptors());
169                         newInterceptorBinding.setExcludeClassInterceptors
170                             (next.getExcludeClassInterceptors());
171                         
172                         newBindings.add(newInterceptorBinding);
173
174                     }
175
176                 }
177                 
178
179             } else {
180
181                 newBindings.add(next);
182
183             }
184
185         }
186
187         bundleDesc.setInterceptorBindings(newBindings);
188     }
189
190     /**
191      * visits all entries within the component environment for which
192      * isInjectable() == true.
193      * @param the InjectionCapable environment dependency
194      */

195     public void accept(InjectionCapable injectable) {
196         acceptWithCL(injectable);
197         acceptWithoutCL(injectable);
198     }
199
200     /**
201      * visits an ejb descriptor
202      * @param ejb descriptor
203      */

204     public void accept(EjbDescriptor ejb) {
205
206         this.ejb =ejb;
207         setDOLDefault(ejb);
208         computeRuntimeDefault(ejb);
209
210         try {
211
212             ClassLoader JavaDoc cl = ejb.getEjbBundleDescriptor().getClassLoader();
213             Class JavaDoc ejbClass = cl.loadClass(ejb.getEjbClassName());
214
215             // Perform 2.x style TimedObject processing if the class
216
// hasn't already been identified as a timed object.
217
if( !ejb.isTimedObject() ) {
218
219                 if( javax.ejb.TimedObject JavaDoc.class.isAssignableFrom(ejbClass) ) {
220                     MethodDescriptor timedObjectMethod =
221                         new MethodDescriptor("ejbTimeout",
222                                              "TimedObject timeout method",
223                                              new String JavaDoc[] {"javax.ejb.Timer"},
224                                              MethodDescriptor.EJB_BEAN);
225                     ejb.setEjbTimeoutMethod(timedObjectMethod);
226                 }
227             } else {
228                 // If timeout-method was only processed from the descriptor,
229
// we need to create a MethodDescriptor using the actual
230
// Method object corresponding to the timeout method. The
231
// timeout method can have any access type and be anywhere
232
// in the bean class hierarchy.
233
String JavaDoc timeoutMethodName = ejb.getEjbTimeoutMethod().getName();
234                 MethodDescriptor timeoutMethodDesc = null;
235                 Class JavaDoc nextClass = ejbClass;
236                 while((nextClass != Object JavaDoc.class) && (nextClass != null)
237                       && (timeoutMethodDesc == null) ) {
238                     Method JavaDoc[] methods = nextClass.getDeclaredMethods();
239                     for(Method JavaDoc m : methods) {
240                         if( (m.getName().equals(timeoutMethodName)) ) {
241                             Class JavaDoc[] params = m.getParameterTypes();
242                             if( (params.length == 1) &&
243                                 (params[0] == javax.ejb.Timer JavaDoc.class) ) {
244                                 timeoutMethodDesc = new MethodDescriptor
245                                     (m, MethodDescriptor.EJB_BEAN);
246                                 ejb.setEjbTimeoutMethod(timeoutMethodDesc);
247                                 break;
248                             }
249                         }
250                     }
251                     nextClass = nextClass.getSuperclass();
252                 }
253             }
254
255         } catch(Exception JavaDoc e) {
256             RuntimeException JavaDoc re = new RuntimeException JavaDoc
257                 ("Error processing EjbDescriptor");
258             re.initCause(e);
259             throw re;
260         }
261         
262
263     }
264         
265     public void accept(WebService webService) {
266     }
267
268     /**
269      * visits an ejb reference for the last J2EE component visited
270      * @param the ejb reference
271      */

272     public void accept(EjbReference ejbRef) {
273         DOLUtils.getDefaultLogger().fine("Visiting Ref" + ejbRef);
274     if (ejbRef.getEjbDescriptor()!=null)
275             return;
276
277         //
278
// NOTE : In the 3.0 local/remote business view, the local vs.
279
// remote designation is not always detectable from the interface
280
// itself.
281
//
282
// That means
283
//
284
// 1) we need to figure it out during this stage of the processing
285
// 2) the EjbReferenceDescriptor.isLocal() operations shouldn't be
286
// be used before the post-application validation stage since its
287
// value would be unreliable.
288
// 3) We can't write out the standard deployment descriptors to XML
289
// until the full application has been processed, including this
290
// validation stage.
291
//
292
// During @EJB processing, setLocal() is set to false if
293
// local vs. remote is ambiguous. setLocal() is set to true within this
294
// method upon successfuly resolution to a local business interface.
295
//
296

297         if (ejbRef.getJndiName()!=null && ejbRef.getJndiName().length()!=0) {
298
299
300             // ok this is getting a little complicated here
301
// the jndi name is not null, if this is a remote ref, proceed with resolution
302
// if this is a local ref, proceed with resolution only if ejb-link is null
303
if (!ejbRef.isLocal() || (ejbRef.isLocal() && ejbRef.getLinkName()==null)) {
304                 DOLUtils.getDefaultLogger().fine("Ref " + ejbRef.getName() + " is bound to Ejb with JNDI Name " + ejbRef.getJndiName());
305                 if (getEjbDescriptors() != null) {
306                     for (Iterator iter = getEjbDescriptors().iterator(); iter.hasNext();) {
307                         EjbDescriptor ejb = (EjbDescriptor)iter.next();
308
309                         if (ejbRef.getJndiName().equals(ejb.getJndiName())) {
310                             ejbRef.setEjbDescriptor(ejb);
311                             return;
312                         }
313                     }
314                 }
315             }
316         }
317
318         // If the reference does not have an ejb-link or jndi-name associated
319
// with it, attempt to resolve it by checking against all the ejbs
320
// within the application. If no match is found, just fall through
321
// and let the existing error-checking logic kick in.
322
if (( (ejbRef.getJndiName() == null) ||
323               (ejbRef.getJndiName().length() == 0) )
324             &&
325             ( (ejbRef.getLinkName() == null) ||
326               (ejbRef.getLinkName().length() == 0) )) {
327
328             Map<String JavaDoc, EjbIntfInfo> ejbIntfInfoMap = getEjbIntfMap();
329             if ( ejbIntfInfoMap.size() > 0 ) {
330
331                 String JavaDoc interfaceToMatch = ejbRef.isEJB30ClientView() ?
332                     ejbRef.getEjbInterface() : ejbRef.getEjbHomeInterface();
333
334                 EjbIntfInfo intfInfo = ejbIntfInfoMap.get(interfaceToMatch);
335
336                 // make sure exactly one match
337
if ( intfInfo != null ) {
338                     int numMatches = intfInfo.ejbs.size();
339                     if( numMatches == 1 ) {
340                         Iterator iter = intfInfo.ejbs.iterator();
341
342                         EjbDescriptor target = (EjbDescriptor)iter.next();
343
344                         BundleDescriptor targetModule =
345                             target.getEjbBundleDescriptor();
346                         BundleDescriptor sourceModule =
347                             ejbRef.getReferringBundleDescriptor();
348
349                         //
350
// It's much cleaner to derive the ejb-link value
351
// and set that instead of the descriptor. This way,
352
// if there are multiple ejb-jars within the .ear that
353
// each have an ejb with the target bean's ejb-name,
354
// there won't be any ambiguity about which one is
355
// the correct target. It's not so much a problem
356
// during this phase of the processing, but if the
357
// fully-qualified ejb-link name is required and is not
358
// written out, there could be non-deterministic
359
// behavior when the application is re-loaded.
360
// Let the ejb-link processing logic handle the
361
// conversion to ejb descriptor.
362
//
363

364                         // If the ejb reference and the target ejb are defined
365
// within the same ejb-jar, the ejb-link will only
366
// be set to ejb-name. This is done regardless of
367
// whether the ejb-jar is within an .ear or is
368
// stand-alone. The ejb-link processing
369
// logic will always check the current ejb-jar
370
// first so there won't be any ambiguity.
371
String JavaDoc ejbLinkName = target.getName();
372                         if( sourceModule != targetModule ) {
373
374                             // Since there are at least two modules, we
375
// must be within an application.
376
String JavaDoc relativeUri = getApplication().
377                                 getRelativeUri(sourceModule, targetModule);
378                             ejbLinkName = relativeUri + "#" + ejbLinkName;
379                         }
380
381                         ejbRef.setLinkName(ejbLinkName);
382
383                     } else {
384                         String JavaDoc msg = "Cannot resolve reference " + ejbRef +
385                             " because there are " + numMatches + " ejbs " +
386                             " in the application with interface " +
387                             interfaceToMatch;
388
389                         DOLUtils.getDefaultLogger().severe(msg);
390                         throw new RuntimeException JavaDoc(msg);
391                     }
392                 }
393             }
394         }
395
396         // now all cases fall back here, we need to resolve through the link-name
397
if (ejbRef.getLinkName()==null) {
398
399
400             // if no link name if present, and this is a local ref, this is always an
401
// error because we must resolve all local refs and we cannot resolve it
402
// throw either the jndi name or the link name
403
if (ejbRef.isLocal()) {
404                 DOLUtils.getDefaultLogger().severe("Cannot resolve reference " + ejbRef);
405                 throw new RuntimeException JavaDoc("Cannot resolve reference " + ejbRef);
406             } else {
407                 // this is a remote interface, jndi will eventually contain the referenced
408
// ejb ref, apply default jndi name if there is none
409
if (ejbRef.getJndiName() == null ||
410                         ejbRef.getJndiName().length() == 0) {
411                     String JavaDoc jndiName = getDefaultEjbJndiName(
412                         ejbRef.isEJB30ClientView() ?
413                         ejbRef.getEjbInterface() : ejbRef.getEjbHomeInterface());
414                     ejbRef.setJndiName(jndiName);
415                     DOLUtils.getDefaultLogger().fine("Applying default to ejb reference: " + ejbRef);
416                 }
417
418                 return;
419             }
420         }
421         
422         // Beginning of ejb-link resolution
423

424         // save anticipated types for checking if interfaces are compatible
425
String JavaDoc homeClassName = ejbRef.getEjbHomeInterface();
426         String JavaDoc intfClassName = ejbRef.getEjbInterface();
427
428         // save anticipated type for checking if bean type is compatible
429
String JavaDoc type = ejbRef.getType();
430         
431         EjbDescriptor ejbReferee=null;
432             
433         String JavaDoc linkName = ejbRef.getLinkName();
434         int ind = linkName.lastIndexOf('#');
435         if ( ind != -1 ) {
436             // link has a relative path from referring EJB JAR,
437
// of form "../products/product.jar#ProductEJB"
438
String JavaDoc ejbName = linkName.substring(ind+1);
439             String JavaDoc jarPath = linkName.substring(0, ind);
440             BundleDescriptor referringJar = ejbRef.getReferringBundleDescriptor();
441             if (referringJar==null) {
442                 ejbRef.setReferringBundleDescriptor(getBundleDescriptor());
443                 referringJar = getBundleDescriptor();
444             }
445             
446             if (getApplication()!=null) {
447                 BundleDescriptor refereeJar =
448                     getApplication().getRelativeBundle(referringJar, jarPath);
449                 if( (refereeJar != null) &&
450                     refereeJar instanceof EjbBundleDescriptor ) {
451                     // this will throw an exception if ejb is not found
452
ejbReferee =
453                        ((EjbBundleDescriptor)refereeJar).getEjbByName(ejbName);
454                 }
455             }
456         }
457         else {
458
459             // Handle an unqualified ejb-link, which is just an ejb-name.
460

461             // If we're in an application and currently processing an
462
// ejb-reference defined within an ejb-jar, first check
463
// the current ejb-jar for an ejb-name match. From a spec
464
// perspective, the deployer can't depend on this behavior,
465
// but it's still better to have deterministic results. In
466
// addition, in the case of automatic-linking, the fully-qualified
467
// "#" ejb-link syntax is not used when the ejb reference and
468
// target ejb are within the same ejb-jar. Checking the
469
// ejb-jar first will ensure the correct linking behavior for
470
// that case.
471
if ( (getApplication() != null) && (ejbBundleDescriptor != null)
472                  && ejbBundleDescriptor.hasEjbByName(linkName) ) {
473
474                 ejbReferee = ejbBundleDescriptor.getEjbByName(linkName);
475
476             } else if ( (getApplication() != null) &&
477                         getApplication().hasEjbByName(linkName)) {
478                 
479                 ejbReferee =
480                     getApplication().getEjbByName(ejbRef.getLinkName());
481                     
482             } else if (ejb!=null) {
483                 try {
484                     ejbReferee = ejb.getEjbBundleDescriptor().getEjbByName(ejbRef.getLinkName());
485                 } catch (IllegalArgumentException JavaDoc e) {
486                     // this may happen when we have no application and the ejb ref
487
// cannot be resolved to a ejb in the bundle. The ref will
488
// probably be resolved when the application is assembled.
489
DOLUtils.getDefaultLogger().warning("Unresolved <ejb-link>: "+linkName);
490                     return;
491                 }
492                     
493             }
494         }
495
496         if (ejbReferee==null)
497         {
498
499             // we could not resolve through the ejb-link. if this is a local ref, this
500
// is an error, if this is a remote ref, this should be also an error at
501
// runtime but maybe the jndi name will be specified by deployer so
502
// a warning should suffice
503
if (ejbRef.isLocal()) {
504                 DOLUtils.getDefaultLogger().severe("Unresolved <ejb-link>: "+linkName);
505                 throw new RuntimeException JavaDoc("Error: Unresolved <ejb-link>: "+linkName);
506             } else {
507                 DOLUtils.getDefaultLogger().warning("Unresolved <ejb-link>: "+linkName);
508                 return;
509             }
510         } else {
511
512             if( ejbRef.isEJB30ClientView() ) {
513
514                 BundleDescriptor referringBundle =
515                     ejbRef.getReferringBundleDescriptor();
516
517                 // If we can verify that the current ejb 3.0 reference is defined
518
// in any Application Client module or in a stand-alone web module
519
// it must be remote business.
520
if( ( (referringBundle == null) && (ejbBundleDescriptor == null) )
521                     ||
522                     (referringBundle instanceof ApplicationClientDescriptor)
523                     ||
524                     ( (getApplication() == null) &&
525                       (referringBundle instanceof WebBundleDescriptor) ) ) {
526
527                     ejbRef.setLocal(false);
528
529                     // Double-check that target has a remote business interface of this
530
// type. This will handle the common error case that the target
531
// EJB has intended to support a remote business interface but
532
// has not used @Remote to specify it, in which case
533
// the interface was assigned the default of local business.
534

535                     if( !ejbReferee.getRemoteBusinessClassNames().contains
536                         (intfClassName) ) {
537                         String JavaDoc msg = "Target ejb " + ejbReferee.getName() + " for " +
538                             " remote ejb 3.0 reference " + ejbRef.getName() +
539                             " does not expose a remote business interface of type " +
540                             intfClassName;
541                         throw new RuntimeException JavaDoc(msg);
542                     }
543
544                 } else if(ejbReferee.getLocalBusinessClassNames().
545                          contains(intfClassName)) {
546
547                     ejbRef.setLocal(true);
548
549                 } else if(ejbReferee.getRemoteBusinessClassNames().
550                           contains(intfClassName)) {
551
552                     ejbRef.setLocal(false);
553
554                 } else {
555                     String JavaDoc msg = "Warning : Unable to determine local " +
556                         " business vs. remote business designation for " +
557                         " EJB 3.0 ref " + ejbRef;
558                     throw new RuntimeException JavaDoc(msg);
559                 }
560             }
561
562             ejbRef.setEjbDescriptor(ejbReferee);
563         }
564         
565         // if we are here, we must have resolved the reference
566

567     if(DOLUtils.getDefaultLogger().isLoggable(Level.FINE)) {
568             DOLUtils.getDefaultLogger().fine("Done Visiting " + ejb.getName() + " reference " + ejbRef);
569     }
570
571         // check that declared types are compatible with expected values
572
// if there is a target ejb descriptor available
573
if( ejbReferee != null ) {
574
575             if( ejbRef.isEJB30ClientView() ) {
576
577                 Set<String JavaDoc> targetBusinessIntfs = ejbRef.isLocal() ?
578                     ejbReferee.getLocalBusinessClassNames() :
579                     ejbReferee.getRemoteBusinessClassNames();
580
581                 if( !targetBusinessIntfs.contains(intfClassName) ) {
582
583                     DOLUtils.getDefaultLogger().log(Level.WARNING,
584                        "enterprise.deployment.backend.ejbRefTypeMismatch",
585                        new Object JavaDoc[] {ejbRef.getName() , intfClassName,
586                        ejbReferee.getName(), ( ejbRef.isLocal() ?
587                        "Local Business" : "Remote Business"),
588                                          targetBusinessIntfs.toString()});
589
590                     // We can only figure out what the correct type should be
591
// if there is only 1 target remote/local business intf.
592
if( targetBusinessIntfs.size() == 1 ) {
593                         Iterator iter = targetBusinessIntfs.iterator();
594                         ejbRef.setEjbInterface((String JavaDoc)iter.next());
595                     }
596                 }
597
598             } else {
599
600                 String JavaDoc targetHome = ejbRef.isLocal() ?
601                     ejbReferee.getLocalHomeClassName() :
602                     ejbReferee.getHomeClassName();
603
604                 if( !homeClassName.equals(targetHome) ) {
605
606                     DOLUtils.getDefaultLogger().log(Level.WARNING,
607                        "enterprise.deployment.backend.ejbRefTypeMismatch",
608                        new Object JavaDoc[] {ejbRef.getName() , homeClassName,
609                        ejbReferee.getName(), ( ejbRef.isLocal() ?
610                        "Local Home" : "Remote Home"), targetHome});
611
612                     if( targetHome != null ) {
613                         ejbRef.setEjbHomeInterface(targetHome);
614                     }
615                 }
616
617                 String JavaDoc targetComponentIntf = ejbRef.isLocal() ?
618                     ejbReferee.getLocalClassName() :
619                     ejbReferee.getRemoteClassName();
620
621                 // In some cases for 2.x style @EJBs that point to Entity beans
622
// the interface class cannot be derived, so only do the
623
// check if the intf is known.
624
if( (intfClassName != null) &&
625                     !intfClassName.equals(targetComponentIntf) ) {
626
627                     DOLUtils.getDefaultLogger().log(Level.WARNING,
628                        "enterprise.deployment.backend.ejbRefTypeMismatch",
629                        new Object JavaDoc[] {ejbRef.getName() , intfClassName,
630                        ejbReferee.getName(), ( ejbRef.isLocal() ?
631                        "Local" : "Remote"), targetComponentIntf});
632
633                     if( targetComponentIntf != null ) {
634                         ejbRef.setEjbInterface(targetComponentIntf);
635                     }
636                 }
637             }
638         }
639
640         if (!type.equals(ejbRef.getType())) {
641             DOLUtils.getDefaultLogger().log(Level.WARNING, "enterprise.deployment.backend.invalidDescriptorMappingFailure",
642             new Object JavaDoc[] {linkName , ejbRef.getType()});
643
644             ejbRef.setType(ejbRef.getType());
645
646         }
647     }
648
649     public void accept(ResourceReferenceDescriptor resRef) {
650         computeRuntimeDefault(resRef);
651     }
652
653     public void accept(JmsDestinationReferenceDescriptor jmsDestRef) {
654         computeRuntimeDefault(jmsDestRef);
655     }
656
657     public void accept(MessageDestinationReferenceDescriptor msgDestRef) {
658         computeRuntimeDefault(msgDestRef);
659     }
660
661     public void accept(MessageDestinationDescriptor msgDest) {
662         computeRuntimeDefault(msgDest);
663     }
664
665     /**
666      * Returns a map of interface name -> EjbIntfInfo based on all the ejbs
667      * within the application or stand-alone module. Only RemoteHome,
668      * RemoteBusiness, LocalHome, and LocalBusiness are eligible for map.
669      */

670     private Map<String JavaDoc, EjbIntfInfo> getEjbIntfMap() {
671
672         Collection ejbs = getEjbDescriptors();
673
674         Map<String JavaDoc, EjbIntfInfo> intfInfoMap=new HashMap<String JavaDoc, EjbIntfInfo>();
675
676         for(Iterator iter = ejbs.iterator(); iter.hasNext();) {
677             EjbDescriptor next = (EjbDescriptor) iter.next();
678             
679             if( next.isRemoteInterfacesSupported() ) {
680                 addIntfInfo(intfInfoMap, next.getHomeClassName(),
681                             EjbIntfType.REMOTE_HOME, next);
682             }
683
684             if( next.isRemoteBusinessInterfacesSupported() ) {
685                 for(String JavaDoc nextIntf : next.getRemoteBusinessClassNames()) {
686                     addIntfInfo(intfInfoMap, nextIntf,
687                                 EjbIntfType.REMOTE_BUSINESS, next);
688                 }
689             }
690
691             if( next.isLocalInterfacesSupported() ) {
692                 addIntfInfo(intfInfoMap, next.getLocalHomeClassName(),
693                             EjbIntfType.LOCAL_HOME, next);
694             }
695
696             if( next.isLocalBusinessInterfacesSupported() ) {
697                 for(String JavaDoc nextIntf : next.getLocalBusinessClassNames()) {
698                     addIntfInfo(intfInfoMap, nextIntf,
699                                 EjbIntfType.LOCAL_BUSINESS, next);
700                 }
701             }
702
703         }
704
705         return intfInfoMap;
706     }
707     
708     private void addIntfInfo(Map<String JavaDoc, EjbIntfInfo> intfInfoMap,
709                              String JavaDoc intf, EjbIntfType intfType,
710                              EjbDescriptor ejbDesc) {
711
712         EjbIntfInfo intfInfo = intfInfoMap.get(intf);
713         if( intfInfo == null ) {
714             EjbIntfInfo newInfo = new EjbIntfInfo();
715             newInfo.ejbs = new HashSet<EjbDescriptor>();
716             newInfo.ejbs.add(ejbDesc);
717             newInfo.intfType = intfType;
718             intfInfoMap.put(intf, newInfo);
719         } else {
720             intfInfo.ejbs.add(ejbDesc);
721             // Since there's more than one match, reset intf type.
722
intfInfo.intfType = EjbIntfType.NONE;
723         }
724
725     }
726
727     /**
728      * @return a vector of EjbDescriptor for this bundle
729      */

730     protected Collection getEjbDescriptors() {
731         if (getApplication() != null) {
732             return getApplication().getEjbDescriptors();
733         } else if (ejbBundleDescriptor!=null) {
734             return ejbBundleDescriptor.getEjbs();
735         } else {
736             return new HashSet();
737         }
738     }
739     
740     /**
741      * @return the Application object if any
742      */

743     protected Application getApplication() {
744         return null;
745     }
746      
747     /**
748      * @return the bundleDescriptor we are validating
749      */

750     protected BundleDescriptor getBundleDescriptor() {
751         return ejbBundleDescriptor;
752     }
753
754     /**
755      * Set a default RunAs principal to given RunAsIdentityDescriptor
756      * if necessary.
757      * @param runAs
758      * @param application
759      * @exception RuntimeException
760      */

761     protected void computeRunAsPrincipalDefault(RunAsIdentityDescriptor runAs,
762             Application application) {
763
764         // for backward compatibile
765
if (runAs != null &&
766                 (runAs.getRoleName() == null ||
767                     runAs.getRoleName().length() == 0)) {
768             DOLUtils.getDefaultLogger().log(Level.WARNING,
769             "enterprise.deployment.backend.emptyRoleName");
770             return;
771         }
772         
773         if (runAs != null &&
774                 (runAs.getPrincipal() == null ||
775                     runAs.getPrincipal().length() == 0) &&
776                 application != null && application.getRoleMapper() != null) {
777
778             String JavaDoc principalName = null;
779             String JavaDoc roleName = runAs.getRoleName();
780
781             final Subject JavaDoc fs = (Subject JavaDoc)application.getRoleMapper().getRoleToSubjectMapping().get(roleName);
782             if (fs != null) {
783                 principalName = (String JavaDoc)AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
784                     public Object JavaDoc run() {
785                         Set<Principal JavaDoc> pset = fs.getPrincipals();
786                         Principal JavaDoc prin = null;
787                         if (pset.size() > 0) {
788                             prin = (Principal JavaDoc)pset.iterator().next();
789                             DOLUtils.getDefaultLogger().log(Level.WARNING,
790                             "enterprise.deployment.backend.computeRunAsPrincipal",
791                             new Object JavaDoc[] { prin.getName() });
792                         }
793                         return (prin != null) ? prin.getName() : null;
794                     }
795                 });
796             }
797
798             if (principalName == null || principalName.length() == 0) {
799                 throw new RuntimeException JavaDoc("The RunAs role " + "\"" + roleName + "\"" +
800                     " is not mapped to a principal.");
801             }
802             runAs.setPrincipal(principalName);
803         }
804     }
805
806     /**
807      * Set default value for EjbDescriptor.
808      */

809     private void setDOLDefault(EjbDescriptor ejb) {
810         if (ejb.getUsesCallerIdentity() == null) {
811             if (ejb instanceof EjbMessageBeanDescriptor) {
812                 ejb.setUsesCallerIdentity(false);
813             } else {
814                 ejb.setUsesCallerIdentity(true);
815             }
816         }
817         // for ejb 3.0
818
if (ejb.getTransactionType() == null) {
819             ejb.setTransactionType(EjbDescriptor.CONTAINER_TRANSACTION_TYPE);
820         }
821         ejb.setUsesDefaultTransaction();
822     }
823
824     /**
825      * Set runtime default value for EjbDescriptor.
826      */

827     private void computeRuntimeDefault(EjbDescriptor ejb) {
828         String JavaDoc intfName = null;
829
830         if ((ejb.getJndiName() == null) || (ejb.getJndiName().length() == 0)) {
831             if (ejb.isRemoteInterfacesSupported() && ejb.isRemoteBusinessInterfacesSupported()) {
832                  // can't use a default.
833
} else if (ejb.isRemoteInterfacesSupported()) {
834                  // For 2.x view, use the Home as the basis for the default
835
intfName = ejb.getHomeClassName();
836             } else if (ejb.isRemoteBusinessInterfacesSupported()) {
837                  Set<String JavaDoc> classNames = ejb.getRemoteBusinessClassNames();
838                  if (classNames.size() == 1) {
839                      intfName = (String JavaDoc)classNames.iterator().next();
840                  }
841             }
842         }
843
844         if( intfName != null ) {
845             String JavaDoc jndiName = getDefaultEjbJndiName(intfName);
846             ejb.setJndiName(jndiName);
847         }
848
849         if (!ejb.getUsesCallerIdentity()) {
850             computeRunAsPrincipalDefault(
851                 ejb.getRunAsIdentity(), ejb.getApplication());
852         }
853     }
854
855     /**
856      * Set runtime default value for ResourceReferenceDescriptor.
857      */

858     private void computeRuntimeDefault(ResourceReferenceDescriptor resRef) {
859         if (resRef.getJndiName() == null ||
860                 resRef.getJndiName().length() == 0) {
861             resRef.setJndiName(getDefaultResourceJndiName(resRef.getName()));
862         }
863     }
864
865     /**
866      * Set runtime default value for JmsDestinationReferenceDescriptor.
867      */

868     private void computeRuntimeDefault(JmsDestinationReferenceDescriptor jmsDestRef) {
869         if (jmsDestRef.getJndiName() == null ||
870                 jmsDestRef.getJndiName().length() == 0) {
871             jmsDestRef.setJndiName(getDefaultResourceJndiName(jmsDestRef.getName()));
872         }
873     }
874     
875     /**
876      * Set runtime default value for MessageDestinationReferenceDescriptor.
877      */

878     private void computeRuntimeDefault(MessageDestinationReferenceDescriptor msgDestRef) {
879         if (msgDestRef.getJndiName() == null ||
880                 msgDestRef.getJndiName().length() == 0) {
881             msgDestRef.setJndiName(getDefaultResourceJndiName(msgDestRef.getName()));
882         }
883     }
884
885     /**
886      * Set runtime default value for MessageDestinationDescriptor.
887      */

888     private void computeRuntimeDefault(MessageDestinationDescriptor msgDest) {
889         if (msgDest.getJndiName() == null ||
890                 msgDest.getJndiName().length() == 0) {
891             msgDest.setJndiName(getDefaultResourceJndiName(msgDest.getName()));
892         }
893     }
894
895     /**
896      * @param resName
897      * @return default jndi name for a given interface resource name
898      */

899     private String JavaDoc getDefaultResourceJndiName(String JavaDoc resName) {
900         return resName;
901     }
902
903     /**
904      * @param intfName
905      * @return default jndi name for a given interface name
906      */

907     //XXX this is first implementation. It does not handle two ejb with same
908
// interface in different jar
909
private String JavaDoc getDefaultEjbJndiName(String JavaDoc intfName) {
910         return intfName;
911     }
912
913     private enum EjbIntfType {
914         NONE,
915         REMOTE_HOME,
916         REMOTE_BUSINESS,
917         LOCAL_HOME,
918         LOCAL_BUSINESS
919     }
920
921     private static class EjbIntfInfo {
922
923         Set<EjbDescriptor> ejbs;
924
925         // Only set when there is one ejb in the set.
926
// Otherwise, value = NONE
927
EjbIntfType intfType;
928     }
929     
930 }
931
Popular Tags