KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > info > magnolia > cms > beans > config > ContentRepository


1 /**
2  *
3  * Magnolia and its source-code is licensed under the LGPL.
4  * You may copy, adapt, and redistribute this file for commercial or non-commercial use.
5  * When copying, adapting, or redistributing this document in keeping with the guidelines above,
6  * you are required to provide proper attribution to obinary.
7  * If you reproduce or distribute the document without making any substantive modifications to its content,
8  * please use the following attribution line:
9  *
10  * Copyright 1993-2006 obinary Ltd. (http://www.obinary.com) All rights reserved.
11  *
12  */

13 package info.magnolia.cms.beans.config;
14
15 import info.magnolia.cms.core.Content;
16 import info.magnolia.cms.core.HierarchyManager;
17 import info.magnolia.cms.core.Path;
18 import info.magnolia.cms.core.SystemProperty;
19 import info.magnolia.cms.core.search.QueryManager;
20 import info.magnolia.cms.core.search.SearchFactory;
21 import info.magnolia.cms.security.AccessDeniedException;
22 import info.magnolia.cms.security.AccessManagerImpl;
23 import info.magnolia.cms.security.Permission;
24 import info.magnolia.cms.security.PermissionImpl;
25 import info.magnolia.cms.util.ClassUtil;
26 import info.magnolia.cms.util.ConfigUtil;
27 import info.magnolia.cms.util.UrlPattern;
28 import info.magnolia.repository.Provider;
29 import info.magnolia.repository.RepositoryMapping;
30 import info.magnolia.repository.RepositoryNotInitializedException;
31 import info.magnolia.repository.RepositoryNameMap;
32
33 import java.io.File JavaDoc;
34 import java.io.FileInputStream JavaDoc;
35 import java.io.FileNotFoundException JavaDoc;
36 import java.io.IOException JavaDoc;
37 import java.util.ArrayList JavaDoc;
38 import java.util.Collection JavaDoc;
39 import java.util.Hashtable JavaDoc;
40 import java.util.Iterator JavaDoc;
41 import java.util.List JavaDoc;
42 import java.util.Map JavaDoc;
43
44 import javax.jcr.Repository;
45 import javax.jcr.RepositoryException;
46 import javax.jcr.Session;
47 import javax.jcr.SimpleCredentials;
48
49 import org.apache.commons.lang.BooleanUtils;
50 import org.apache.commons.lang.StringUtils;
51 import org.jdom.Document;
52 import org.jdom.Element;
53 import org.jdom.JDOMException;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56
57
58 /**
59  * @author Sameer Charles
60  * $Id: ContentRepository.java 6587 2006-10-05 15:47:48Z philipp $
61  */

