Java tutorial
/** * Copyright 2010 David Froehlich <david.froehlich@businesssoftware.at>, Samuel * Kogler <samuel.kogler@gmail.com>, Stephan Stiboller <stistc06@htlkaindorf.at> * * This file is part of Codesearch. * * Codesearch is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * Codesearch 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along with * Codesearch. If not, see <http://www.gnu.org/licenses/>. */ package org.codesearch.commons.configuration.xml; import java.io.File; import java.net.URI; import java.net.URISyntaxException; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.NoSuchElementException; import java.util.Set; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.HierarchicalConfiguration; import org.apache.commons.configuration.XMLConfiguration; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.codesearch.commons.configuration.ConfigurationReader; import org.codesearch.commons.configuration.InvalidConfigurationException; import org.codesearch.commons.configuration.dto.AuthenticationType; import org.codesearch.commons.configuration.dto.BasicAuthentication; import org.codesearch.commons.configuration.dto.CodesearchConfiguration; import org.codesearch.commons.configuration.dto.JobDto; import org.codesearch.commons.configuration.dto.NoAuthentication; import org.codesearch.commons.configuration.dto.RepositoryDto; import org.codesearch.commons.configuration.dto.SshAuthentication; import com.google.inject.Inject; import com.google.inject.Singleton; import com.google.inject.name.Named; /** * Xml implementation of the configuration reader. By default, the properties * are loaded from a file in the classpath called codesearch_config.xml. * * @author Stephan Stiboller * @author David Froehlich * @author Samuel Kogler */ @Singleton public class XmlConfigurationReader implements ConfigurationReader { private static final Logger LOG = Logger.getLogger(XmlConfigurationReader.class); /** * The XMLConfiguration object that is used to read the properties from the * XML-file */ private XMLConfiguration config; /** * The path to the configuration file. */ private String configPath = "codesearch_config.xml"; private CodesearchConfiguration codesearchConfiguration; /** * creates a new instance of XmlConfigurationReader * * @param configPath the classpath of the config file * @throws InvalidConfigurationException if the configuration file was * invalid */ @Inject public XmlConfigurationReader(@Named("configpath") String configPath) throws InvalidConfigurationException { if (StringUtils.isNotEmpty(configPath)) { this.configPath = configPath; } LOG.debug("Reading config file: " + this.configPath); loadConfig(); } /** * {@inheritDoc} */ @Override public synchronized List<JobDto> getJobs() { return codesearchConfiguration.getJobs(); } /** * {@inheritDoc} */ @Override public synchronized RepositoryDto getRepositoryByName(String name) { for (RepositoryDto repo : codesearchConfiguration.getRepositories()) { if (repo.getName().equals(name)) { return repo; } } return null; } /** * returns a list of all globally whitelisted filenames, so every filename * has to match at least one of the whitelist names (only if the whitelist * is not empty) */ public synchronized List<String> getGlobalWhitelistEntries() { return codesearchConfiguration.getGlobalWhitelist(); } /** * returns a list of all file name patterns that are listed to be ignored on * the entire system */ private synchronized List<String> getGlobalBlacklistEntries() { return codesearchConfiguration.getGlobalBlacklist(); } /** * {@inheritDoc} */ @Override public synchronized List<RepositoryDto> getRepositories() { return codesearchConfiguration.getRepositories(); } /** * {@inheritDoc} */ @Override public synchronized List<String> getRepositoryGroups() { return new LinkedList<String>(codesearchConfiguration.getRepositoryGroups()); } /** * {@inheritDoc} */ @Override public synchronized List<String> getRepositoriesForGroup(String groupName) { List<String> repos = new LinkedList<String>(); for (RepositoryDto repo : getRepositories()) { if (repo.getRepositoryGroups() != null) { if (repo.getRepositoryGroups().contains(groupName)) { repos.add(repo.getName()); } } } return repos; } /** * {@inheritDoc} */ @Override public synchronized File getCacheDirectory() { return codesearchConfiguration.getCacheDirectory(); } /** * {@inheritDoc} */ @Override public synchronized File getIndexLocation() { return codesearchConfiguration.getIndexLocation(); } /** * {@inheritDoc} */ @Override public synchronized URI getSearcherLocation() { return codesearchConfiguration.getSearcherLocation(); } /** * {@inheritDoc} */ @Override public synchronized void refresh() { try { loadConfig(); } catch (InvalidConfigurationException e) { LOG.fatal("Reload of configuration failed: \n" + e); } } // TODO perform config value validation here private void loadConfig() throws InvalidConfigurationException { codesearchConfiguration = new CodesearchConfiguration(); try { config = new XMLConfiguration(this.configPath); if (config == null) { throw new InvalidConfigurationException("Config was null at: " + this.configPath); } config.setDelimiterParsingDisabled(true); } catch (ConfigurationException ex) { throw new InvalidConfigurationException("Configuration file could not be read:\n" + ex); } loadCacheDirectory(); loadIndexLocation(); loadSearcherLocation(); loadGlobalBlacklist(); loadGlobalWhitelist(); loadRepositories(); loadJobs(); } private void loadCacheDirectory() throws InvalidConfigurationException { File cacheDirectory = null; try { cacheDirectory = new File(config.getString(XmlConfigurationReaderConstants.CACHE_DIR)); } catch (NullPointerException ex) { throw new InvalidConfigurationException("Cache directory not specified"); } codesearchConfiguration.setCacheDirectory(cacheDirectory); } private void loadIndexLocation() throws InvalidConfigurationException { File indexLocation = null; try { indexLocation = new File(config.getString(XmlConfigurationReaderConstants.INDEX_DIR)); } catch (NullPointerException ex) { throw new InvalidConfigurationException("Index location not specified"); } codesearchConfiguration.setIndexLocation(indexLocation); } private void loadSearcherLocation() throws InvalidConfigurationException { try { URI searcherLocation = new URI(config.getString(XmlConfigurationReaderConstants.SEARCHER_LOCATION)); codesearchConfiguration.setSearcherLocation(searcherLocation); } catch (URISyntaxException ex) { throw new InvalidConfigurationException("Searcher location is not a valid URI: " + ex); } } private void loadRepositories() throws InvalidConfigurationException { List<RepositoryDto> repositories = new LinkedList<RepositoryDto>(); Set<String> repositoryGroups = new HashSet<String>(); @SuppressWarnings("unchecked") List<HierarchicalConfiguration> repositoryConfigs = config .configurationsAt(XmlConfigurationReaderConstants.REPOSITORY_LIST); for (HierarchicalConfiguration repositoryConfig : repositoryConfigs) { RepositoryDto repo = loadRepository(repositoryConfig); repositoryGroups.addAll(repo.getRepositoryGroups()); repositories.add(repo); } codesearchConfiguration.setRepositoryGroups(new LinkedList<String>(repositoryGroups)); codesearchConfiguration.setRepositories(repositories); } /** * retrieves all required data about the given repository from the * configuration via the HierarchicalConfiguration and returns it as a * RepositoryDto */ @SuppressWarnings("unchecked") private RepositoryDto loadRepository(HierarchicalConfiguration hc) throws InvalidConfigurationException { RepositoryDto repo; //mandatory field String name = hc.getString(XmlConfigurationReaderConstants.REPOSITORY_NAME); // retrieve the repository blacklisted filenames and add all global filenames List<String> blacklistEntries = hc.getList(XmlConfigurationReaderConstants.REPOSITORY_BLACKLIST); if (blacklistEntries == null) { blacklistEntries = new LinkedList<String>(); } blacklistEntries.addAll(getGlobalBlacklistEntries()); // retrieve the repository whitelisted filenames and add all global filenames List<String> whitelistFileNames = hc .getList(XmlConfigurationReaderConstants.REPOSITORY_WHITELIST_FILENAMES); if (whitelistFileNames == null) { whitelistFileNames = new LinkedList<String>(); } whitelistFileNames.addAll(getGlobalWhitelistEntries()); String repoGroupString = hc.getString(XmlConfigurationReaderConstants.REPOSITORY_GROUPS); List<String> repositoryGroups = Arrays.asList(repoGroupString.split(" ")); // retrieve the used authentication system and fill it with the required data AuthenticationType usedAuthentication = null; String authenticationType = hc.getString(XmlConfigurationReaderConstants.REPOSITORY_AUTHENTICATION_DATA); if (authenticationType == null || authenticationType.trim().isEmpty() || authenticationType.equals("none")) { usedAuthentication = new NoAuthentication(); } else if (authenticationType.equals("basic")) { String username = hc.getString(XmlConfigurationReaderConstants.REPOSITORY_AUTHENTICATION_DATA_USERNAME); String password = hc.getString(XmlConfigurationReaderConstants.REPOSITORY_AUTHENTICATION_DATA_PASSWORD); usedAuthentication = new BasicAuthentication(username, password); } else if (authenticationType.equals("ssh")) { String sshFilePath = hc .getString(XmlConfigurationReaderConstants.REPOSITORY_AUTHENTICATION_DATA_SSH_FILE_PATH); String username = hc.getString(XmlConfigurationReaderConstants.REPOSITORY_AUTHENTICATION_DATA_USERNAME); String password = hc.getString(XmlConfigurationReaderConstants.REPOSITORY_AUTHENTICATION_DATA_PASSWORD); String port = hc.getString(XmlConfigurationReaderConstants.REPOSITORY_AUTHENTICATION_DATA_PORT); usedAuthentication = new SshAuthentication(username, password, port, sshFilePath); } String versionControlSystem = hc.getString(XmlConfigurationReaderConstants.REPOSITORY_VCS); repo = new RepositoryDto(name, hc.getString(XmlConfigurationReaderConstants.REPOSITORY_URL), usedAuthentication, hc.getBoolean(XmlConfigurationReaderConstants.REPOSITORY_CODE_NAVIGATION_ENABLED), versionControlSystem, blacklistEntries, whitelistFileNames, repositoryGroups); LOG.info("Read repository: " + repo.getName()); return repo; } @SuppressWarnings("unchecked") private void loadJobs() throws InvalidConfigurationException { List<JobDto> jobs = new LinkedList<JobDto>(); // read the configuration for the jobs from the config List<HierarchicalConfiguration> jobConfig = config .configurationsAt(XmlConfigurationReaderConstants.INDEX_JOB); for (HierarchicalConfiguration hc : jobConfig) { // reads job specific values and adds them to the JobDto JobDto job = new JobDto(); String cronExpression; try { cronExpression = hc.getString(XmlConfigurationReaderConstants.JOB_CRON_EXPRESSION); } catch (NoSuchElementException ex) { // in case no interval was specified the job is set to execute only once cronExpression = ""; } job.setCronExpression(cronExpression); String repositoryString = hc.getString(XmlConfigurationReaderConstants.JOB_REPOSITORY); // The list of repositories this job is associated with, each task specified in the configuration is created for each of // these repositories List<RepositoryDto> repositoriesForJob = getRepositoriesByNames(repositoryString); job.setRepositories(repositoriesForJob); boolean clearIndex = hc.getBoolean(XmlConfigurationReaderConstants.JOB_CLEAR, false); job.setClearIndex(clearIndex); job.setJobDescription(hc.getString(XmlConfigurationReaderConstants.JOB_DESCRIPTION, "")); jobs.add(job); } codesearchConfiguration.setJobs(jobs); } @SuppressWarnings("unchecked") private void loadGlobalWhitelist() { List<String> globalWhitelist = config.getList(XmlConfigurationReaderConstants.GLOBAL_WHITELIST); codesearchConfiguration.setGlobalWhitelist(globalWhitelist); } @SuppressWarnings("unchecked") private void loadGlobalBlacklist() { List<String> globalBlacklist = config.getList(XmlConfigurationReaderConstants.GLOBAL_BLACKLIST); codesearchConfiguration.setGlobalBlacklist(globalBlacklist); } /** * Takes a string of repository names and returns a {@link List} of the * corresponding {@link RepositoryDto} objects. * * @param repositoryNames The names of the repositories in a single string * separated by spaces. * @return the {@link List} of {@link RepositoryDto}s. */ private List<RepositoryDto> getRepositoriesByNames(String repositoryNames) { if (repositoryNames == null) { return getRepositories(); } List<RepositoryDto> repos = new LinkedList<RepositoryDto>(); for (String name : repositoryNames.split(" ")) { for (RepositoryDto repositoryDto : codesearchConfiguration.getRepositories()) { if (repositoryDto.getName().equals(name)) { repos.add(repositoryDto); } } } return repos; } }