View Javadoc

1   /*
2    * Copyright 2000-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.portals.graffito.jcr.repository;
17  
18  import java.util.Hashtable;
19  
20  import javax.jcr.Repository;
21  import javax.jcr.Session;
22  import javax.jcr.SimpleCredentials;
23  import javax.naming.Context;
24  import javax.naming.InitialContext;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.apache.jackrabbit.core.jndi.RegistryHelper;
29  import org.apache.jackrabbit.util.ISO9075;
30  import org.apache.jackrabbit.util.Text;
31  import org.apache.portals.graffito.jcr.exception.JcrMappingException;
32  import org.apache.portals.graffito.jcr.exception.PersistenceException;
33  import org.apache.portals.graffito.jcr.exception.RepositoryException;
34  
35  /***
36  * Utility class for managing JCR repositories.
37  * <b>Note</b>: most of the utility methods in this class can be used only with Jackrabbit.
38  *
39  * @author <a href="mailto:christophe.lombart@sword-technologies.com">Lombart Christophe </a>
40  * @version $Id: Exp $
41  */
42  public class RepositoryUtil
43  {
44      
45      /*** Graffito namespace prefix constant.
46       */
47      public static final String GRAFFITO_NAMESPACE_PREFIX   = "graffito";
48  
49      /*** Graffito namespace constant.
50       */
51      public static final String GRAFFITO_NAMESPACE          = "http://incubator.apache.org/graffito";    
52      /*** Item path separator */
53      public static final String PATH_SEPARATOR = "/";
54      
55      public static final Log log = LogFactory.getLog(RepositoryUtil.class);  
56      /***
57       * Register a new repository 
58       * 
59       * @param repositoryName The repository unique name
60       * @param configFile The JCR config file
61       * @param homeDir The directory containing the complete repository settings (workspace, node types, ...)
62       * 
63       * @throws RepositoryException when it is not possible to register the repository
64       */
65      public static void registerRepository(String repositoryName, String configFile, String homeDir) throws RepositoryException
66      {
67          try
68          {
69              Hashtable env = new Hashtable();
70              env.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.jackrabbit.core.jndi.provider.DummyInitialContextFactory");
71              env.put(Context.PROVIDER_URL, "localhost");
72              InitialContext ctx = new InitialContext(env);
73  
74              RegistryHelper.registerRepository(ctx, repositoryName, configFile, homeDir, true);
75          }
76          catch (Exception e)
77          {        
78              throw new RepositoryException("Impossible to register the respository : " + 
79                                             repositoryName + " - config file : " + configFile, e);
80          }        
81          
82      }
83      
84      
85      /***
86       * Unregister a repository 
87       * 
88       * @param repositoryName The repository unique name
89       * 
90       * @throws RepositoryException when it is not possible to unregister the repository
91       */
92      public static void unRegisterRepository(String repositoryName) throws RepositoryException
93      {
94          try
95          {
96          	Hashtable env = new Hashtable();
97              env.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.jackrabbit.core.jndi.provider.DummyInitialContextFactory");
98              env.put(Context.PROVIDER_URL, "localhost");
99              InitialContext ctx = new InitialContext(env);
100 
101             RegistryHelper.unregisterRepository(ctx, repositoryName);
102         }
103         catch (Exception e)
104         {
105             throw new RepositoryException("Impossible to unregister the respository : " + 
106                                            repositoryName , e);
107         }        
108         
109     }
110     
111     /***
112      * Get a repository
113      * 
114      * @param repositoryName The repository name
115      * @return a JCR repository reference
116      * 
117      * @throws RepositoryException when it is not possible to get the repository. 
118      *         Before calling this method, the repository has to be registered (@see RepositoryUtil#registerRepository(String, String, String)
119      */
120     public static Repository getRepository(String repositoryName) throws RepositoryException
121     {
122         try
123         {
124             Hashtable env = new Hashtable();
125             env.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.jackrabbit.core.jndi.provider.DummyInitialContextFactory");
126             env.put(Context.PROVIDER_URL, "localhost");
127             InitialContext ctx = new InitialContext(env);
128             
129             Repository repository = (Repository) ctx.lookup(repositoryName);
130             return repository;
131         }
132         catch (Exception e)
133         {
134             throw new RepositoryException("Impossible to get the repository : " + repositoryName, e);
135         }        
136     }
137     
138     /***
139      * Connect to a JCR repository
140      * 
141      * @param repository The JCR repository 
142      * @param user The user name
143      * @param password The password
144      * @return a valid JCR session 
145      * 
146      * @throws RepositoryException when it is not possible to connect to the JCR repository 
147      */
148     public static Session login(Repository repository, String user, String password) throws RepositoryException
149     {
150         try
151         {
152             Session session = repository.login(new SimpleCredentials(user, password.toCharArray()), null);
153             setupSession(session);
154            
155             return session; 
156         }
157         catch (Exception e)
158         {
159             throw new RepositoryException("Impossible to login ", e);
160         }
161     }
162     
163     /***
164      * Check if a path is valid 
165      * 
166      * @param path The path to validate
167      * @return true if the path is valid, else false
168      */
169     public static boolean isValidPath(String path)
170     {
171         if ((path == null) ||
172             (path.equals(PATH_SEPARATOR)) ||
173             (path.endsWith(PATH_SEPARATOR)) ||
174             (! path.startsWith(PATH_SEPARATOR)) || 
175             (path.equals("")))
176         {
177             return false; 
178         }
179         return true;
180     }    
181     
182     /***
183      * Get the parent path
184      * @param path The path from wich the parent path has to be returned
185      * @return The parent path
186      * 
187      * @throws PersistenceException when the path is invalid
188      */
189     public static String getParentPath(String path) throws PersistenceException
190     {
191         String parentPath = "";
192         
193         if (!isValidPath(path))
194         {
195             throw new JcrMappingException("Invalid path : " + path);
196         }
197         
198         String[] pathElements = path.split(PATH_SEPARATOR);         
199         
200         // Firts path element should be = empty string because a uri always start with '/'
201         // So, if len=2, means it is a root folder like '/foo'. 
202         // In this case the uri has not parent folder => return "/"
203         if (pathElements.length == 2)
204         {
205             return PATH_SEPARATOR;
206         }
207         
208         for(int i=0; i < pathElements.length -1; i++)
209         {   
210             if (! pathElements[i].equals(""))
211             {    
212                parentPath += PATH_SEPARATOR + pathElements[i];
213             }
214         }                  
215         return parentPath;
216     }
217 
218     /***
219      * Get the node name
220      * @param path  The path from which the node name has to be retrieved
221      * @return The node name
222      * 
223      * @throws PersistenceException when the path is invalid
224      */
225     public static String getNodeName(String path)  throws PersistenceException
226     {
227         
228         String[] pathElements = path.split(PATH_SEPARATOR);
229         
230         if (! isValidPath(path))
231         {
232             throw new JcrMappingException("Invalid path : " + path);
233         }        
234         return pathElements[pathElements.length-1];
235     }
236     
237     /***
238      * Setup the session. 
239      * Until now, we check only if the Graffito namespace prefix exist in the repository
240      * 
241      */
242     private static void setupSession(Session session) throws RepositoryException
243     {
244          try
245          {
246             String[] jcrNamespaces = session.getWorkspace().getNamespaceRegistry().getPrefixes();
247             boolean createGraffitoNamespace = true;
248             for (int i = 0; i < jcrNamespaces.length; i++)
249             {
250                 if (jcrNamespaces[i].equals(GRAFFITO_NAMESPACE_PREFIX))
251                 {
252                     createGraffitoNamespace = false;
253                     log.debug("Graffito namespace exists.");
254                 }
255             }
256              
257             if (createGraffitoNamespace)
258             {
259                 session.getWorkspace().getNamespaceRegistry().registerNamespace(GRAFFITO_NAMESPACE_PREFIX, GRAFFITO_NAMESPACE);
260                 log.info("Successfully created graffito namespace.");
261             }
262             
263             if (session.getRootNode() != null)
264             {
265                 log.info("Jcr repository setup successfull.");
266             }
267             
268 
269         }
270         catch (Exception e)
271         {
272             log.error("Error while setting up the jcr repository.", e);
273             throw new RepositoryException(e.getMessage());
274         }
275     }
276 
277     /***
278      * Encode a path 
279      * @TODO : drop Jackrabbit dependency
280      * 
281      * @param path the path to encode
282      * @return the encoded path 
283      * 
284      */
285     public static String encodePath(String path)
286     {
287     	String[] pathElements = Text.explode(path, '/');
288     	for (int i=0;i<pathElements.length;i++)
289     	{
290     		pathElements[i] = ISO9075.encode(pathElements[i]);
291     	}
292     	return "/" + Text.implode(pathElements, "/");
293     }
294 }