| /* |
| * Copyright (c) 2011-2013, 2015 Eike Stepper (Berlin, Germany) and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Eike Stepper - initial API and implementation |
| * Lothar Werzinger - support for configuring user managers |
| * Christian W. Damus (CEA LIST) - bug 418454 |
| */ |
| package org.eclipse.emf.cdo.spi.server; |
| |
| import org.eclipse.emf.cdo.internal.server.SessionManager; |
| import org.eclipse.emf.cdo.internal.server.bundle.OM; |
| import org.eclipse.emf.cdo.server.CDOServerUtil; |
| import org.eclipse.emf.cdo.server.IRepository; |
| import org.eclipse.emf.cdo.server.IRepositoryFactory; |
| import org.eclipse.emf.cdo.server.IStore; |
| import org.eclipse.emf.cdo.server.IStoreFactory; |
| |
| import org.eclipse.net4j.util.ObjectUtil; |
| import org.eclipse.net4j.util.StringUtil; |
| import org.eclipse.net4j.util.container.IManagedContainer; |
| import org.eclipse.net4j.util.om.OMPlatform; |
| import org.eclipse.net4j.util.om.trace.ContextTracer; |
| import org.eclipse.net4j.util.security.AuthenticatorFactory; |
| import org.eclipse.net4j.util.security.IAuthenticator; |
| import org.eclipse.net4j.util.security.IUserManager; |
| import org.eclipse.net4j.util.security.UserManagerFactory; |
| |
| import org.eclipse.emf.ecore.EPackage; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IExtensionRegistry; |
| import org.eclipse.core.runtime.Platform; |
| |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| import org.xml.sax.InputSource; |
| import org.xml.sax.SAXException; |
| |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.parsers.ParserConfigurationException; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.Reader; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| /** |
| * If the meaning of this type isn't clear, there really should be more of a description here... |
| * |
| * @author Eike Stepper |
| * @since 4.0 |
| */ |
| public class RepositoryConfigurator |
| { |
| private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REPOSITORY, RepositoryConfigurator.class); |
| |
| private IManagedContainer container; |
| |
| private Map<String, IRepositoryFactory> repositoryFactories = new HashMap<String, IRepositoryFactory>(); |
| |
| private Map<String, IStoreFactory> storeFactories = new HashMap<String, IStoreFactory>(); |
| |
| public RepositoryConfigurator() |
| { |
| this(null); |
| } |
| |
| public RepositoryConfigurator(IManagedContainer container) |
| { |
| this.container = container; |
| } |
| |
| public IManagedContainer getContainer() |
| { |
| return container; |
| } |
| |
| public Map<String, IRepositoryFactory> getRepositoryFactories() |
| { |
| return repositoryFactories; |
| } |
| |
| public Map<String, IStoreFactory> getStoreFactories() |
| { |
| return storeFactories; |
| } |
| |
| public IRepository[] configure(File configFile) |
| throws ParserConfigurationException, SAXException, IOException, CoreException |
| { |
| if (TRACER.isEnabled()) |
| { |
| TRACER.trace("Configuring CDO server from " + configFile.getAbsolutePath()); //$NON-NLS-1$ |
| } |
| |
| return configure(getDocument(configFile)); |
| } |
| |
| /** |
| * @since 4.3 |
| */ |
| public IRepository[] configure(Reader configReader) |
| throws ParserConfigurationException, SAXException, IOException, CoreException |
| { |
| if (TRACER.isEnabled()) |
| { |
| TRACER.trace("Configuring CDO server from dynamic configuration"); //$NON-NLS-1$ |
| } |
| |
| return configure(getDocument(configReader)); |
| } |
| |
| /** |
| * @since 4.3 |
| */ |
| protected IRepository[] configure(Document document) |
| throws ParserConfigurationException, SAXException, IOException, CoreException |
| { |
| List<IRepository> repositories = new ArrayList<IRepository>(); |
| NodeList elements = document.getElementsByTagName("repository"); //$NON-NLS-1$ |
| for (int i = 0; i < elements.getLength(); i++) |
| { |
| Element repositoryConfig = (Element)elements.item(i); |
| IRepository repository = getRepository(repositoryConfig); |
| repositories.add(repository); |
| |
| if (container != null) |
| { |
| CDOServerUtil.addRepository(container, repository); |
| } |
| } |
| |
| return repositories.toArray(new IRepository[repositories.size()]); |
| } |
| |
| protected Document getDocument(File configFile) throws ParserConfigurationException, SAXException, IOException |
| { |
| DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
| DocumentBuilder builder = factory.newDocumentBuilder(); |
| return builder.parse(configFile); |
| } |
| |
| /** |
| * @since 4.3 |
| */ |
| protected Document getDocument(Reader configReader) throws ParserConfigurationException, SAXException, IOException |
| { |
| DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
| DocumentBuilder builder = factory.newDocumentBuilder(); |
| return builder.parse(new InputSource(configReader)); |
| } |
| |
| protected IRepositoryFactory getRepositoryFactory(String type) throws CoreException |
| { |
| IRepositoryFactory factory = repositoryFactories.get(type); |
| if (factory == null) |
| { |
| factory = createExecutableExtension("repositoryFactories", "repositoryFactory", //$NON-NLS-1$ //$NON-NLS-2$ |
| "repositoryType", type); //$NON-NLS-1$ |
| } |
| |
| if (factory == null) |
| { |
| throw new IllegalStateException("CDORepositoryInfo factory not found: " + type); //$NON-NLS-1$ |
| } |
| |
| return factory; |
| } |
| |
| protected IRepository getRepository(Element repositoryConfig) throws CoreException |
| { |
| String repositoryName = repositoryConfig.getAttribute("name"); //$NON-NLS-1$ |
| if (StringUtil.isEmpty(repositoryName)) |
| { |
| throw new IllegalArgumentException("CDORepositoryInfo name is missing or empty"); //$NON-NLS-1$ |
| } |
| |
| String repositoryType = repositoryConfig.getAttribute("type"); //$NON-NLS-1$ |
| if (StringUtil.isEmpty(repositoryType)) |
| { |
| repositoryType = RepositoryFactory.TYPE; |
| } |
| |
| if (TRACER.isEnabled()) |
| { |
| TRACER.format("Configuring repository {0} (type={1})", repositoryName, repositoryType); //$NON-NLS-1$ |
| } |
| |
| Map<String, String> properties = getProperties(repositoryConfig, 1); |
| |
| Element storeConfig = getStoreConfig(repositoryConfig); |
| IStore store = createStore(repositoryName, properties, storeConfig); |
| |
| InternalRepository repository = (InternalRepository)getRepository(repositoryType); |
| repository.setName(repositoryName); |
| repository.setStore((InternalStore)store); |
| repository.setProperties(properties); |
| |
| setUserManager(repository, repositoryConfig); |
| setAuthenticator(repository, repositoryConfig); |
| |
| EPackage[] initialPackages = getInitialPackages(repositoryConfig); |
| if (initialPackages.length != 0) |
| { |
| repository.setInitialPackages(initialPackages); |
| } |
| |
| return repository; |
| } |
| |
| protected IRepository getRepository(String repositoryType) throws CoreException |
| { |
| IRepositoryFactory factory = getRepositoryFactory(repositoryType); |
| return factory.createRepository(); |
| } |
| |
| protected Element getUserManagerConfig(Element repositoryConfig) |
| { |
| NodeList userManagerConfig = repositoryConfig.getElementsByTagName("userManager"); //$NON-NLS-1$ |
| if (userManagerConfig.getLength() > 1) |
| { |
| String repositoryName = repositoryConfig.getAttribute("name"); //$NON-NLS-1$ |
| throw new IllegalStateException("At most one user manager must be configured for repository " + repositoryName); //$NON-NLS-1$ |
| } |
| |
| return (Element)(userManagerConfig.getLength() > 0 ? userManagerConfig.item(0) : null); |
| } |
| |
| protected IUserManager getUserManager(Element userManagerConfig) throws CoreException |
| { |
| String type = userManagerConfig.getAttribute("type"); //$NON-NLS-1$ |
| String description = userManagerConfig.getAttribute("description"); //$NON-NLS-1$ |
| return getUserManager(type, description); |
| } |
| |
| protected IUserManager getUserManager(String type, String description) throws CoreException |
| { |
| IUserManager userManager = (IUserManager)container.getElement(UserManagerFactory.PRODUCT_GROUP, type, description); |
| if (userManager == null) |
| { |
| throw new IllegalStateException("UserManager factory not found: " + type); //$NON-NLS-1$ |
| } |
| |
| return userManager; |
| } |
| |
| /** |
| * @since 4.2 |
| */ |
| @SuppressWarnings("deprecation") |
| protected void setUserManager(InternalRepository repository, Element repositoryConfig) throws CoreException |
| { |
| Element userManagerConfig = getUserManagerConfig(repositoryConfig); |
| if (userManagerConfig != null) |
| { |
| IUserManager userManager = getUserManager(userManagerConfig); |
| if (userManager != null) |
| { |
| InternalSessionManager sessionManager = repository.getSessionManager(); |
| if (sessionManager == null) |
| { |
| sessionManager = new SessionManager(); |
| repository.setSessionManager(sessionManager); |
| } |
| |
| sessionManager.setUserManager(userManager); |
| } |
| } |
| } |
| |
| /** |
| * @since 4.2 |
| */ |
| protected Element getAuthenticatorConfig(Element repositoryConfig) |
| { |
| NodeList authenticatorConfig = repositoryConfig.getElementsByTagName("authenticator"); //$NON-NLS-1$ |
| if (authenticatorConfig.getLength() > 1) |
| { |
| String repositoryName = repositoryConfig.getAttribute("name"); //$NON-NLS-1$ |
| throw new IllegalStateException("At most one authenticator must be configured for repository " + repositoryName); //$NON-NLS-1$ |
| } |
| |
| return (Element)(authenticatorConfig.getLength() > 0 ? authenticatorConfig.item(0) : null); |
| } |
| |
| /** |
| * @since 4.2 |
| */ |
| protected IAuthenticator getAuthenticator(Element authenticatorConfig) throws CoreException |
| { |
| String type = authenticatorConfig.getAttribute("type"); //$NON-NLS-1$ |
| String description = authenticatorConfig.getAttribute("description"); //$NON-NLS-1$ |
| return getAuthenticator(type, description); |
| } |
| |
| /** |
| * @since 4.2 |
| */ |
| protected IAuthenticator getAuthenticator(String type, String description) throws CoreException |
| { |
| IAuthenticator authenticator = (IAuthenticator)container.getElement(AuthenticatorFactory.PRODUCT_GROUP, type, |
| description); |
| if (authenticator == null) |
| { |
| throw new IllegalStateException("Authenticator factory not found: " + type); //$NON-NLS-1$ |
| } |
| |
| return authenticator; |
| } |
| |
| /** |
| * @since 4.2 |
| */ |
| protected void setAuthenticator(InternalRepository repository, Element repositoryConfig) throws CoreException |
| { |
| Element authenticatorConfig = getAuthenticatorConfig(repositoryConfig); |
| if (authenticatorConfig != null) |
| { |
| IAuthenticator authenticator = getAuthenticator(authenticatorConfig); |
| if (authenticator != null) |
| { |
| InternalSessionManager sessionManager = repository.getSessionManager(); |
| if (sessionManager == null) |
| { |
| sessionManager = new SessionManager(); |
| repository.setSessionManager(sessionManager); |
| } |
| |
| sessionManager.setAuthenticator(authenticator); |
| } |
| } |
| } |
| |
| protected EPackage[] getInitialPackages(Element repositoryConfig) |
| { |
| List<EPackage> result = new ArrayList<EPackage>(); |
| |
| NodeList initialPackagesConfig = repositoryConfig.getElementsByTagName("initialPackage"); //$NON-NLS-1$ |
| for (int i = 0; i < initialPackagesConfig.getLength(); i++) |
| { |
| Element initialPackageConfig = (Element)initialPackagesConfig.item(i); |
| String nsURI = initialPackageConfig.getAttribute("nsURI"); //$NON-NLS-1$ |
| if (nsURI == null) |
| { |
| throw new IllegalStateException("nsURI missing for initialPackage element"); //$NON-NLS-1$ |
| } |
| |
| EPackage initialPackage = EPackage.Registry.INSTANCE.getEPackage(nsURI); |
| if (initialPackage == null) |
| { |
| throw new IllegalStateException("Initial package not found in global package registry: " + nsURI); //$NON-NLS-1$ |
| } |
| |
| result.add(initialPackage); |
| } |
| |
| return result.toArray(new EPackage[result.size()]); |
| } |
| |
| protected Element getStoreConfig(Element repositoryConfig) |
| { |
| NodeList storeConfigs = repositoryConfig.getElementsByTagName("store"); //$NON-NLS-1$ |
| if (storeConfigs.getLength() == 0) |
| { |
| String repositoryName = repositoryConfig.getAttribute("name"); //$NON-NLS-1$ |
| throw new IllegalStateException("A store must be configured for repository " + repositoryName); //$NON-NLS-1$ |
| } |
| |
| return (Element)storeConfigs.item(0); |
| } |
| |
| protected IStoreFactory getStoreFactory(String type) throws CoreException |
| { |
| IStoreFactory factory = storeFactories.get(type); |
| if (factory == null) |
| { |
| factory = createExecutableExtension("storeFactories", "storeFactory", "storeType", type); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| } |
| |
| if (factory == null) |
| { |
| throw new IllegalStateException("Store factory not found: " + type); //$NON-NLS-1$ |
| } |
| |
| return factory; |
| } |
| |
| protected IStore createStore(String repositoryName, Map<String, String> repositoryProperties, Element storeConfig) |
| throws CoreException |
| { |
| String type = storeConfig.getAttribute("type"); //$NON-NLS-1$ |
| IStoreFactory storeFactory = getStoreFactory(type); |
| return storeFactory.createStore(repositoryName, repositoryProperties, storeConfig); |
| } |
| |
| public static Map<String, String> getProperties(Element element, int levels) |
| { |
| Map<String, String> properties = new HashMap<String, String>(); |
| collectProperties(element, "", properties, levels); //$NON-NLS-1$ |
| return properties; |
| } |
| |
| private static void collectProperties(Element element, String prefix, Map<String, String> properties, int levels) |
| { |
| if ("property".equals(element.getNodeName())) //$NON-NLS-1$ |
| { |
| String name = element.getAttribute("name"); //$NON-NLS-1$ |
| String value = element.getAttribute("value"); //$NON-NLS-1$ |
| properties.put(prefix + name, value); |
| prefix += name + "."; //$NON-NLS-1$ |
| } |
| |
| if (levels > 0) |
| { |
| NodeList childNodes = element.getChildNodes(); |
| for (int i = 0; i < childNodes.getLength(); i++) |
| { |
| Node childNode = childNodes.item(i); |
| if (childNode instanceof Element) |
| { |
| collectProperties((Element)childNode, prefix, properties, levels - 1); |
| } |
| } |
| } |
| } |
| |
| private static <T> T createExecutableExtension(String extPointName, String elementName, String attributeName, |
| String type) throws CoreException |
| { |
| if (OMPlatform.INSTANCE.isExtensionRegistryAvailable()) |
| { |
| IExtensionRegistry registry = Platform.getExtensionRegistry(); |
| IConfigurationElement[] elements = registry.getConfigurationElementsFor(OM.BUNDLE_ID, extPointName); |
| for (IConfigurationElement element : elements) |
| { |
| if (ObjectUtil.equals(element.getName(), elementName)) |
| { |
| String storeType = element.getAttribute(attributeName); |
| if (ObjectUtil.equals(storeType, type)) |
| { |
| @SuppressWarnings("unchecked") |
| T result = (T)element.createExecutableExtension("class"); //$NON-NLS-1$ |
| return result; |
| } |
| } |
| } |
| } |
| |
| return null; |
| } |
| } |