62 public final class ContentRepository {
63
64     /**
65      * default repository ID's.
66      */

67     public static final String JavaDoc WEBSITE = "website"; //$NON-NLS-1$
68

69     public static final String JavaDoc USERS = "users"; //$NON-NLS-1$
70

71     public static final String JavaDoc USER_ROLES = "userroles"; //$NON-NLS-1$
72

73     public static final String JavaDoc USER_GROUPS = "usergroups"; //$NON-NLS-1$
74

75     public static final String JavaDoc CONFIG = "config"; //$NON-NLS-1$
76

77     public static final String JavaDoc DEFAULT_WORKSPACE = "default"; //$NON-NLS-1$
78

79     public static final String JavaDoc VERSION_STORE = "mgnlVersion";
80
81     /**
82      * magnolia namespace.
83      */

84     public static final String JavaDoc NAMESPACE_PREFIX = "mgnl"; //$NON-NLS-1$
85

86     public static final String JavaDoc NAMESPACE_URI = "http://www.magnolia.info/jcr/mgnl"; //$NON-NLS-1$
87

88     /**
89      * Logger.
90      */

91     private static Logger log = LoggerFactory.getLogger(ContentRepository.class);
92
93     /**
94      * repository element string.
95      */

96     private static final String JavaDoc ELEMENT_REPOSITORY = "Repository"; //$NON-NLS-1$
97

98     private static final String JavaDoc ELEMENT_REPOSITORYMAPPING = "RepositoryMapping"; //$NON-NLS-1$
99

100     private static final String JavaDoc ELEMENT_PARAM = "param"; //$NON-NLS-1$
101

102     private static final String JavaDoc ELEMENT_WORKSPACE = "workspace"; //$NON-NLS-1$
103

104     /**
105      * Attribute names.
106      */

107     private static final String JavaDoc ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
108

109     private static final String JavaDoc ATTRIBUTE_LOAD_ON_STARTUP = "loadOnStartup"; //$NON-NLS-1$
110

111     private static final String JavaDoc ATTRIBUTE_PROVIDER = "provider"; //$NON-NLS-1$
112

113     private static final String JavaDoc ATTRIBUTE_VALUE = "value"; //$NON-NLS-1$
114

115     private static final String JavaDoc ATTRIBUTE_REPOSITORY_NAME = "repositoryName"; //$NON-NLS-1$
116

117     private static final String JavaDoc ATTRIBUTE_WORKSPACE_NAME = "workspaceName"; //$NON-NLS-1$
118

119     /**
120      * repository user.
121      */

122     public static final String JavaDoc REPOSITORY_USER = SystemProperty.getProperty("magnolia.connection.jcr.userId");
123
124     /**
125      * repository default password
126      */

127     public static final String JavaDoc REPOSITORY_PSWD = SystemProperty.getProperty("magnolia.connection.jcr.password");
128
129     /**
130      * All available repositories store.
131      */

132     private static Map repositories = new Hashtable JavaDoc();
133
134     /**
135      * JCR providers as mapped in repositories.xml.
136      */

137     private static Map repositoryProviders = new Hashtable JavaDoc();
138
139     /**
140      * All server hierarchy managers with full access to specific repositories.
141      */

142     private static Map hierarchyManagers = new Hashtable JavaDoc();
143
144     /**
145      * Repositories configuration as defined in repositories mapping file via attribute
146      * <code>magnolia.repositories.config</code>.
147      */

148     private static Map repositoryMapping = new Hashtable JavaDoc();
149
150     /**
151      * holds all repository names as configured in repositories.xml
152      */

153     private static Map repositoryNameMap = new Hashtable JavaDoc();
154
155     /**
156      * Utility class, don't instantiate.
157      */

158     private ContentRepository() {
159         // unused constructor
160
}
161
162     /**
163      * loads all configured repository using ID as Key, as configured in repositories.xml.
164      *
165      * <pre>
166      * &lt;Repository name="website"
167      * id="website"
168      * provider="info.magnolia.jackrabbit.ProviderImpl"
169      * loadOnStartup="true" >
170      * &lt;param name="configFile"
171      * value="WEB-INF/config/repositories/website.xml"/>
172      * &lt;param name="repositoryHome"
173      * value="repositories/website"/>
174      * &lt;param name="contextFactoryClass"
175      * value="org.apache.jackrabbit.core.jndi.provider.DummyInitialContextFactory"/>
176      * &lt;param name="providerURL"
177      * value="localhost"/>
178      * &lt;param name="id" value="website"/>
179      * &lt;/Repository>
180      *</pre>
181      */

182     public static void init() {
183         log.info("System : loading JCR"); //$NON-NLS-1$
184
repositories.clear();
185         hierarchyManagers.clear();
186         try {
187             loadRepositories();
188             log.info("System : JCR loaded"); //$NON-NLS-1$
189
}
190         catch (Exception JavaDoc e) {
191             log.error(e.getMessage(), e);
192         }
193     }
194
195     /**
196      * Verify the initialization state of all the repositories. This methods returns <code>false</code> only if
197      * <strong>all</strong> the repositories are empty (no node else than the root one).
198      * @return <code>false</code> if all the repositories are empty, <code>true</code> if at least one of them has
199      * content.
200      * @throws AccessDeniedException repository authentication failed
201      * @throws RepositoryException exception while accessing the repository
202      */

203     public static boolean checkIfInitialized() throws AccessDeniedException, RepositoryException {
204         Iterator JavaDoc repositoryNames = getAllRepositoryNames();
205         while (repositoryNames.hasNext()) {
206             String JavaDoc repository = (String JavaDoc) repositoryNames.next();
207             if (checkIfInitialized(repository)) {
208                 return true;
209             }
210         }
211         return false;
212     }
213
214     /**
215      * @param repository
216      * @throws RepositoryException
217      * @throws AccessDeniedException
218      */

219     public static boolean checkIfInitialized(String JavaDoc repository) throws RepositoryException, AccessDeniedException {
220         if (log.isDebugEnabled()) {
221             log.debug("Checking [" + repository + "] repository."); //$NON-NLS-1$ //$NON-NLS-2$
222
}
223         HierarchyManager hm = getHierarchyManager(repository);
224
225         if (hm == null) {
226             throw new RuntimeException JavaDoc("Repository [" + repository + "] not loaded"); //$NON-NLS-1$ //$NON-NLS-2$
227
}
228
229         Content startPage = hm.getRoot();
230
231         // return any kind of children
232
Collection JavaDoc children = startPage.getChildren(new Content.ContentFilter(){
233             public boolean accept(Content content) {
234                 return !content.getName().startsWith("jcr:");
235             }
236         });
237
238         if (!children.isEmpty()) {
239             if (log.isDebugEnabled()) {
240                 log.debug("Content found in [" + repository + "]."); //$NON-NLS-1$ //$NON-NLS-2$
241
}
242             return true;
243         }
244         return false;
245     }
246
247     /**
248      * Re-load all configured repositories.
249      * @see #init()
250      */

251     public static void reload() {
252         log.info("System : reloading JCR"); //$NON-NLS-1$
253
ContentRepository.init();
254     }
255
256     /**
257      * Load repository mappings and params using repositories.xml
258      * @throws Exception
259      */

260     private static void loadRepositories() throws Exception JavaDoc {
261         Document document = buildDocument();
262         Element root = document.getRootElement();
263         loadRepositoryNameMap(root);
264         Collection JavaDoc repositoryElements = root.getChildren(ContentRepository.ELEMENT_REPOSITORY);
265         Iterator JavaDoc children = repositoryElements.iterator();
266         while (children.hasNext()) {
267             Element element = (Element) children.next();
268             String JavaDoc name = element.getAttributeValue(ATTRIBUTE_NAME);
269             String JavaDoc load = element.getAttributeValue(ATTRIBUTE_LOAD_ON_STARTUP);
270             String JavaDoc provider = element.getAttributeValue(ATTRIBUTE_PROVIDER);
271             RepositoryMapping map = new RepositoryMapping();
272             map.setName(name);
273             map.setProvider(provider);
274             boolean loadOnStartup = BooleanUtils.toBoolean(load);
275             map.setLoadOnStartup(loadOnStartup);
276             /* load repository parameters */
277             Iterator JavaDoc params = element.getChildren(ELEMENT_PARAM).iterator();
278             Map parameters = new Hashtable JavaDoc();
279             while (params.hasNext()) {
280                 Element param = (Element) params.next();
281                 String JavaDoc value = param.getAttributeValue(ATTRIBUTE_VALUE);
282                 parameters.put(param.getAttributeValue(ATTRIBUTE_NAME), value);
283             }
284             map.setParameters(parameters);
285             List JavaDoc workspaces = element.getChildren(ELEMENT_WORKSPACE);
286             if (workspaces != null && !workspaces.isEmpty()) {
287                 Iterator JavaDoc wspIterator = workspaces.iterator();
288                 while (wspIterator.hasNext()) {
289                     Element workspace = (Element) wspIterator.next();
290                     String JavaDoc wspName = workspace.getAttributeValue(ATTRIBUTE_NAME);
291                     log.info("Loading workspace:" + wspName);
292                     map.addWorkspace(wspName);
293                 }
294             }
295             else {
296                 map.addWorkspace(DEFAULT_WORKSPACE);
297             }
298             ContentRepository.repositoryMapping.put(name, map);
299             try {
300                 loadRepository(map);
301             }
302             catch (Exception JavaDoc e) {
303                 log.error("System : Failed to load JCR \"" + map.getName() + "\" " + e.getMessage(), e); //$NON-NLS-1$ //$NON-NLS-2$
304
}
305         }
306     }
307
308     /**
309      * load repository name mapping
310      * @param root element of repositories.xml
311      */

312     private static void loadRepositoryNameMap(Element root) {
313         Element repositoryMapping = root.getChild(ContentRepository.ELEMENT_REPOSITORYMAPPING);
314         Iterator JavaDoc children = repositoryMapping.getChildren().iterator();
315         while (children.hasNext()) {
316             Element nameMap = (Element) children.next();
317             addMappedRepositoryName(
318                     nameMap.getAttributeValue(ATTRIBUTE_NAME),
319                     nameMap.getAttributeValue(ATTRIBUTE_REPOSITORY_NAME),
320                     nameMap.getAttributeValue(ATTRIBUTE_WORKSPACE_NAME));
321         }
322     }
323
324     /**
325      * This method initializes the repository. You must not call this method twice.
326      * @param map
327      * @throws RepositoryNotInitializedException
328      * @throws InstantiationException
329      * @throws IllegalAccessException
330      * @throws ClassNotFoundException
331      */

332     public static void loadRepository(RepositoryMapping map) throws RepositoryNotInitializedException,
333         InstantiationException JavaDoc, IllegalAccessException JavaDoc, ClassNotFoundException JavaDoc {
334         log.info("System : loading JCR {}", map.getName()); //$NON-NLS-1$
335
Provider handlerClass = (Provider) ClassUtil.newInstance(map.getProvider());
336         handlerClass.init(map);
337         Repository repository = handlerClass.getUnderlineRepository();
338         ContentRepository.repositories.put(map.getName(), repository);
339         ContentRepository.repositoryProviders.put(map.getName(), handlerClass);
340         if (map.isLoadOnStartup()) {
341             // load hierarchy managers for each workspace
342
Iterator JavaDoc workspaces = map.getWorkspaces().iterator();
343             while (workspaces.hasNext()) {
344                 String JavaDoc wspID = (String JavaDoc) workspaces.next();
345                 loadHierarchyManager(repository, wspID, map, handlerClass);
346             }
347         }
348     }
349
350     /**
351      * @param repositoryId
352      * @param workspaceId
353      * @throws RepositoryException
354      * */

355     public static void loadWorkspace(String JavaDoc repositoryId, String JavaDoc workspaceId) throws RepositoryException {
356         log.info("System : loading workspace {}", workspaceId); //$NON-NLS-1$
357
if(!repositoryNameMap.containsKey(workspaceId)){
358             addMappedRepositoryName(workspaceId, repositoryId, workspaceId);
359         }
360         RepositoryMapping map = getRepositoryMapping(repositoryId);
361         if(!map.getWorkspaces().contains(workspaceId)){
362             map.addWorkspace(workspaceId);
363         }
364         Provider provider = getRepositoryProvider(repositoryId);
365         provider.registerWorkspace(workspaceId);
366         loadHierarchyManager(getRepository(repositoryId), workspaceId, map, provider);
367     }
368
369     /**
370      * Load hierarchy manager for the specified repository and workspace
371      * @param repository
372      * @param wspID
373      * @param map
374      * @param provider
375      */

376     private static void loadHierarchyManager(Repository repository, String JavaDoc wspID, RepositoryMapping map,
377         Provider provider) {
378         try {
379             SimpleCredentials sc = new SimpleCredentials(REPOSITORY_USER, REPOSITORY_PSWD.toCharArray());
380             Session session = repository.login(sc, wspID);
381             provider.registerNamespace(NAMESPACE_PREFIX, NAMESPACE_URI, session.getWorkspace());
382             provider.registerNodeTypes();
383             AccessManagerImpl accessManager = getAccessManager();
384             HierarchyManager hierarchyManager = new HierarchyManager(REPOSITORY_USER);
385             hierarchyManager.init(session.getRootNode());
386             hierarchyManager.setAccessManager(accessManager);
387             ContentRepository.hierarchyManagers.put(map.getName()
388                     + "_"
389                     + getInternalWorkspaceName(wspID), hierarchyManager); //$NON-NLS-1$
390
try {
391                 QueryManager queryManager = SearchFactory.getAccessControllableQueryManager(hierarchyManager
392                     .getWorkspace()
393                     .getQueryManager(), accessManager);
394                 hierarchyManager.setQueryManager(queryManager);
395             }
396             catch (RepositoryException e) {
397                 // probably no search manager is configured for this workspace
398
log.info("QueryManager not initialized for repository {}: {}", map.getName(), e.getMessage()); //$NON-NLS-1$
399
}
400         }
401         catch (RepositoryException re) {
402             log.error("System : Failed to initialize hierarchy manager for JCR {}", map.getName()); //$NON-NLS-1$
403
log.error(re.getMessage(), re);
404         }
405     }
406
407     /**
408      * Configures and returns a AccessManager with system permissions
409      * @return The system AccessManager
410      */

411     public static AccessManagerImpl getAccessManager() {
412         List JavaDoc acl = getSystemPermissions();
413         AccessManagerImpl accessManager = new AccessManagerImpl();
414         accessManager.setPermissionList(acl);
415         return accessManager;
416     }
417
418     /**
419      * Get maximum permission available
420      * @return List of permissions
421      */

422     private static List JavaDoc getSystemPermissions() {
423         List JavaDoc acl = new ArrayList JavaDoc();
424         UrlPattern p = UrlPattern.MATCH_ALL;
425         Permission permission = new PermissionImpl();
426         permission.setPattern(p);
427         permission.setPermissions(Permission.ALL);
428         acl.add(permission);
429         return acl;
430     }
431
432     /**
433      * Builds JDOM document.
434      * @return document
435      * @throws IOException
436      * @throws JDOMException
437      */

438     private static Document buildDocument() throws JDOMException, IOException JavaDoc {
439         File JavaDoc source = Path.getRepositoriesConfigFile();
440         if (!source.exists()) {
441             throw new FileNotFoundException JavaDoc("Failed to locate magnolia repositories config file at " //$NON-NLS-1$
442
+ source.getAbsolutePath());
443         }
444         
445         return ConfigUtil.string2JDOM(ConfigUtil.replaceTokens(new FileInputStream JavaDoc(source)));
446     }
447
448     /**
449      * Get mapped repository name
450      * @param name
451      * @return mapped name as in repositories.xml RepositoryMapping element
452      */

453     public static String JavaDoc getMappedRepositoryName(String JavaDoc name) {
454         RepositoryNameMap nameMap = (RepositoryNameMap) ContentRepository.repositoryNameMap.get(name);
455         if(nameMap==null){
456             return name;
457         }
458         return nameMap.getRepositoryName();
459     }
460
461     /**
462      * Get mapped workspace name
463      * @param name
464      * @return mapped name as in repositories.xml RepositoryMapping element
465      */

466     public static String JavaDoc getMappedWorkspaceName(String JavaDoc name) {
467         RepositoryNameMap nameMap = (RepositoryNameMap) ContentRepository.repositoryNameMap.get(name);
468         return nameMap.getWorkspaceName();
469     }
470
471     /**
472      * Add a mapped repository name
473      * @param name
474      * @param repositoryName
475      */

476     public static void addMappedRepositoryName(String JavaDoc name, String JavaDoc repositoryName) {
477         addMappedRepositoryName(name, repositoryName, null);
478     }
479
480     /**
481      * Add a mapped repository name
482      * @param name
483      * @param repositoryName
484      * @param workspaceName
485      */

486     public static void addMappedRepositoryName(String JavaDoc name, String JavaDoc repositoryName, String JavaDoc workspaceName) {
487         if (StringUtils.isEmpty(workspaceName)) workspaceName = name;
488         RepositoryNameMap nameMap = new RepositoryNameMap(repositoryName, workspaceName);
489         ContentRepository.repositoryNameMap.put(name, nameMap);
490     }
491
492     /**
493      * Get default workspace name
494      * @return default name if there are no workspaces defined or there is no workspace present with name "default",
495      * otherwise return same name as repository name.
496      */

497     public static String JavaDoc getDefaultWorkspace(String JavaDoc repositoryId) {
498         RepositoryMapping mapping = getRepositoryMapping(repositoryId);
499         if (mapping == null) {
500             return DEFAULT_WORKSPACE;
501         }
502         Collection JavaDoc workspaces = mapping.getWorkspaces();
503         if (workspaces.contains(getMappedWorkspaceName(repositoryId))) {
504             return repositoryId;
505         }
506         return DEFAULT_WORKSPACE;
507     }
508
509     /**
510      * Hierarchy manager as created on startup. Note: this hierarchyManager is created with system rights and has full
511      * access on the specified repository.
512      */

513     public static HierarchyManager getHierarchyManager(String JavaDoc repositoryID) {
514         return getHierarchyManager(repositoryID, getDefaultWorkspace(repositoryID));
515     }
516
517     /**
518      * Hierarchy manager as created on startup. Note: this hierarchyManager is created with system rights and has full
519      * access on the specified repository.
520      */

521     public static HierarchyManager getHierarchyManager(String JavaDoc repositoryID, String JavaDoc workspaceID) {
522         String JavaDoc mappedRepositoryName = getMappedRepositoryName(repositoryID);
523         if (mappedRepositoryName == null) {
524             return null;
525         }
526         return (HierarchyManager) ContentRepository.hierarchyManagers.get(mappedRepositoryName + '_' + workspaceID);
527     }
528
529     /**
530      * Returns repository specified by the <code>repositoryID</code> as configured in repository config.
531      */

532     public static Repository getRepository(String JavaDoc repositoryID) {
533         String JavaDoc mappedRepositoryName = getMappedRepositoryName(repositoryID);
534         if (mappedRepositoryName == null) {
535             return null;
536         }
537         return (Repository) ContentRepository.repositories.get(mappedRepositoryName);
538     }
539
540     /**
541      * Returns repository provider specified by the <code>repositoryID</code> as configured in repository config.
542      */

543     public static Provider getRepositoryProvider(String JavaDoc repositoryID) {
544
545         Provider provider = (Provider) ContentRepository.repositoryProviders.get(repositoryID);
546
547         if (provider == null) {
548             String JavaDoc mappedRepositoryName = getMappedRepositoryName(repositoryID);
549             if (mappedRepositoryName != null) {
550                 provider = (Provider) ContentRepository.repositoryProviders.get(mappedRepositoryName);
551             }
552         }
553         return provider;
554     }
555
556     /**
557      * returns repository mapping as configured.
558      */

559     public static RepositoryMapping getRepositoryMapping(String JavaDoc repositoryID) {
560         String JavaDoc name = getMappedRepositoryName(repositoryID);
561         if (name != null && ContentRepository.repositoryMapping.containsKey(name)) {
562             return (RepositoryMapping) ContentRepository.repositoryMapping.get(getMappedRepositoryName(repositoryID));
563         }
564         log.warn("no mapping for the repository [" + repositoryID + "]");
565         return null;
566     }
567
568     /**
569      * Returns <code>true</code> if a mapping for the given repository name does exist.
570      */

571     public static boolean hasRepositoryMapping(String JavaDoc repositoryID) {
572         String JavaDoc name = getMappedRepositoryName(repositoryID);
573         return name != null;
574     }
575
576     /**
577      * Gets repository names array as configured in repositories.xml
578      * @return repository names
579      */

580     public static Iterator JavaDoc getAllRepositoryNames() {
581         return ContentRepository.repositoryNameMap.keySet().iterator();
582     }
583
584     /**
585      * get internal workspace name
586      * @param workspaceName
587      * @return workspace name as configured in magnolia repositories.xml
588      * */

589     private static String JavaDoc getInternalWorkspaceName(String JavaDoc workspaceName) {
590         Iterator JavaDoc keys = repositoryNameMap.keySet().iterator();
591         while (keys.hasNext()) {
592             String JavaDoc key = (String JavaDoc) keys.next();
593             RepositoryNameMap nameMap = (RepositoryNameMap) repositoryNameMap.get(key);
594             if (nameMap.getWorkspaceName().equalsIgnoreCase(workspaceName)) return key;
595         }
596         log.error("No Repository/Workspace name mapping defined for "+workspaceName);
597         return workspaceName;
598     }
599
600 }
601
Popular Tags