KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > jcr > AbstractRepository


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

16 package org.apache.cocoon.jcr;
17
18 import org.apache.avalon.framework.activity.Disposable;
19 import org.apache.avalon.framework.component.Component;
20 import org.apache.avalon.framework.configuration.Configurable;
21 import org.apache.avalon.framework.configuration.Configuration;
22 import org.apache.avalon.framework.configuration.ConfigurationException;
23 import org.apache.avalon.framework.context.Context;
24 import org.apache.avalon.framework.context.ContextException;
25 import org.apache.avalon.framework.context.Contextualizable;
26 import org.apache.avalon.framework.logger.AbstractLogEnabled;
27 import org.apache.avalon.framework.service.ServiceException;
28 import org.apache.avalon.framework.service.ServiceManager;
29 import org.apache.avalon.framework.service.Serviceable;
30 import org.apache.avalon.framework.thread.ThreadSafe;
31
32 import org.apache.cocoon.components.ContextHelper;
33 import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
34 import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
35 import org.apache.cocoon.environment.ObjectModelHelper;
36 import org.apache.cocoon.environment.Request;
37 import org.apache.cocoon.sitemap.PatternException;
38
39 import org.apache.excalibur.source.SourceResolver;
40 import org.apache.excalibur.source.impl.FileSource;
41
42 import javax.jcr.Credentials;
43 import javax.jcr.LoginException;
44 import javax.jcr.NoSuchWorkspaceException;
45 import javax.jcr.Repository;
46 import javax.jcr.RepositoryException;
47 import javax.jcr.Session;
48 import javax.jcr.SimpleCredentials;
49 import java.util.Map JavaDoc;
50
51 /**
52  * Base class for JCR (aka <a
53  * HREF="http://www.jcp.org/en/jsr/detail?id=170">JSR-170</a>) repository as
54  * a Cocoon component. The main purpose of this class is to allow repository
55  * credentials to be specified in the component's configuration, so that the
56  * application code just has to call <code>repository.login()</code>.
57  *
58  * <p>
59  * There is no Cocoon-specific role for this component: "<code>javax.jcr.Repository</code>"
60  * should be used.
61  *
62  * <p>
63  * The configuration of this class, inherited by its subclasses, is as follows:
64  *
65  * <pre>
66  * &lt;jcr-repository&gt;
67  * &lt;jaas SRC="context://samples/jaas.config"/&gt;
68  * &lt;credentials login="<i>expression</i>" password="<i>expression</i>"/&gt;
69  * ... other specific configuration...
70  * &lt;/jcr-repository&gt;
71  * </pre>
72  *
73  * Login and password can be specified using the sitemap expression language,
74  * thus allowing the use of input modules to compute their values, e.g.
75  * <code>password="{session-attr:jcr-password}"</code>.
76  *
77  * <p>
78  * <code>&lt;credentials&gt;</code> is optional. If not specified, the
79  * application must explicitely supply credentials when calling
80  * <code>Repository.login()</code>.
81  *
82  * @version $Id: AbstractRepository.java 330017 2005-11-01 10:28:25Z sylvain $
83  */

