KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > client > AppClientContainer


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.geronimo.client;
18
19 import java.lang.reflect.Constructor JavaDoc;
20 import java.lang.reflect.InvocationTargetException JavaDoc;
21 import java.lang.reflect.Method JavaDoc;
22 import java.security.PrivilegedAction JavaDoc;
23
24 import javax.security.auth.Subject JavaDoc;
25 import javax.security.auth.callback.CallbackHandler JavaDoc;
26 import javax.security.auth.login.LoginContext JavaDoc;
27 import javax.security.auth.login.LoginException JavaDoc;
28
29 import org.apache.geronimo.gbean.AbstractName;
30 import org.apache.geronimo.gbean.GBeanInfo;
31 import org.apache.geronimo.gbean.GBeanInfoBuilder;
32 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
33 import org.apache.geronimo.kernel.Kernel;
34 import org.apache.geronimo.security.ContextManager;
35 import org.apache.geronimo.security.Callers;
36 import org.apache.geronimo.security.deploy.DefaultPrincipal;
37 import org.apache.geronimo.security.util.ConfigurationUtil;
38
39 /**
40  * @version $Rev: 486195 $ $Date: 2006-12-12 10:42:02 -0500 (Tue, 12 Dec 2006) $
41  */

42 public final class AppClientContainer {
43     private static final Class JavaDoc[] MAIN_ARGS = {String JavaDoc[].class};
44
45     private final String JavaDoc mainClassName;
46     private final AppClientPlugin jndiContext;
47     private final AbstractName appClientModuleName;
48     private final String JavaDoc realmName;
49     private final Class JavaDoc callbackHandlerClass;
50     private final Subject JavaDoc defaultSubject;
51     private final Method JavaDoc mainMethod;
52     private final ClassLoader JavaDoc classLoader;
53     private final Kernel kernel;
54
55     public AppClientContainer(String JavaDoc mainClassName,
56             AbstractName appClientModuleName,
57             String JavaDoc realmName,
58             String JavaDoc callbackHandlerClassName,
59             DefaultPrincipal defaultPrincipal,
60             AppClientPlugin jndiContext,
61             ClassLoader JavaDoc classLoader,
62             Kernel kernel
63     ) throws Exception JavaDoc {
64         this.mainClassName = mainClassName;
65         this.appClientModuleName = appClientModuleName;
66         if ((realmName == null) != (callbackHandlerClassName == null)) {
67             throw new IllegalArgumentException JavaDoc("You must supply both realmName and callbackHandlerClass or neither");
68         }
69         this.realmName = realmName;
70         if (callbackHandlerClassName != null) {
71             try {
72                 this.callbackHandlerClass = classLoader.loadClass(callbackHandlerClassName);
73             } catch (ClassNotFoundException JavaDoc e) {
74                 throw new AppClientInitializationException("Could not load callbackHandlerClass", e);
75             }
76         } else {
77             callbackHandlerClass = null;
78         }
79         if (defaultPrincipal != null) {
80             defaultSubject = ConfigurationUtil.generateDefaultSubject(defaultPrincipal, classLoader);
81         } else {
82             defaultSubject = null;
83         }
84         this.classLoader = classLoader;
85         this.kernel = kernel;
86         this.jndiContext = jndiContext;
87
88         try {
89             Class JavaDoc mainClass = classLoader.loadClass(mainClassName);
90             mainMethod = mainClass.getMethod("main", MAIN_ARGS);
91         } catch (ClassNotFoundException JavaDoc e) {
92             throw new AppClientInitializationException("Unable to load Main-Class " + mainClassName, e);
93         } catch (NoSuchMethodException JavaDoc e) {
94             throw new AppClientInitializationException("Main-Class " + mainClassName + " does not have a main method", e);
95         }
96     }
97
98     public AbstractName getAppClientModuleName() {
99         return appClientModuleName;
100     }
101
102     public String JavaDoc getMainClassName() {
103         return mainClassName;
104     }
105
106     public void main(final String JavaDoc[] args) throws Exception JavaDoc {
107         //TODO reorganize this so it makes more sense. maybe use an interceptor stack.
108
//TODO track resource ref shared and app managed security
109
Thread JavaDoc thread = Thread.currentThread();
110
111         ClassLoader JavaDoc oldClassLoader = thread.getContextClassLoader();
112         Callers oldCallers = ContextManager.getCallers();
113         Subject JavaDoc clientSubject = defaultSubject;
114         LoginContext JavaDoc loginContext = null;
115         try {
116             thread.setContextClassLoader(classLoader);
117             if (callbackHandlerClass != null) {
118                 //look for a constructor taking the args
119
CallbackHandler JavaDoc callbackHandler;
120                 try {
121                     Constructor JavaDoc cArgs = callbackHandlerClass.getConstructor(new Class JavaDoc[] {String JavaDoc[].class});
122                     callbackHandler = (CallbackHandler JavaDoc) cArgs.newInstance(new Object JavaDoc[] {args});
123                 } catch (NoSuchMethodException JavaDoc e) {
124                     callbackHandler = (CallbackHandler JavaDoc) callbackHandlerClass.newInstance();
125                 }
126                 loginContext = new LoginContext JavaDoc(realmName, callbackHandler);
127                 try {
128                     loginContext.login();
129                 } catch (LoginException JavaDoc e) {
130                     loginContext = null;
131                     throw e;
132                 }
133                 clientSubject = loginContext.getSubject();
134             }
135             ContextManager.setCallers(clientSubject, clientSubject);
136             jndiContext.startClient(appClientModuleName, kernel, classLoader);
137             if (clientSubject == null) {
138                 mainMethod.invoke(null, new Object JavaDoc[]{args});
139             } else {
140                 Subject.doAs(clientSubject, new PrivilegedAction JavaDoc() {
141                     public Object JavaDoc run() {
142                         try {
143                             mainMethod.invoke(null, new Object JavaDoc[]{args});
144                         } catch (IllegalAccessException JavaDoc e) {
145                             throw new RuntimeException JavaDoc(e);
146                         } catch (InvocationTargetException JavaDoc e) {
147                             throw new RuntimeException JavaDoc(e);
148                         }
149                         return null;
150                     }
151                 });
152             }
153         } catch (InvocationTargetException JavaDoc e) {
154             Throwable JavaDoc cause = e.getCause();
155             if (cause instanceof Exception JavaDoc) {
156                 throw (Exception JavaDoc) cause;
157             } else if (cause instanceof Error JavaDoc) {
158                 throw (Error JavaDoc) cause;
159             }
160             throw new Error JavaDoc(e);
161         } finally {
162             if (loginContext != null) {
163                 loginContext.logout();
164             }
165             jndiContext.stopClient(appClientModuleName);
166
167             thread.setContextClassLoader(oldClassLoader);
168             ContextManager.popCallers(oldCallers);
169         }
170     }
171
172     public static final GBeanInfo GBEAN_INFO;
173
174     static {
175         GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(AppClientContainer.class, NameFactory.APP_CLIENT);
176
177         infoFactory.addOperation("main", new Class JavaDoc[]{String JavaDoc[].class});
178
179         infoFactory.addAttribute("mainClassName", String JavaDoc.class, true);
180         infoFactory.addAttribute("appClientModuleName", AbstractName.class, true);
181         infoFactory.addAttribute("realmName", String JavaDoc.class, true);
182         infoFactory.addAttribute("callbackHandlerClassName", String JavaDoc.class, true);
183         infoFactory.addAttribute("defaultPrincipal", DefaultPrincipal.class, true);
184
185         infoFactory.addReference("JNDIContext", AppClientPlugin.class, NameFactory.GERONIMO_SERVICE);
186
187         infoFactory.addAttribute("classLoader", ClassLoader JavaDoc.class, false);
188         infoFactory.addAttribute("kernel", Kernel.class, false);
189
190
191         infoFactory.setConstructor(new String JavaDoc[]{"mainClassName",
192                                                 "appClientModuleName",
193                                                 "realmName",
194                                                 "callbackHandlerClassName",
195                                                 "defaultPrincipal",
196                                                 "JNDIContext",
197                                                 "classLoader",
198                                                 "kernel"
199         });
200
201         GBEAN_INFO = infoFactory.getBeanInfo();
202     }
203
204     public static GBeanInfo getGBeanInfo() {
205         return GBEAN_INFO;
206     }
207 }
208
Popular Tags