1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
201
202
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 }