org.betaconceptframework.astroboa.configuration.RepositoryRegistry.java Source code

Java tutorial

Introduction

Here is the source code for org.betaconceptframework.astroboa.configuration.RepositoryRegistry.java

Source

/*
 * Copyright (C) 2005-2012 BetaCONCEPT Limited
 *
 * This file is part of Astroboa.
 *
 * Astroboa is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Astroboa is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Astroboa.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.betaconceptframework.astroboa.configuration;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.apache.commons.lang.StringUtils;
import org.betaconceptframework.astroboa.api.model.exception.CmsException;
import org.betaconceptframework.astroboa.configuration.SecurityType.PermanentUserKeyList.PermanentUserKey;
import org.betaconceptframework.astroboa.configuration.SecurityType.SecretUserKeyList.AdministratorSecretKey;
import org.betaconceptframework.astroboa.configuration.SecurityType.SecretUserKeyList.SecretUserKey;
import org.betaconceptframework.astroboa.util.CmsConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Astroboa Repository Registry.
 * 
 * It loads the configuration for all repositories managed by the Astroboa server.
 * 
 * It expects to find configuration file repositories-conf.xml in the path
 * specified in the system property with key {@link CmsConstants#ASTROBOA_CONFIGURATION_HOME_DIRECTORY_SYSTEM_PROPERTY_NAME}
 * 
 * It also expects to find Xml Schema astroboa-conf-{version}.xsd in 
 * the classpath inside the META-INF directory.
 * 
 * @author Gregory Chomatas (gchomatas@betaconcept.com)
 * @author Savvas Triantafyllou (striantafyllou@betaconcept.com)
 * 
 */
public enum RepositoryRegistry {

    INSTANCE;

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private String ASTROBOA_CONFIGURATION_FILE = "repositories-conf.xml";
    private String ASTROBOA_CONFIGURATION_XSD_FILEPATH = CmsConstants.FORWARD_SLASH + "META-INF"
            + CmsConstants.FORWARD_SLASH + CmsConstants.ASTROBOA_CONFIGURATION_XSD_FILENAME;

    private Unmarshaller configurationUnmarshaller;

    private Repositories repositories;

    private Map<String, RepositoryType> configurationsPerRepository = new HashMap<String, RepositoryType>();

    private Map<String, String> adminUsernamePerRepository = new HashMap<String, String>();

    private Map<String, Map<String, String>> permanentKeyPerUserPerRepository = new HashMap<String, Map<String, String>>();

    private File configuration = null;

    private long lastModified;

