KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openejb > alt > assembler > classic > AssemblerTool


1 /**
2  * Redistribution and use of this software and associated documentation
3  * ("Software"), with or without modification, are permitted provided
4  * that the following conditions are met:
5  *
6  * 1. Redistributions of source code must retain copyright
7  * statements and notices. Redistributions must also contain a
8  * copy of this document.
9  *
10  * 2. Redistributions in binary form must reproduce the
11  * above copyright notice, this list of conditions and the
12  * following disclaimer in the documentation and/or other
13  * materials provided with the distribution.
14  *
15  * 3. The name "Exolab" must not be used to endorse or promote
16  * products derived from this Software without prior written
17  * permission of Exoffice Technologies. For written permission,
18  * please contact info@exolab.org.
19  *
20  * 4. Products derived from this Software may not be called "Exolab"
21  * nor may "Exolab" appear in their names without prior written
22  * permission of Exoffice Technologies. Exolab is a registered
23  * trademark of Exoffice Technologies.
24  *
25  * 5. Due credit should be given to the Exolab Project
26  * (http://www.exolab.org/).
27  *
28  * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32  * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39  * OF THE POSSIBILITY OF SUCH DAMAGE.
40  *
41  * Copyright 1999 (C) Exoffice Technologies Inc. All Rights Reserved.
42  *
43  * $Id: AssemblerTool.java 2080 2005-08-16 01:05:03Z dblevins $
44  */

45 package org.openejb.alt.assembler.classic;
46
47 import org.openejb.Container;
48 import org.openejb.OpenEJBException;
49 import org.openejb.core.ContainerSystem;
50 import org.openejb.core.DeploymentInfo;
51 import org.openejb.spi.SecurityService;
52 import org.openejb.spi.TransactionService;
53 import org.openejb.util.Messages;
54 import org.openejb.util.SafeToolkit;
55 import org.openejb.util.proxy.ProxyFactory;
56 import org.openejb.util.proxy.ProxyManager;
57
58 import javax.naming.InitialContext JavaDoc;
59 import javax.resource.spi.ConnectionManager JavaDoc;
60 import javax.resource.spi.ManagedConnectionFactory JavaDoc;
61 import java.lang.reflect.Method JavaDoc;
62 import java.util.HashMap JavaDoc;
63 import java.util.HashSet JavaDoc;
64 import java.util.List JavaDoc;
65 import java.util.Properties JavaDoc;
66 import java.util.Vector JavaDoc;
67
68 /**
69  * This class provides a set of utility methods for constructing various artifacts
70  * in the container system from org.openejb.alt.assembler.classic configuration classes.
71  * <p/>
72  * This class is used as an independent tool or is extended to create specialized
73  * assemblers as is the case with the org.openejb.alt.assembler.classic.Assembler which bootstraps
74  * the core container system extracting the configuration from a single XML file and
75  * building the container system from a complete graph of conf objects.
76  * <p/>
77  * The methods in this class are not interdependent and other then a SafeToolKit
78  * variable they are stateless (the class has no instance variables).
79  *
80  * @author <a HREF="mailto:david.blevins@visi.com">David Blevins</a>
81  * @author <a HREF="mailto:Richard@Monson-Haefel.com">Richard Monson-Haefel</a>
82  * @see org.openejb.alt.assembler.classic.Assembler
83  * @see org.openejb.spi.Assembler
84  * @see OpenEjbConfigurationFactory
85  */