84 public abstract class AbstractRepository extends AbstractLogEnabled
85                                          implements Repository, ThreadSafe, Contextualizable, Serviceable,
86                                                     Configurable, Disposable, Component {
87
88     /**
89      * Role which shall be used for JCR repository implementations.
90      */

91     public static final String JavaDoc ROLE = "javax.jcr.Repository";
92
93     /**
94      * The request attribute in which the JCR session is stored
95      */

96     public static final String JavaDoc JCR_SESSION_REQUEST_ATTRIBUTE = "jcr-session";
97
98     protected ServiceManager manager;
99
100     protected Context context;
101
102     protected Repository delegate;
103
104     // Defined by the portal block :-(
105
// protected VariableResolverFactory variableFactory;
106

107     protected VariableResolver loginResolver;
108
109     protected VariableResolver passwordResolver;
110
111
112     // =============================================================================================
113
// Avalon lifecycle
114
// =============================================================================================
115

116     public void contextualize(Context context) throws ContextException {
117         this.context = context;
118     }
119
120     public void service(ServiceManager manager) throws ServiceException {
121         this.manager = manager;
122     }
123
124     public void configure(Configuration config) throws ConfigurationException {
125         // FIXME FIXME FIXME Hack setting system jaas property
126
Configuration jaas = config.getChild("jaas", false);
127         if (jaas != null) {
128             String JavaDoc jaasURI = jaas.getAttribute("src");
129             SourceResolver resolver = null;
130             FileSource jaasSrc = null;
131             try {
132                 resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
133                 jaasSrc = (FileSource) resolver.resolveURI(jaasURI);
134                 if (System.getProperty("java.security.auth.login.config") == null) {
135                     System.setProperty("java.security.auth.login.config", jaasSrc.getFile().getAbsolutePath());
136                 } else {
137                     // WARNING: java.security.auth.login.config has already been set
138
}
139             } catch (Exception JavaDoc e) {
140                 throw new ConfigurationException("Cannot resolve jaas URI: " + jaasURI + " at " + config.getLocation());
141             } finally {
142                 if (jaasSrc != null) {
143                     resolver.release(jaasSrc);
144                 }
145                 this.manager.release(resolver);
146             }
147         }
148
149         Configuration credentials = config.getChild("credentials", false);
150         if (credentials != null) {
151             String JavaDoc login = credentials.getAttribute("login");
152             String JavaDoc password = credentials.getAttribute("password");
153
154             try {
155                 this.loginResolver = VariableResolverFactory.getResolver(login, this.manager);
156             } catch (PatternException e) {
157                 throw new ConfigurationException("Invalid expression for 'login' at " + credentials.getLocation(), e);
158             }
159             try {
160                 this.passwordResolver = VariableResolverFactory.getResolver(password, this.manager);
161             } catch (PatternException e) {
162                 if (this.loginResolver instanceof Disposable) {
163                     ((Disposable) this.loginResolver).dispose();
164                 }
165                 this.loginResolver = null;
166                 throw new ConfigurationException("Invalid expression for 'password' at " + credentials.getLocation(), e);
167             }
168         }
169     }
170
171     public void dispose() {
172         this.context = null;
173         this.delegate = null;
174
175         if (this.loginResolver instanceof Disposable) {
176             ((Disposable) this.loginResolver).dispose();
177         }
178         this.loginResolver = null;
179         if (this.passwordResolver instanceof Disposable) {
180             ((Disposable) this.passwordResolver).dispose();
181         }
182         this.passwordResolver = null;
183         this.manager = null;
184     }
185
186     // =============================================================================================
187
// Repository interface
188
// =============================================================================================
189

190     public String JavaDoc getDescriptor(String JavaDoc key) {
191         return delegate.getDescriptor(key);
192     }
193
194     public String JavaDoc[] getDescriptorKeys() {
195         return delegate.getDescriptorKeys();
196     }
197
198     public Session login()
199     throws LoginException, NoSuchWorkspaceException, RepositoryException {
200         Session session = getCachedSession(null);
201
202         if (session == null) {
203             Credentials creds = getCredentials();
204             session = creds == null ? delegate.login() : delegate.login(creds);
205             cacheSession(session, null);
206         }
207
208         return session;
209     }
210
211     public Session login(Credentials creds)
212     throws LoginException, NoSuchWorkspaceException, RepositoryException {
213         Session session = getCachedSession(null);
214
215         if (session == null) {
216             session = delegate.login(creds);
217             cacheSession(session, null);
218         }
219
220         return session;
221     }
222
223     public Session login(Credentials creds, String JavaDoc workspace)
224     throws LoginException, NoSuchWorkspaceException, RepositoryException {
225         Session session = getCachedSession(workspace);
226
227         if (session == null) {
228             session = delegate.login(creds, workspace);
229             cacheSession(session, workspace);
230         }
231
232         return session;
233     }
234
235     public Session login(String JavaDoc workspace)
236     throws LoginException, NoSuchWorkspaceException, RepositoryException {
237         Session session = getCachedSession(workspace);
238
239         if (session == null) {
240             Credentials creds = getCredentials();
241             session = creds == null ? delegate.login(workspace) : delegate.login(creds, workspace);
242             cacheSession(session, workspace);
243         }
244
245         return session;
246     }
247
248     // TODO: When logout should be called?
249

250     // =============================================================================================
251
// Implementation methods
252
// =============================================================================================
253

254     private Session getCachedSession(String JavaDoc workspace) {
255         Map JavaDoc objectModel;
256         try {
257             objectModel = ContextHelper.getObjectModel(context);
258         } catch(Exception JavaDoc e) {
259             // We don't have an object model (happens e.g. at init time or in a cron job)
260
return null;
261         }
262
263         String JavaDoc attributeName = workspace == null ?
264                 JCR_SESSION_REQUEST_ATTRIBUTE : JCR_SESSION_REQUEST_ATTRIBUTE + "/" + workspace;
265
266         Request request = ObjectModelHelper.getRequest(objectModel);
267         //FIXME: request is null when running in a testcase
268
if (request == null) return null;
269         Session session = (Session) request.getAttribute(attributeName);
270
271         return (session != null && session.isLive()) ? session : null;
272     }
273
274     private void cacheSession(Session session, String JavaDoc workspace) {
275         Map JavaDoc objectModel;
276         try {
277             objectModel = ContextHelper.getObjectModel(context);
278         } catch(Exception JavaDoc e) {
279             // We don't have an object model (happens e.g. at init time or in a cron job)
280
return;
281         }
282
283         String JavaDoc attributeName = workspace == null ?
284                 JCR_SESSION_REQUEST_ATTRIBUTE : JCR_SESSION_REQUEST_ATTRIBUTE + "/" + workspace;
285
286         Request request = ObjectModelHelper.getRequest(objectModel);
287         //FIXME: request is null when running in a testcase
288
if (request == null) return;
289         request.setAttribute(attributeName, session);
290     }
291
292     private Credentials getCredentials() throws LoginException {
293         if (this.loginResolver != null) {
294
295             Map JavaDoc objectModel;
296             try {
297                 objectModel = ContextHelper.getObjectModel(context);
298             } catch(Exception JavaDoc e) {
299                 // We don't have an object model (happens e.g. at init time or in a cron job)
300
throw new LoginException("No objectModel to evaluate credentials", e);
301             }
302
303             try {
304                 String JavaDoc login = this.loginResolver.resolve(objectModel);
305                 String JavaDoc password = this.loginResolver.resolve(objectModel);
306                 return new SimpleCredentials(login, password.toCharArray());
307             } catch (PatternException e) {
308                 throw new LoginException("Failed to evaluate credentials", e);
309             }
310         } else {
311             return null;
312         }
313     }
314 }
315
Popular Tags