Java tutorial
/** * * Magnolia and its source-code is licensed under the LGPL. * You may copy, adapt, and redistribute this file for commercial or non-commercial use. * When copying, adapting, or redistributing this document in keeping with the guidelines above, * you are required to provide proper attribution to obinary. * If you reproduce or distribute the document without making any substantive modifications to its content, * please use the following attribution line: * * Copyright 1993-2006 obinary Ltd. (http://www.obinary.com) All rights reserved. * */ package info.magnolia.cms.beans.config; import info.magnolia.cms.core.Content; import info.magnolia.cms.core.HierarchyManager; import info.magnolia.cms.core.ItemType; import info.magnolia.cms.core.Path; import info.magnolia.cms.core.SystemProperty; import info.magnolia.cms.core.search.QueryManager; import info.magnolia.cms.core.search.SearchFactory; import info.magnolia.cms.security.AccessDeniedException; import info.magnolia.cms.security.AccessManagerImpl; import info.magnolia.cms.security.Permission; import info.magnolia.cms.security.PermissionImpl; import info.magnolia.cms.util.UrlPattern; import info.magnolia.repository.Provider; import info.magnolia.repository.RepositoryMapping; import info.magnolia.repository.RepositoryNotInitializedException; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.SimpleCredentials; import org.apache.commons.lang.BooleanUtils; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Sameer Charles $Id :$ */ public final class ContentRepository { /** * default repository ID's. */ public static final String WEBSITE = "website"; //$NON-NLS-1$ public static final String USERS = "users"; //$NON-NLS-1$ public static final String USER_ROLES = "userroles"; //$NON-NLS-1$ public static final String USER_GROUPS = "usergroups"; //$NON-NLS-1$ public static final String CONFIG = "config"; //$NON-NLS-1$ public static final String DEFAULT_WORKSPACE = "default"; //$NON-NLS-1$ public static final String VERSION_STORE = "mgnlVersion"; /** * magnolia namespace. */ public static final String NAMESPACE_PREFIX = "mgnl"; //$NON-NLS-1$ public static final String NAMESPACE_URI = "http://www.magnolia.info/jcr/mgnl"; //$NON-NLS-1$ /** * Logger. */ private static Logger log = LoggerFactory.getLogger(ContentRepository.class); /** * repository element string. */ private static final String ELEMENT_REPOSITORY = "Repository"; //$NON-NLS-1$ private static final String ELEMENT_REPOSITORYMAPPING = "RepositoryMapping"; //$NON-NLS-1$ private static final String ELEMENT_PARAM = "param"; //$NON-NLS-1$ private static final String ELEMENT_WORKSPACE = "workspace"; //$NON-NLS-1$ /** * Attribute names. */ private static final String ATTRIBUTE_NAME = "name"; //$NON-NLS-1$ private static final String ATTRIBUTE_LOAD_ON_STARTUP = "loadOnStartup"; //$NON-NLS-1$ private static final String ATTRIBUTE_PROVIDER = "provider"; //$NON-NLS-1$ private static final String ATTRIBUTE_VALUE = "value"; //$NON-NLS-1$ private static final String ATTRIBUTE_REPOSITORY_NAME = "repositoryName"; //$NON-NLS-1$ /** * repository user. */ public static final String REPOSITORY_USER = SystemProperty.getProperty("magnolia.connection.jcr.userId"); /** * repository default password */ public static final String REPOSITORY_PSWD = SystemProperty.getProperty("magnolia.connection.jcr.password"); /** * All available repositories store. */ private static Map repositories = new Hashtable(); /** * JCR providers as mapped in repositories.xml. */ private static Map repositoryProviders = new Hashtable(); /** * All server hierarchy managers with full access to specific repositories. */ private static Map hierarchyManagers = new Hashtable(); /** * Repositories configuration as defined in repositories mapping file via attribute * <code>magnolia.repositories.config</code>. */ private static Map repositoryMapping = new Hashtable(); /** * holds all repository names as configured in repositories.xml */ private static Map repositoryNameMap = new Hashtable(); /** * Utility class, don't instantiate. */ private ContentRepository() { // unused constructor } /** * loads all configured repository using ID as Key, as configured in repositories.xml. * * <pre> * <Repository name="website" * id="website" * provider="info.magnolia.jackrabbit.ProviderImpl" * loadOnStartup="true" > * <param name="configFile" * value="WEB-INF/config/repositories/website.xml"/> * <param name="repositoryHome" * value="repositories/website"/> * <param name="contextFactoryClass" * value="org.apache.jackrabbit.core.jndi.provider.DummyInitialContextFactory"/> * <param name="providerURL" * value="localhost"/> * <param name="id" value="website"/> * </Repository> *</pre> */ public static void init() { log.info("System : loading JCR"); //$NON-NLS-1$ repositories.clear(); hierarchyManagers.clear(); try { loadRepositories(); log.info("System : JCR loaded"); //$NON-NLS-1$ } catch (Exception e) { log.error(e.getMessage(), e); } } /** * Verify the initialization state of all the repositories. This methods returns <code>false</code> only if * <strong>all</strong> the repositories are empty (no node else than the root one). * @return <code>false</code> if all the repositories are empty, <code>true</code> if at least one of them has * content. * @throws AccessDeniedException repository authentication failed * @throws RepositoryException exception while accessing the repository */ public static boolean checkIfInitialized() throws AccessDeniedException, RepositoryException { Iterator repositoryNames = getAllRepositoryNames(); while (repositoryNames.hasNext()) { String repository = (String) repositoryNames.next(); if (log.isDebugEnabled()) { log.debug("Checking [" + repository + "] repository."); //$NON-NLS-1$ //$NON-NLS-2$ } HierarchyManager hm = getHierarchyManager(repository); if (hm == null) { throw new RuntimeException("Repository [" + repository + "] not loaded"); //$NON-NLS-1$ //$NON-NLS-2$ } Content startPage = hm.getRoot(); if (startPage.getChildren(ItemType.CONTENT).size() > 0) { if (log.isDebugEnabled()) { log.debug("Content found in [" + repository + "]."); //$NON-NLS-1$ //$NON-NLS-2$ } return true; } } return false; } /** * Re-load all configured repositories. * @see #init() */ public static void reload() { log.info("System : reloading JCR"); //$NON-NLS-1$ ContentRepository.init(); } /** * Load repository mappings and params using repositories.xml * @throws Exception */ private static void loadRepositories() throws Exception { Document document = buildDocument(); Element root = document.getRootElement(); loadRepositoryNameMap(root); Collection repositoryElements = root.getChildren(ContentRepository.ELEMENT_REPOSITORY); Iterator children = repositoryElements.iterator(); while (children.hasNext()) { Element element = (Element) children.next(); String name = element.getAttributeValue(ATTRIBUTE_NAME); String load = element.getAttributeValue(ATTRIBUTE_LOAD_ON_STARTUP); String provider = element.getAttributeValue(ATTRIBUTE_PROVIDER); RepositoryMapping map = new RepositoryMapping(); map.setName(name); map.setProvider(provider); boolean loadOnStartup = BooleanUtils.toBoolean(load); map.setLoadOnStartup(loadOnStartup); /* load repository parameters */ Iterator params = element.getChildren(ELEMENT_PARAM).iterator(); Map parameters = new Hashtable(); while (params.hasNext()) { Element param = (Element) params.next(); parameters.put(param.getAttributeValue(ATTRIBUTE_NAME), param.getAttributeValue(ATTRIBUTE_VALUE)); } map.setParameters(parameters); List workspaces = element.getChildren(ELEMENT_WORKSPACE); if (workspaces != null && !workspaces.isEmpty()) { Iterator wspIterator = workspaces.iterator(); while (wspIterator.hasNext()) { Element workspace = (Element) wspIterator.next(); String wspName = workspace.getAttributeValue(ATTRIBUTE_NAME); log.info("Loading workspace:" + wspName); map.addWorkspace(wspName); } } else { map.addWorkspace(DEFAULT_WORKSPACE); } ContentRepository.repositoryMapping.put(name, map); try { loadRepository(map); } catch (Exception e) { log.error("System : Failed to load JCR \"" + map.getName() + "\" " + e.getMessage(), e); //$NON-NLS-1$ //$NON-NLS-2$ } } } /** * load repository name mapping * @param root element of repositories.xml */ private static void loadRepositoryNameMap(Element root) { Element repositoryMapping = root.getChild(ContentRepository.ELEMENT_REPOSITORYMAPPING); Iterator children = repositoryMapping.getChildren().iterator(); while (children.hasNext()) { Element nameMap = (Element) children.next(); addMappedRepositoryName(nameMap.getAttributeValue(ATTRIBUTE_NAME), nameMap.getAttributeValue(ATTRIBUTE_REPOSITORY_NAME)); } } /** * This method initializes the repository. You must not call this method twice. * @param map * @throws RepositoryNotInitializedException * @throws InstantiationException * @throws IllegalAccessException * @throws ClassNotFoundException */ public static void loadRepository(RepositoryMapping map) throws RepositoryNotInitializedException, InstantiationException, IllegalAccessException, ClassNotFoundException { log.info("System : loading JCR {}", map.getName()); //$NON-NLS-1$ Provider handlerClass = (Provider) Class.forName(map.getProvider()).newInstance(); handlerClass.init(map); Repository repository = handlerClass.getUnderlineRepository(); ContentRepository.repositories.put(map.getName(), repository); ContentRepository.repositoryProviders.put(map.getName(), handlerClass); if (map.isLoadOnStartup()) { // load hierarchy managers for each workspace Iterator workspaces = map.getWorkspaces().iterator(); while (workspaces.hasNext()) { String wspID = (String) workspaces.next(); loadHierarchyManager(repository, wspID, map, handlerClass); } } } /** * Load hierarchy manager for the specified repository and workspace * @param repository * @param wspID * @param map * @param provider */ private static void loadHierarchyManager(Repository repository, String wspID, RepositoryMapping map, Provider provider) { try { SimpleCredentials sc = new SimpleCredentials(REPOSITORY_USER, REPOSITORY_PSWD.toCharArray()); Session session = repository.login(sc, wspID); provider.registerNamespace(NAMESPACE_PREFIX, NAMESPACE_URI, session.getWorkspace()); provider.registerNodeTypes(); AccessManagerImpl accessManager = getAccessManager(); HierarchyManager hierarchyManager = new HierarchyManager(REPOSITORY_USER); hierarchyManager.init(session.getRootNode()); hierarchyManager.setAccessManager(accessManager); ContentRepository.hierarchyManagers.put(map.getName() + "_" + wspID, hierarchyManager); //$NON-NLS-1$ try { QueryManager queryManager = SearchFactory.getAccessControllableQueryManager( hierarchyManager.getWorkspace().getQueryManager(), accessManager); hierarchyManager.setQueryManager(queryManager); } catch (RepositoryException e) { // probably no search manager is configured for this workspace log.info("QueryManager not initialized for repository {}: {}", map.getName(), e.getMessage()); //$NON-NLS-1$ } } catch (RepositoryException re) { log.error("System : Failed to initialize hierarchy manager for JCR {}", map.getName()); //$NON-NLS-1$ log.error(re.getMessage(), re); } } /** * Configures and returns a AccessManager with system permissions * @return The system AccessManager */ public static AccessManagerImpl getAccessManager() { List acl = getSystemPermissions(); AccessManagerImpl accessManager = new AccessManagerImpl(); accessManager.setPermissionList(acl); return accessManager; } /** * Get maximum permission available * @return List of permissions */ private static List getSystemPermissions() { List acl = new ArrayList(); UrlPattern p = UrlPattern.MATCH_ALL; Permission permission = new PermissionImpl(); permission.setPattern(p); permission.setPermissions(Permission.ALL); acl.add(permission); return acl; } /** * Builds JDOM document. * @return document * @throws IOException * @throws JDOMException */ private static Document buildDocument() throws JDOMException, IOException { File source = Path.getRepositoriesConfigFile(); if (!source.exists()) { throw new FileNotFoundException("Failed to locate magnolia repositories config file at " //$NON-NLS-1$ + source.getAbsolutePath()); } SAXBuilder builder = new SAXBuilder(); return builder.build(source); } /** * Get mapped repository name * @param name * @return mapped name as in repositories.xml RepositoryMapping element */ public static String getMappedRepositoryName(String name) { return (String) ContentRepository.repositoryNameMap.get(name); } /** * Add a mapped repository name * @param name * @param repositoryName * @return mapped name as in repositories.xml RepositoryMapping element */ public static void addMappedRepositoryName(String name, String repositoryName) { ContentRepository.repositoryNameMap.put(name, repositoryName); } /** * Get default workspace name * @return default name if there are no workspaces defined or there is no workspace present with name "default", * otherwise return same name as repository name. */ public static String getDefaultWorkspace(String repositoryId) { RepositoryMapping mapping = getRepositoryMapping(repositoryId); if (mapping == null) { return DEFAULT_WORKSPACE; } Collection workspaces = mapping.getWorkspaces(); if (workspaces.contains(repositoryId)) { return repositoryId; } return DEFAULT_WORKSPACE; } /** * Hierarchy manager as created on startup. Note: this hierarchyManager is created with system rights and has full * access on the specified repository. */ public static HierarchyManager getHierarchyManager(String repositoryID) { return getHierarchyManager(repositoryID, getDefaultWorkspace(repositoryID)); } /** * Hierarchy manager as created on startup. Note: this hierarchyManager is created with system rights and has full * access on the specified repository. */ public static HierarchyManager getHierarchyManager(String repositoryID, String workspaceID) { String mappedRepositoryName = getMappedRepositoryName(repositoryID); if (mappedRepositoryName == null) { return null; } return (HierarchyManager) ContentRepository.hierarchyManagers.get(mappedRepositoryName + '_' + workspaceID); } /** * Returns repository specified by the <code>repositoryID</code> as configured in repository config. */ public static Repository getRepository(String repositoryID) { String mappedRepositoryName = getMappedRepositoryName(repositoryID); if (mappedRepositoryName == null) { return null; } return (Repository) ContentRepository.repositories.get(mappedRepositoryName); } /** * Returns repository provider specified by the <code>repositoryID</code> as configured in repository config. */ public static Provider getRepositoryProvider(String repositoryID) { Provider provider = (Provider) ContentRepository.repositoryProviders.get(repositoryID); if (provider == null) { String mappedRepositoryName = getMappedRepositoryName(repositoryID); if (mappedRepositoryName != null) { provider = (Provider) ContentRepository.repositoryProviders.get(mappedRepositoryName); } } return provider; } /** * returns repository mapping as configured. */ public static RepositoryMapping getRepositoryMapping(String repositoryID) { String name = getMappedRepositoryName(repositoryID); if (name != null && ContentRepository.repositoryMapping.containsKey(name)) { return (RepositoryMapping) ContentRepository.repositoryMapping .get(getMappedRepositoryName(repositoryID)); } log.warn("no mapping for the repository [{}]", repositoryID); return null; } /** * Gets repository names array as configured in repositories.xml * @return repository names */ public static Iterator getAllRepositoryNames() { return ContentRepository.repositoryNameMap.keySet().iterator(); } }