    private RepositoryRegistry() {

        try {
            initializeUnmarshaller();

            loadConfigurationXml();

            loadRepositoryConfigurations();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public Repositories getRepositories() {

        return repositories;
    }

    public boolean isRepositoryRegistered(String repositoryId) {
        if (repositoryId == null) {
            return false;
        }

        return configurationsPerRepository.containsKey(repositoryId);
    }

    public RepositoryType getRepositoryConfiguration(String repositoryId) {
        if (repositoryId == null) {
            return null;
        }

        return configurationsPerRepository.get(repositoryId);
    }

    public String retrieveAdminUsernameForRepository(String repositoryId) {

        if (repositoryId != null) {
            return adminUsernamePerRepository.get(repositoryId);
        }

        return null;
    }

    public String getPermanentKeyForUser(String repositoryId, String username) {

        if (StringUtils.isNotBlank(repositoryId) && StringUtils.isNotBlank(username)) {

            if (permanentKeyPerUserPerRepository.containsKey(repositoryId)) {

                Map<String, String> permanentKeys = permanentKeyPerUserPerRepository.get(repositoryId);

                if (permanentKeys.containsKey(username)) {
                    return permanentKeys.get(username);
                }
            }
        }

        return null;

    }

    public boolean isSecretKeyValidForUser(String repositoryId, String username, String key) {

        if (StringUtils.isBlank(repositoryId) || StringUtils.isBlank(key) || StringUtils.isBlank(username)) {
            return false;
        }

        if (!isRepositoryRegistered(repositoryId)) {
            return false;
        }

        RepositoryType repositoryConfiguration = getRepositoryConfiguration(repositoryId);

        final SecurityType security = repositoryConfiguration.getSecurity();

        if (security == null || repositoryConfiguration.getSecurity().getSecretUserKeyList() == null) {
            return false;
        }

        //Check if user name is administrator
        AdministratorSecretKey administratorEntry = security.getSecretUserKeyList().getAdministratorSecretKey();

        if (administratorEntry != null && StringUtils.equals(administratorEntry.getUserid(), username)) {
            return StringUtils.equals(administratorEntry.getKey(), key);
        }

        List<SecretUserKey> secretKeys = repositoryConfiguration.getSecurity().getSecretUserKeyList()
                .getSecretUserKey();

        for (SecretUserKey secretUserKey : secretKeys) {

            if (StringUtils.equals(secretUserKey.getKey(), key)) {

                List<String> userIds = Arrays.asList(StringUtils.split(secretUserKey.getUserid(), ","));

                return userIds.contains("*") || userIds.contains(username);

            }
        }

        return false;

    }

    public Map<String, RepositoryType> getConfigurationsPerRepositoryId() {
        return configurationsPerRepository;
    }

    public void loadRepositoryConfigurations() {

        InputStream is = null;

        try {

            if (configurationHasChanged() || repositories == null) {

                loadConfigurationXml();

                Map<String, RepositoryType> configurationsPerRepository = new HashMap<String, RepositoryType>();

                Map<String, String> adminUsernamePerRepository = new HashMap<String, String>();

                Map<String, Map<String, String>> permanentKeyPerUserPerRepository = new HashMap<String, Map<String, String>>();

                is = new FileInputStream(configuration);

                Repositories Repositories = (Repositories) configurationUnmarshaller
                        .unmarshal(new StreamSource(is));

                List<RepositoryType> repositoryConfigurations = Repositories.getRepository();

                if (repositoryConfigurations != null && !repositoryConfigurations.isEmpty()) {

                    for (RepositoryType repositoryConfiguration : repositoryConfigurations) {

                        String repositoryId = repositoryConfiguration.getId();

                        configurationsPerRepository.put(repositoryId, repositoryConfiguration);

                        extractAdminUsername(repositoryConfiguration, adminUsernamePerRepository);

                        extractPermanentKeyPerUser(repositoryConfiguration, permanentKeyPerUserPerRepository);
                    }
                }

                this.configurationsPerRepository = configurationsPerRepository;
                this.adminUsernamePerRepository = adminUsernamePerRepository;
                this.permanentKeyPerUserPerRepository = permanentKeyPerUserPerRepository;
                this.repositories = Repositories;

                logger.info("Astroboa Configuration {} has been loaded", configuration.getAbsolutePath());
            }
        } catch (Exception e) {
            throw new CmsException(e);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (Exception e) {
                    //Close quietly
                }
            }
        }
    }

    private void initializeUnmarshaller() throws Exception, JAXBException {

        Schema configurationXmlSchema = loadXmlSchema();

        configurationUnmarshaller = initJaxbContext().createUnmarshaller();

        configurationUnmarshaller.setSchema(configurationXmlSchema);
    }

    /**
     * @param repositoryConfiguration
     * @param permanentKeyPerUserPerRepository 
     */
    private void extractPermanentKeyPerUser(RepositoryType repositoryConfiguration,
            Map<String, Map<String, String>> permanentKeyPerUserPerRepository) {

        if (repositoryConfiguration != null && repositoryConfiguration.getSecurity() != null
                && repositoryConfiguration.getSecurity().getPermanentUserKeyList() != null
                && repositoryConfiguration.getSecurity().getPermanentUserKeyList().getPermanentUserKey() != null) {

            Map<String, String> permanentKeysPerUser = new HashMap<String, String>();

            List<PermanentUserKey> permanentUserKeys = repositoryConfiguration.getSecurity()
                    .getPermanentUserKeyList().getPermanentUserKey();

            for (PermanentUserKey permanentUserKey : permanentUserKeys) {

                if (StringUtils.isNotBlank(permanentUserKey.getUserid())) {

                    String[] userIds = permanentUserKey.getUserid().split(",");
                    String key = permanentUserKey.getKey();

                    for (String userId : userIds) {
                        permanentKeysPerUser.put(userId, key);
                    }
                }
            }

            permanentKeyPerUserPerRepository.put(repositoryConfiguration.getId(), permanentKeysPerUser);
        }

    }

    private void extractAdminUsername(RepositoryType repositoryConfiguration,
            Map<String, String> adminUsernamePerRepository) {

        final SecurityType security = repositoryConfiguration.getSecurity();

        if (security != null && repositoryConfiguration.getSecurity().getSecretUserKeyList() != null
                && security.getSecretUserKeyList().getAdministratorSecretKey() != null) {
            adminUsernamePerRepository.put(repositoryConfiguration.getId(),
                    security.getSecretUserKeyList().getAdministratorSecretKey().getUserid());
        }

    }

    private Schema loadXmlSchema() throws Exception {

        SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        schemaFactory.setResourceResolver(new W3CRelatedSchemaEntityResolver());

        //Search in classpath at root level
        URL configurationSchemaURL = this.getClass().getResource(ASTROBOA_CONFIGURATION_XSD_FILEPATH);

        if (configurationSchemaURL == null) {
            throw new Exception("Could not find " + ASTROBOA_CONFIGURATION_XSD_FILEPATH + " in classpath");
        }

        return schemaFactory.newSchema(configurationSchemaURL);
    }

    private static JAXBContext initJaxbContext() throws JAXBException {

        return JAXBContext.newInstance("org.betaconceptframework.astroboa.configuration");
    }

    private void loadConfigurationXml() throws MalformedURLException, IOException, Exception {

        if (StringUtils.isNotBlank(CmsConstants.ASTROBOA_CONFIGURATION_HOME_DIRECTORY)) {

            String configurationHomeDir = new String(CmsConstants.ASTROBOA_CONFIGURATION_HOME_DIRECTORY);

            if (CmsConstants.ASTROBOA_CONFIGURATION_HOME_DIRECTORY.startsWith("file:")) {
                configurationHomeDir = StringUtils.removeStart(configurationHomeDir, "file:");
            }

            configuration = new File(configurationHomeDir + File.separator + ASTROBOA_CONFIGURATION_FILE);

            if (!configuration.exists()) {
                throw new Exception(
                        "Astroboa Configuration " + ASTROBOA_CONFIGURATION_FILE + " could not be located in  path "
                                + configurationHomeDir + File.separator + ASTROBOA_CONFIGURATION_FILE);
            }
        } else {
            throw new Exception("Astroboa Configuration Home Directory is null. System property '"
                    + CmsConstants.ASTROBOA_CONFIGURATION_HOME_DIRECTORY_SYSTEM_PROPERTY_NAME
                    + "' does not exist or has no value ");
        }

        lastModified = configuration.lastModified();

    }

    public boolean configurationHasChanged() {

        return configuration == null || lastModified < configuration.lastModified();
    }

    public String getDefaultServerURL() {

        if (repositories != null) {
            return repositories.getServerURL();
        }

        return null;
    }

    public String getDefaultIdentityStoreId() {

        if (repositories != null) {
            return repositories.getIdentityStoreRepositoryId();
        }

        return null;
    }

    public Integer getDefaultAuthenticationTokenTimeout() {

        if (repositories != null) {
            return repositories.getAuthenticationTokenTimeout();
        }

        return null;
    }

    public File getConfiguration() {
        return configuration;
    }

    public boolean isConsistencyCheckEnabled() {

        if (repositories != null) {
            return repositories.isCheckConsistency();
        }

        return false;
    }

}