86 public class AssemblerTool {
87
88     public static final Class JavaDoc PROXY_FACTORY = org.openejb.util.proxy.ProxyFactory.class;
89     public static final Class JavaDoc SECURITY_SERVICE = org.openejb.spi.SecurityService.class;
90     public static final Class JavaDoc TRANSACTION_SERVICE = org.openejb.spi.TransactionService.class;
91     public static final Class JavaDoc CONNECTION_MANAGER = javax.resource.spi.ConnectionManager JavaDoc.class;
92     public static final Class JavaDoc CONNECTOR = javax.resource.spi.ManagedConnectionFactory JavaDoc.class;
93
94     /**
95      * A mutable static field could be changed by malicious code or by accident from another package. The field could be made final to avoid this vulnerability.
96      */

97     protected static final Messages messages = new Messages("org.openejb.util.resources");
98     protected static final SafeToolkit toolkit = SafeToolkit.getToolkit("AssemblerTool");
99     protected static final HashMap JavaDoc codebases = new HashMap JavaDoc();
100
101     protected Properties JavaDoc props;
102
103     static {
104         ClassLoader JavaDoc cl = ClassLoader.getSystemClassLoader();
105         codebases.put("CLASSPATH", cl);
106
107         System.setProperty("noBanner", "true");
108     }
109
110     /**
111      * When given a complete ContainerSystemInfo object, this method,
112      * will construct all the containers (entity, stateful, stateless)
113      * and add those containers to the ContainerSystem. The containers
114      * are constructed using the assembleContainer() method. Once constructed
115      * the container and its deployments are added to the container system.
116      *
117      * @param containerSystem the system to which the container should be added.
118      * @param containerSystemInfo defines the contain system,its containers, and deployments.
119      * @throws Exception if there was a problem constructing the ContainerManager.
120      * @throws Exception
121      * @see org.openejb.core.ContainerSystem
122      * @see ContainerManagerInfo
123      */

124     public void assembleContainers(ContainerSystem containerSystem, ContainerSystemInfo containerSystemInfo) throws Exception JavaDoc {
125
126         ContainerBuilder containerBuilder = new ContainerBuilder(containerSystemInfo, this.props);
127         List JavaDoc containers = (List JavaDoc) containerBuilder.build();
128         for (int i = 0; i < containers.size(); i++) {
129             Container container = (Container) containers.get(i);
130             containerSystem.addContainer(container.getContainerID(), container);
131             org.openejb.DeploymentInfo[] deployments = container.deployments();
132             for (int j = 0; j < deployments.length; j++) {
133                 containerSystem.addDeployment((org.openejb.core.DeploymentInfo) deployments[j]);
134             }
135         }
136     }
137
138     /*
139     TODO: The Exception Handling here isn't up-to-date and doesn't
140     use a message number. Message numbers allow the message text to
141     be internationalized.
142     */

143     public InitialContext JavaDoc assembleRemoteJndiContext(JndiContextInfo context)
144             throws org.openejb.OpenEJBException {
145         try {
146             InitialContext JavaDoc ic = new InitialContext JavaDoc(context.properties);
147             return ic;
148         } catch (javax.naming.NamingException JavaDoc ne) {
149             //FIXME Log this
150
// not a super serious error but assemble should be stoped.
151
throw new org.openejb.OpenEJBException("The remote JNDI EJB references for remote-jndi-contexts = " + context.jndiContextId + "+ could not be resolved.", ne);
152         }
153     }
154
155     /**
156      * This class will assemble a ConnectionManager instace from a ConnectionManagerInfo
157      * configuration object.
158      *
159      * @param cmInfo describes the ConnectionManager to be assembled.
160      * @return the ConnectionManager instance assembled.
161      * @see org.openejb.alt.assembler.classic.ConnectionManagerInfo
162      */

163     public ConnectionManager JavaDoc assembleConnectionManager(ConnectionManagerInfo cmInfo)
164             throws OpenEJBException, java.lang.Exception JavaDoc {
165         /*TODO: Add better exception handling, this method throws java.lang.Exception,
166          which is not very specific. Only a very specific OpenEJBException should be
167          thrown.
168          */

169         Class JavaDoc managerClass = SafeToolkit.loadClass(cmInfo.className, cmInfo.codebase);
170
171         checkImplementation(CONNECTION_MANAGER, managerClass, "ConnectionManager", cmInfo.connectionManagerId);
172
173         ConnectionManager JavaDoc connectionManager = (ConnectionManager JavaDoc) toolkit.newInstance(managerClass);
174
175         // a container manager has either properties or configuration information or nothing at all
176
if (cmInfo.properties != null) {
177             Properties JavaDoc clonedProps = (Properties JavaDoc) (this.props.clone());
178             clonedProps.putAll(cmInfo.properties);
179             applyProperties(connectionManager, clonedProps);
180         }
181
182         return connectionManager;
183     }
184
185     /**
186      * This method will assemble a ManagedConnectionFactory instance from a
187      * ManagedConnecitonFactoryInfo configuration object.
188      *
189      * @param mngedConFactInfo describes the the ManagedConnectionFactory to be created.
190      * @return the ManagedConnecitonFactory assembled.
191      * @see org.openejb.alt.assembler.classic.ManagedConnectionFactoryInfo
192      */

193     public ManagedConnectionFactory JavaDoc assembleManagedConnectionFactory(ManagedConnectionFactoryInfo mngedConFactInfo)
194             throws org.openejb.OpenEJBException, java.lang.Exception JavaDoc {
195
196         ManagedConnectionFactory JavaDoc managedConnectionFactory = null;
197         try {
198             Class JavaDoc factoryClass = SafeToolkit.loadClass(mngedConFactInfo.className, mngedConFactInfo.codebase);
199             checkImplementation(CONNECTOR, factoryClass, "Connector", mngedConFactInfo.id);
200
201             managedConnectionFactory = (ManagedConnectionFactory JavaDoc) toolkit.newInstance(factoryClass);
202         } catch (Exception JavaDoc e) {
203             throw new OpenEJBException("Could not instantiate Connector '" + mngedConFactInfo.id + "'.", e);
204         }
205
206
207         try {
208             // a ManagedConnectionFactory has either properties or configuration information or nothing at all
209
if (mngedConFactInfo.properties != null) {
210                 Properties JavaDoc clonedProps = (Properties JavaDoc) (this.props.clone());
211                 clonedProps.putAll(mngedConFactInfo.properties);
212                 applyProperties(managedConnectionFactory, clonedProps);
213             }
214         } catch (java.lang.reflect.InvocationTargetException JavaDoc ite) {
215             throw new OpenEJBException("Could not initialize Connector '" + mngedConFactInfo.id + "'.", ite.getTargetException());
216         } catch (Exception JavaDoc e) {
217             //e.printStackTrace();
218
throw new OpenEJBException("Could not initialize Connector '" + mngedConFactInfo.id + "'.", e);
219         }
220
221         return managedConnectionFactory;
222     }
223
224     /**
225      * This method assembles the SecurityService from the SecuirtyServiceInfo
226      * configuration object.
227      *
228      * @param securityInfo describes the SecurityService to be assembled.
229      * @return the SecurityService object that was assembled.
230      * @see org.openejb.alt.assembler.classic.SecurityServiceInfo
231      */

232     public SecurityService assembleSecurityService(SecurityServiceInfo securityInfo)
233             throws org.openejb.OpenEJBException, java.lang.Exception JavaDoc {
234         /*TODO: Add better exception handling, this method throws java.lang.Exception,
235          which is not very specific. Only a very specific OpenEJBException should be
236          thrown.
237          */

238         Class JavaDoc serviceClass = SafeToolkit.loadClass(securityInfo.factoryClassName, securityInfo.codebase);
239
240         checkImplementation(SECURITY_SERVICE, serviceClass, "SecurityService", securityInfo.serviceName);
241
242         SecurityService securityService = (SecurityService) toolkit.newInstance(serviceClass);
243
244         // a SecurityService has either properties or configuration information or nothing at all
245
if (securityInfo.properties != null)
246             applyProperties(securityService, securityInfo.properties);
247
248         return securityService;
249     }
250
251     /**
252      * This method assembles the TransactionManager from the TransactionServiceInfo
253      * configuration object.
254      *
255      * @param txInfo describes the TransactionService to be assembled. The Transaction
256      * manager is obtained from this service.
257      * @return the TranactionManager instance that was obtained from the assembled TransactionService
258      * @see org.openejb.alt.assembler.classic.TransactionServiceInfo
259      */

260     public javax.transaction.TransactionManager JavaDoc assembleTransactionManager(TransactionServiceInfo txInfo)
261             throws org.openejb.OpenEJBException, java.lang.Exception JavaDoc {
262         /*TODO: Add better exception handling, this method throw java.lang.Exception,
263          which is not very specific. If something is wrong, we should at least say
264          "Cannot initialize the TransactionManager, because X happened."
265          */

266
267         Class JavaDoc serviceClass = SafeToolkit.loadClass(txInfo.factoryClassName, txInfo.codebase);
268
269         checkImplementation(TRANSACTION_SERVICE, serviceClass, "TransactionService", txInfo.serviceName);
270
271         TransactionService txService = (TransactionService) toolkit.newInstance(serviceClass);
272
273         // a TransactionService has either properties or configuration information or nothing at all
274
if (txInfo.properties != null)
275             applyProperties(txService, txInfo.properties);
276
277
278         // TransactionManagerWrapper must be used to allow proper synchronization by ConnectionManager and persistence manager.
279
// See org.openejb.core.TransactionManagerWrapper for details.
280
return (javax.transaction.TransactionManager JavaDoc) (new org.openejb.core.TransactionManagerWrapper(txService.getTransactionManager()));
281     }
282
283     /**
284      * This method constructs a ProxyFactory from teh IntraVmServerInfo conf class and automatically
285      * registers that ProxyFactory with the ProxyManager as the default proxy.
286      * Because of interedependices that require a proxy to be in place (specifically the creation of
287      * the OpenEJB JNDI global name space in the org.openejb.core.ContainerSystem class, this method
288      * should be processed before anything else is done in the deployment process.
289      *
290      * @param ivmInfo the IntraVmServerInfo configuration object that describes the ProxyFactory
291      * @see org.openejb.alt.assembler.classic.IntraVmServerInfo
292      */

293     public void applyProxyFactory(IntraVmServerInfo ivmInfo) throws OpenEJBException {
294         Class JavaDoc factoryClass = SafeToolkit.loadClass(ivmInfo.proxyFactoryClassName, ivmInfo.codebase);
295
296         checkImplementation(PROXY_FACTORY, factoryClass, "ProxyFactory", ivmInfo.factoryName);
297
298         ProxyFactory factory = (ProxyFactory) toolkit.newInstance(factoryClass);
299
300         factory.init(ivmInfo.properties);
301         ProxyManager.registerFactory("ivm_server", factory);
302         ProxyManager.setDefaultFactory("ivm_server");
303
304     }
305
306     /**
307      * This method will automatically attempt to invoke an init(Properties )
308      * method on the target object, passing in the properties and an argument.
309      *
310      * @param target the object that will have its init(Properties) method invoked
311      * @param props
312      * @throws java.lang.reflect.InvocationTargetException
313      *
314      * @throws java.lang.IllegalAccessException
315      *
316      * @throws java.lang.NoSuchMethodException
317      *
318      */

319     public void applyProperties(Object JavaDoc target, Properties JavaDoc props)
320             throws java.lang.reflect.InvocationTargetException JavaDoc,
321             java.lang.IllegalAccessException JavaDoc, java.lang.NoSuchMethodException JavaDoc {
322         if (props != null /*&& props.size()>0*/) {
323             Method JavaDoc method = target.getClass().getMethod("init", new Class JavaDoc[]{Properties JavaDoc.class});
324             method.invoke(target, new Object JavaDoc[]{props});
325         }
326     }
327
328     /**
329      * This method applies the transaction attributed described by the collection of MethodTransactionInfo
330      * object to the org.openejb.core.DeploymentInfo objects. This method maps every method of the bean's
331      * remote and home interfaces (including remove() methods) to their assigned transaction attributes and
332      * then applies these mappings to the bean through the DeploymentInfo.setMethodTransationAttribute().
333      * At run time the container will get the transaction attribute associated with a client call from the
334      * DeploymentInfo object by invoking its getTransactionAttribute(Method) method.
335      * See page 251 EJB 1.1 for an explanation of the method attribute.
336      *
337      * @param deploymentInfo the deployment to which the transaction attributes are applied
338      * @param mtis describes the transaction attributes for the enterprise bean(s)
339      * @see org.openejb.alt.assembler.classic.MethodTransactionInfo
340      */

341     public void applyTransactionAttributes(DeploymentInfo deploymentInfo, MethodTransactionInfo[] mtis) {
342         /*TODO: Add better exception handling. This method doesn't throws any exceptions!!
343          there is a lot of complex code here, I'm sure something could go wrong the user
344          might want to know about.
345          */

346         for (int i = 0; i < mtis.length; i++) {
347             MethodTransactionInfo transInfo = mtis[i];
348             MethodInfo[] mis = transInfo.methods;
349
350             for (int z = 0; z < mis.length; z++) {
351                 MethodInfo methodInfo = mis[z];
352                 // IF no deployment was specified OR this deployment was specified
353
if (mis[z].ejbDeploymentId == null || mis[z].ejbDeploymentId.equals(deploymentInfo.getDeploymentID())) {
354                     if (!deploymentInfo.isBeanManagedTransaction()) {
355                         // if its not Bean Managed transaction type
356
Vector JavaDoc methodVect = new Vector JavaDoc();
357
358                         if (methodInfo.methodIntf == null) {
359                             // => attribute applies to both home and remote interface methods
360
resolveMethods(methodVect, deploymentInfo.getRemoteInterface(), methodInfo);
361                             resolveMethods(methodVect, deploymentInfo.getHomeInterface(), methodInfo);
362                         } else if (methodInfo.methodIntf.equals("Home")) {
363                             resolveMethods(methodVect, deploymentInfo.getHomeInterface(), methodInfo);
364                         } else if (methodInfo.methodIntf.equals("Remote")) {
365                             resolveMethods(methodVect, deploymentInfo.getRemoteInterface(), methodInfo);
366                         } else {
367                             // wrong string constant
368
}
369
370                         for (int x = 0; x < methodVect.size(); x++) {
371                             Method JavaDoc method = (Method JavaDoc) methodVect.elementAt(x);
372
373                             // filter out all EJBObject and EJBHome methods that are not remove() methods
374
if ((method.getDeclaringClass() == javax.ejb.EJBObject JavaDoc.class ||
375                                     method.getDeclaringClass() == javax.ejb.EJBHome JavaDoc.class) &&
376                                     method.getName().equals("remove") == false) {
377                                 continue; //skip it
378
}
379                             deploymentInfo.setMethodTransactionAttribute(method, transInfo.transAttribute);
380                         }
381                     }
382                 }
383             }
384         }
385
386     }
387
388     /**
389      * Maps the security role references used by enterprise beans to their associated physical
390      * in the target environment. Each security role reference is mapped to a logical role. The
391      * logical roles are themselves mapped to their respective physical role equivalents in the
392      * AssemblerTool.RoleMapping object.
393      *
394      * @param deployment the DeploymentInfo object to which the mapping should be applied.
395      * @param beanInfo the EnterpiseBeanInfo object which contains the securityRoleReferences
396      * @param roleMapping the RoleMapping object which contains the logical to physical security roles.
397      * @see org.openejb.alt.assembler.classic.EnterpriseBeanInfo
398      * @see org.openejb.alt.assembler.classic.AssemblerTool.RoleMapping
399      * @see org.openejb.core.DeploymentInfo#addSecurityRoleReference(String, String[])
400      */

401     public void applySecurityRoleReference(DeploymentInfo deployment, EnterpriseBeanInfo beanInfo, AssemblerTool.RoleMapping roleMapping) {
402         if (beanInfo.securityRoleReferences != null) {
403             for (int l = 0; l < beanInfo.securityRoleReferences.length; l++) {
404                 SecurityRoleReferenceInfo roleRef = beanInfo.securityRoleReferences[l];
405                 String JavaDoc[] physicalRoles = roleMapping.getPhysicalRoles(roleRef.roleLink);
406                 deployment.addSecurityRoleReference(roleRef.roleName, physicalRoles);
407             }
408         }
409     }
410
411     /**
412      * This method applies a set of method permissions to a deploymentInfo object, so that the container
413      * can verify that a specific physical security role has access to a specific method.
414      * The method itself maps each of the physical security roles to a method and add this binding
415      * to the org.openejb.core.DeploymentInfo object by invoking its DeploymentInfo.appendMethodPermission()
416      * method. The roleNames of the MethodPermissionInfo object are assumed to be the physical names,
417      * not the logical names. If this is not the case then the MethodPermissionInfo object should be preprocessed
418      * by the applyRoleMapping( ) method, or the overloaded version of this method which takes a RoleMapping
419      * object should be used (both these strategies will map logical to physical roles).
420      *
421      * @param deployment the DeploymentInfo object to which the Method Permissions should be applied.
422      * @param permissions the Method Permission to be applied to the deployment.
423      * @see org.openejb.alt.assembler.classic.MethodPermissionInfo
424      * @see org.openejb.core.DeploymentInfo#appendMethodPermissions(java.lang.reflect.Method, String[])
425      */

426     public void applyMethodPermissions(DeploymentInfo deployment, MethodPermissionInfo[] permissions) {
427         /*TODO: Add better exception handling. This method doesn't throws any exceptions!!
428          there is a lot of complex code here, I'm sure something could go wrong the user
429          might want to know about.
430          At the very least, log a warning or two.
431          */

432         for (int a = 0; a < permissions.length; a++) {
433             MethodPermissionInfo methodPermission = permissions[a];
434             for (int b = 0; b < methodPermission.methods.length; b++) {
435                 MethodInfo methodInfo = methodPermission.methods[b];
436
437                 // IF no deployment id was specified OR this deployment's id is specified.
438
if (methodInfo.ejbDeploymentId == null || methodInfo.ejbDeploymentId.equals(deployment.getDeploymentID())) {
439                     // get the actual methods that match for this deployment (EJBHome, EJBObject, remote and home interface methods)
440
java.lang.reflect.Method JavaDoc[] methods = resolveMethodInfo(methodInfo, deployment);
441                     // add the method permission to the set of permissions held by the deployment info object
442
for (int c = 0; c < methods.length; c++) {
443                         deployment.appendMethodPermissions(methods[c], methodPermission.roleNames);
444                     }
445                 }
446
447             }
448         }
449     }
450
451     /**
452      * This method applies a set of method permissions and RoleMapping to a deploymentInfo object, so that the container
453      * can verify that a specific physical security role has access to a specific method.
454      * The method itself maps each of the physical security roles to a method and adds this binding
455      * to the org.openejb.core.DeploymentInfo object by invoking its DeploymentInfo.appendMethodPermission()
456      * method. The roleNames of the MethodPermissionInfo object are assumed to be the logical names that corrspond
457      * to logical mappings in the RoleMappig object. If the MethodPermissionInfo object's roleMappings are actually
458      * physical role names then the overloaded version of this method which doesn't require a RoleMapping parameter should
459      * be used.
460      *
461      * @param deployment the DeploymentInfo object to which the Method Permissions should be applied.
462      * @param permissions the Method Permission to be applied to the deployment.
463      * @param roleMapping the encapsulation of logical roles and their corresponding physical role mappings.
464      * @see org.openejb.alt.assembler.classic.MethodPermissionInfo
465      * @see org.openejb.alt.assembler.classic.AssemblerTool.RoleMapping
466      * @see org.openejb.core.DeploymentInfo#appendMethodPermissions(java.lang.reflect.Method, String[])
467      */

468     public void applyMethodPermissions(DeploymentInfo deployment, MethodPermissionInfo[] permissions, AssemblerTool.RoleMapping roleMapping) {
469         /*TODO: Add better exception handling. This method doesn't throws any exceptions!!
470          there is a lot of complex code here, I'm sure something could go wrong the user
471          might want to know about.
472          At the very least, log a warning or two.
473          */

474         for (int i = 0; i < permissions.length; i++) {
475             permissions[i] = applyRoleMappings(permissions[i], roleMapping);
476         }
477         applyMethodPermissions(deployment, permissions);
478     }
479
480     /*
481     * Makes a copy of the MethodPermissionObject and then replaces the logical roles of the MethodPermissionInfo copy
482     * with the physical roles in the roleMapping object.
483     * If the RoleMapping object doesn't have a set of physical roles for a particular logical role in the
484     * MethodPermissionInfo, then the logical role is used.
485     *
486     * @param methodPermission the permission object to be copies and updated.
487     * @param roleMapping encapsulates the mapping of many logical roles to their equivalent physical roles.
488     * @see org.openejb.alt.assembler.classic.MethodPermissionInfo
489     * @see org.openejb.alt.assembler.classic.AssemblerTool.RoleMapping
490     */

491     public MethodPermissionInfo applyRoleMappings(MethodPermissionInfo methodPermission,
492                                                   AssemblerTool.RoleMapping roleMapping) {
493         /*TODO: Add better exception handling. This method doesn't throws any exceptions!!
494          there is a lot of complex code here, I'm sure something could go wrong the user
495          might want to know about.
496          At the very least, log a warning or two.
497          */

498
499         HashSet JavaDoc physicalRoles = new HashSet JavaDoc();
500
501         for (int z = 0; z < methodPermission.roleNames.length; z++) {
502             String JavaDoc[] physicals = roleMapping.getPhysicalRoles(methodPermission.roleNames[z]);
503             if (physicals != null) {
504                 for (int x = 0; x < physicals.length; x++) {
505                     physicalRoles.add(physicals[x]);
506                 }
507             } else {// if no physical roles are mapped use logical role
508

509                 physicalRoles.add(methodPermission.roleNames[z]);
510             }
511         }
512         methodPermission.roleNames = new String JavaDoc[physicalRoles.size()];
513         physicalRoles.toArray(methodPermission.roleNames);
514         return methodPermission;
515     }
516
517     /**
518      * This class encapsulates a mapping between a collection of
519      * logical roles and each of those roles equivalent physical security roles
520      * in the target environment.
521      * <p/>
522      * Instance of this class are constructed from a RoleMappingInfo configuration
523      * class. This class is used in the applySecurityRoleReferences( ) and
524      * applyMethodPermissions( ) Assembler methods.
525      */

526     public static class RoleMapping {
527         private HashMap JavaDoc map = new HashMap JavaDoc();
528
529         /**
530          * Constructs an instance from a RoleMappingInfo configuration object.
531          *
532          * @param roleMappingInfos configuration object holds collections of logical and physical roles
533          * @see org.openejb.alt.assembler.classic.RoleMappingInfo
534          */

535         public RoleMapping(RoleMappingInfo[] roleMappingInfos) {
536             for (int i = 0; i < roleMappingInfos.length; i++) {
537                 RoleMappingInfo mapping = roleMappingInfos[i];
538                 for (int z = 0; z < mapping.logicalRoleNames.length; z++) {
539                     map.put(mapping.logicalRoleNames[z], mapping.physicalRoleNames);
540                 }
541             }
542         }
543
544         /**
545          * Returns all the logical roles in this mapping. The logical roles
546          * act as keys to collections of equivalent physical roles
547          *
548          * @return a collection of logical roles
549          */

550         public String JavaDoc[] logicalRoles() {
551             return (String JavaDoc[]) map.keySet().toArray();
552         }
553
554         /**
555          * Returns a collection of physical roles that are mapped to the
556          * logical role.
557          *
558          * @param logicalRole a logical role that is mapped to physical roles
559          * @return a collection of physical roles; null if no roles are mapped.
560          */

561         public String JavaDoc[] getPhysicalRoles(String JavaDoc logicalRole) {
562             String JavaDoc[] roles = (String JavaDoc[]) map.get(logicalRole);
563             return roles != null ? (String JavaDoc[]) roles.clone() : null;
564         }
565
566     }
567
568
569     ////////////////////////////////////////////////////////////////
570
/////
571
///// Protected Helper methods. Not part of public static interface
572
/////
573
///////////////////////////////////////////////////////////////
574

575
576
577
578
579
580     /**
581      * Returns all the Method objects specified by a MethodInfo object for a specific bean deployment.
582      *
583      * @see org.openejb.core.DeploymentInfo
584      * @see MethodInfo
585      */

586     protected java.lang.reflect.Method JavaDoc[] resolveMethodInfo(MethodInfo methodInfo, org.openejb.core.DeploymentInfo di) {
587         /*TODO: Add better exception handling. This method doesn't throws any exceptions!!
588          there is a lot of complex code here, I'm sure something could go wrong the user
589          might want to know about.
590          At the very least, log a warning or two.
591          */

592
593         Vector JavaDoc methodVect = new Vector JavaDoc();
594
595         Class JavaDoc remote = di.getRemoteInterface();
596         Class JavaDoc home = di.getHomeInterface();
597         if (methodInfo.methodIntf == null) {
598             resolveMethods(methodVect, remote, methodInfo);
599             resolveMethods(methodVect, home, methodInfo);
600         } else if (methodInfo.methodIntf.equals("Remote")) {
601             resolveMethods(methodVect, remote, methodInfo);
602         } else {
603             resolveMethods(methodVect, home, methodInfo);
604         }
605         return (java.lang.reflect.Method JavaDoc[]) methodVect.toArray(new java.lang.reflect.Method JavaDoc[methodVect.size()]);
606     }
607
608     /**
609      * @throws SecurityException
610      * @see org.openejb.core.DeploymentInfo
611      * @see MethodInfo
612      */

613     protected static void resolveMethods(Vector JavaDoc methods, Class JavaDoc intrface, MethodInfo mi)
614             throws SecurityException JavaDoc {
615         /*TODO: Add better exception handling. There is a lot of complex code here, I'm sure something could go wrong the user
616          might want to know about.
617          At the very least, log a warning or two.
618          */

619
620         if (mi.methodName.equals("*")) {
621             Method JavaDoc[] mthds = intrface.getMethods();
622             for (int i = 0; i < mthds.length; i++)
623                 methods.add(mthds[i]);
624         } else if (mi.methodParams != null) {// there are paramters specified
625
try {
626                 Class JavaDoc[] params = new Class JavaDoc[mi.methodParams.length];
627                 ClassLoader JavaDoc cl = intrface.getClassLoader();
628                 for (int i = 0; i < params.length; i++) {
629                     try {
630                         params[i] = getClassForParam(mi.methodParams[i], cl);
631                     } catch (ClassNotFoundException JavaDoc cnfe) {
632                         // logSomething here.
633
}
634                 }
635                 Method JavaDoc m = intrface.getMethod(mi.methodName, params);
636                 methods.add(m);
637             } catch (NoSuchMethodException JavaDoc nsme) {
638                 /*
639                 Do nothing. Exceptions are not only possible they are expected to be a part of normall processing.
640                 Normally exception handling should not be a part of business logic, but server start up doesn't need to be
641                 as peformant as server runtime, so its allowed.
642                 */

643             }
644         } else {// no paramters specified so may be several methods
645
Method JavaDoc[] ms = intrface.getMethods();
646             for (int i = 0; i < ms.length; i++) {
647                 if (ms[i].getName().equals(mi.methodName))
648                     methods.add(ms[i]);
649             }
650         }
651
652     }
653
654     protected void checkImplementation(Class JavaDoc intrfce, Class JavaDoc factory, String JavaDoc serviceType, String JavaDoc serviceName) throws OpenEJBException {
655         if (!intrfce.isAssignableFrom(factory)) {
656             handleException("init.0100", serviceType, serviceName, factory.getName(), intrfce.getName());
657         }
658     }
659
660     /**
661      * Return the correct Class object. Either use forName or
662      * return a primitive TYPE Class.
663      */

664     private static java.lang.Class JavaDoc getClassForParam(java.lang.String JavaDoc className, ClassLoader JavaDoc cl) throws ClassNotFoundException JavaDoc {
665         if (cl == null) {
666             cl = ClassLoader.getSystemClassLoader();
667         }
668
669         // Test if the name is a primitive type name
670
if (className.equals("int")) {
671             return java.lang.Integer.TYPE;
672         } else if (className.equals("double")) {
673             return java.lang.Double.TYPE;
674         } else if (className.equals("long")) {
675             return java.lang.Long.TYPE;
676         } else if (className.equals("boolean")) {
677             return java.lang.Boolean.TYPE;
678         } else if (className.equals("float")) {
679             return java.lang.Float.TYPE;
680         } else if (className.equals("char")) {
681             return java.lang.Character.TYPE;
682         } else if (className.equals("short")) {
683             return java.lang.Short.TYPE;
684         } else if (className.equals("byte")) {
685             return java.lang.Byte.TYPE;
686         } else
687             return cl.loadClass(className);
688
689     }
690
691
692     /*------------------------------------------------------*/
693     /* Methods for easy exception handling */
694     /*------------------------------------------------------*/
695     public void handleException(String JavaDoc errorCode, Object JavaDoc arg0, Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3) throws OpenEJBException {
696         throw new OpenEJBException(messages.format(errorCode, arg0, arg1, arg2, arg3));
697     }
698
699     public void handleException(String JavaDoc errorCode, Object JavaDoc arg0, Object JavaDoc arg1, Object JavaDoc arg2) throws OpenEJBException {
700         throw new OpenEJBException(messages.format(errorCode, arg0, arg1, arg2));
701     }
702
703     public void handleException(String JavaDoc errorCode, Object JavaDoc arg0, Object JavaDoc arg1) throws OpenEJBException {
704         throw new OpenEJBException(messages.format(errorCode, arg0, arg1));
705     }
706
707     public void handleException(String JavaDoc errorCode, Object JavaDoc arg0) throws OpenEJBException {
708         throw new OpenEJBException(messages.format(errorCode, arg0));
709     }
710
711     public void handleException(String JavaDoc errorCode) throws OpenEJBException {
712         throw new OpenEJBException(messages.format(errorCode));
713     }
714
715
716     /*------------------------------------------------------*/
717     /* Methods for logging exceptions that are noteworthy */
718     /* but not bad enough to stop the container system. */
719     /*------------------------------------------------------*/
720     public void logWarning(String JavaDoc errorCode, Object JavaDoc arg0, Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3) {
721         System.out.println("Warning: " + messages.format(errorCode, arg0, arg1, arg2, arg3));
722     }
723
724     public void logWarning(String JavaDoc errorCode, Object JavaDoc arg0, Object JavaDoc arg1, Object JavaDoc arg2) {
725         System.out.println("Warning: " + messages.format(errorCode, arg0, arg1, arg2));
726     }
727
728     public void logWarning(String JavaDoc errorCode, Object JavaDoc arg0, Object JavaDoc arg1) {
729         System.out.println("Warning: " + messages.format(errorCode, arg0, arg1));
730     }
731
732     public void logWarning(String JavaDoc errorCode, Object JavaDoc arg0) {
733         System.out.println("Warning: " + messages.format(errorCode, arg0));
734     }
735
736     public void logWarning(String JavaDoc errorCode) {
737         System.out.println("Warning: " + messages.format(errorCode));
738     }
739 }
Popular Tags