0N/A/*
0N/A * CDDL HEADER START
0N/A *
0N/A * The contents of this file are subject to the terms of the
0N/A * Common Development and Distribution License (the "License").
0N/A * You may not use this file except in compliance with the License.
0N/A *
0N/A * See LICENSE.txt included in this distribution for the specific
0N/A * language governing permissions and limitations under the License.
0N/A *
0N/A * When distributing Covered Code, include this CDDL HEADER in each
0N/A * file and include the License file at LICENSE.txt.
0N/A * If applicable, add the following below this CDDL HEADER, with the
0N/A * fields enclosed by brackets "[]" replaced with your own identifying
0N/A * information: Portions Copyright [yyyy] [name of copyright owner]
0N/A *
0N/A * CDDL HEADER END
0N/A */
0N/A
0N/A/*
1403N/A * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
0N/A */
0N/Apackage org.opensolaris.opengrok.history;
0N/A
182N/Aimport java.io.File;
182N/Aimport java.io.IOException;
182N/Aimport java.io.InputStream;
240N/Aimport java.util.ArrayList;
966N/Aimport java.util.Collection;
1403N/Aimport java.util.Collections;
1403N/Aimport java.util.Date;
8N/Aimport java.util.HashMap;
240N/Aimport java.util.List;
8N/Aimport java.util.Map;
879N/Aimport java.util.Set;
701N/Aimport java.util.concurrent.ExecutorService;
701N/Aimport java.util.concurrent.Executors;
701N/Aimport java.util.concurrent.TimeUnit;
416N/Aimport java.util.logging.Level;
590N/Aimport java.util.logging.Logger;
416N/Aimport org.opensolaris.opengrok.OpenGrokLogger;
58N/Aimport org.opensolaris.opengrok.configuration.RuntimeEnvironment;
186N/Aimport org.opensolaris.opengrok.index.IgnoredNames;
0N/A
0N/A/**
0N/A * The HistoryGuru is used to implement an transparent layer to the various
0N/A * source control systems.
0N/A *
0N/A * @author Chandan
0N/A */
439N/Apublic final class HistoryGuru {
715N/A private static final Logger log = OpenGrokLogger.getLogger();
715N/A
0N/A /** The one and only instance of the HistoryGuru */
0N/A private static HistoryGuru instance = new HistoryGuru();
99N/A
353N/A /** The history cache to use */
456N/A private final HistoryCache historyCache;
1190N/A
1190N/A private Map<String, Repository> repositories =
1183N/A new HashMap<String, Repository>();
1183N/A private final int scanningDepth;
330N/A
0N/A /**
0N/A * Creates a new instance of HistoryGuru, and try to set the default
0N/A * source control system.
0N/A */
0N/A private HistoryGuru() {
772N/A HistoryCache cache = null;
773N/A RuntimeEnvironment env = RuntimeEnvironment.getInstance();
993N/A scanningDepth=env.getScanningDepth();
773N/A if (env.useHistoryCache()) {
773N/A if (env.storeHistoryCacheInDB()) {
772N/A cache = new JDBCHistoryCache();
772N/A } else {
772N/A cache = new FileHistoryCache();
772N/A }
772N/A try {
772N/A cache.initialize();
772N/A } catch (HistoryException he) {
772N/A log.log(Level.WARNING,
772N/A "Failed to initialize the history cache", he);
772N/A // Failed to initialize, run without a history cache
772N/A cache = null;
772N/A }
715N/A }
772N/A historyCache = cache;
0N/A }
1190N/A
0N/A /**
0N/A * Get the one and only instance of the HistoryGuru
0N/A * @return the one and only HistoryGuru instance
0N/A */
0N/A public static HistoryGuru getInstance() {
0N/A return instance;
0N/A }
83N/A
0N/A /**
772N/A * Return whether or not a cache should be used for the history log.
772N/A * @return {@code true} if the history cache has been enabled and
772N/A * initialized, {@code false} otherwise
772N/A */
772N/A private boolean useCache() {
772N/A return historyCache != null;
772N/A }
772N/A
772N/A /**
864N/A * Get a string with information about the history cache.
864N/A *
864N/A * @return a free form text string describing the history cache instance
864N/A * @throws HistoryException if an error occurred while getting the info
864N/A */
864N/A public String getCacheInfo() throws HistoryException {
864N/A return historyCache == null ? "No cache" : historyCache.getInfo();
864N/A }
864N/A
864N/A /**
84N/A * Annotate the specified revision of a file.
84N/A *
84N/A * @param file the file to annotate
84N/A * @param rev the revision to annotate (<code>null</code> means BASE)
87N/A * @return file annotation, or <code>null</code> if the
87N/A * <code>HistoryParser</code> does not support annotation
1190N/A * @throws IOException
84N/A */
459N/A public Annotation annotate(File file, String rev) throws IOException {
543N/A Annotation ret = null;
543N/A
290N/A Repository repos = getRepository(file);
176N/A if (repos != null) {
543N/A ret = repos.annotate(file, rev);
878N/A History hist = null;
878N/A try {
878N/A hist = repos.getHistory(file);
878N/A } catch (HistoryException ex) {
1190N/A Logger.getLogger(HistoryGuru.class.getName()).log(Level.FINEST,
1182N/A "Cannot get messages for tooltip: ", ex);
878N/A }
1182N/A if (hist != null && ret != null) {
879N/A Set<String> revs=ret.getRevisions();
1182N/A // !!! cannot do this because of not matching rev ids (keys)
1190N/A // first is the most recent one, so we need the position of "rev"
1182N/A // until the end of the list
878N/A //if (hent.indexOf(rev)>0) {
1182N/A // hent = hent.subList(hent.indexOf(rev), hent.size());
878N/A //}
1182N/A for (HistoryEntry he : hist.getHistoryEntries()) {
878N/A String cmr=he.getRevision();
1190N/A //TODO this is only for mercurial, for other SCMs it might also
1190N/A // be a problem, we need to revise how we shorten the rev # for
1182N/A // annotate
1190N/A String[] brev=cmr.split(":");
878N/A if (revs.contains(brev[0])) {
1182N/A ret.addDesc(brev[0], "changeset: "+he.getRevision()
1182N/A +"\nsummary: "+he.getMessage()+"\nuser: "
1182N/A +he.getAuthor()+"\ndate: "+he.getDate());
878N/A }
878N/A }
878N/A }
84N/A }
176N/A
543N/A return ret;
84N/A }
84N/A
84N/A /**
1190N/A * Get the appropriate history reader for the file specified by parent and
1183N/A * basename.
0N/A *
25N/A * @param file The file to get the history reader for
615N/A * @throws HistoryException If an error occurs while getting the history
1183N/A * @return A HistorReader that may be used to read out history data for a
1183N/A * named file
0N/A */
615N/A public HistoryReader getHistoryReader(File file) throws HistoryException {
839N/A History history = getHistory(file, false);
829N/A return history == null ? null : new HistoryReader(history);
829N/A }
829N/A
829N/A /**
829N/A * Get the history for the specified file.
829N/A *
829N/A * @param file the file to get the history for
829N/A * @return history for the file
829N/A * @throws HistoryException on error when accessing the history
829N/A */
829N/A public History getHistory(File file) throws HistoryException {
839N/A return getHistory(file, true);
839N/A }
839N/A
839N/A /**
839N/A * Get the history for the specified file.
839N/A *
839N/A * @param file the file to get the history for
839N/A * @param withFiles whether or not the returned history should contain
839N/A * a list of files touched by each changeset (the file list may be skipped
839N/A * if false, but it doesn't have to)
839N/A * @return history for the file
839N/A * @throws HistoryException on error when accessing the history
839N/A */
839N/A public History getHistory(File file, boolean withFiles)
839N/A throws HistoryException {
772N/A final File dir = file.isDirectory() ? file : file.getParentFile();
772N/A final Repository repos = getRepository(dir);
25N/A
829N/A History history = null;
829N/A
1183N/A if (repos != null && repos.isWorking() && repos.fileHasHistory(file)
1183N/A && (!repos.isRemote() || RuntimeEnvironment.getInstance()
1190N/A .isRemoteScmSupported()))
1183N/A {
887N/A if (useCache() && historyCache.supportsRepository(repos)) {
839N/A history = historyCache.get(file, repos, withFiles);
839N/A } else {
839N/A history = repos.getHistory(file);
839N/A }
25N/A }
25N/A
829N/A return history;
0N/A }
50N/A
0N/A /**
0N/A * Get a named revision of the specified file.
0N/A * @param parent The directory containing the file
0N/A * @param basename The name of the file
0N/A * @param rev The revision to get
0N/A * @return An InputStream containing the named revision of the file.
0N/A */
1190N/A public InputStream getRevision(String parent, String basename, String rev)
1183N/A {
543N/A InputStream ret = null;
543N/A
353N/A Repository rep = getRepository(new File(parent));
353N/A if (rep != null) {
543N/A ret = rep.getHistoryGet(parent, basename, rev);
0N/A }
543N/A return ret;
0N/A }
1190N/A
0N/A /**
0N/A * Does this directory contain files with source control information?
258N/A * @param file The name of the directory
1190N/A * @return true if the files in this directory have associated revision
1183N/A * history
0N/A */
256N/A public boolean hasHistory(File file) {
290N/A Repository repos = getRepository(file);
703N/A
1183N/A return repos == null
1183N/A ? false
1183N/A : repos.isWorking() && repos.fileHasHistory(file)
1190N/A && (RuntimeEnvironment.getInstance().isRemoteScmSupported()
1183N/A || !repos.isRemote());
0N/A }
93N/A
93N/A /**
93N/A * Check if we can annotate the specified file.
93N/A *
93N/A * @param file the file to check
93N/A * @return <code>true</code> if the file is under version control and the
93N/A * version control system supports annotation
93N/A */
93N/A public boolean hasAnnotation(File file) {
176N/A if (!file.isDirectory()) {
290N/A Repository repos = getRepository(file);
435N/A if (repos != null && repos.isWorking()) {
298N/A return repos.fileHasAnnotation(file);
176N/A }
93N/A }
1190N/A
176N/A return false;
93N/A }
93N/A
1403N/A /**
1403N/A * Get the last modified times for all files and subdirectories in the
1403N/A * specified directory.
1403N/A *
1403N/A * @param directory the directory whose files to check
1403N/A * @return a map from file names to modification times for the files that
1403N/A * the history cache has information about
1403N/A */
1403N/A public Map<String, Date> getLastModifiedTimes(File directory)
1403N/A throws HistoryException {
1403N/A Repository repository = getRepository(directory);
1403N/A if (repository != null && useCache()) {
1403N/A return historyCache.getLastModifiedTimes(directory, repository);
1403N/A }
1403N/A return Collections.emptyMap();
1403N/A }
1403N/A
1183N/A private void addRepositories(File[] files, Collection<RepositoryInfo> repos,
1190N/A IgnoredNames ignoredNames, int depth)
1183N/A {
993N/A addRepositories(files, repos, ignoredNames, true, depth);
317N/A }
317N/A
993N/A /**
993N/A * recursivelly search for repositories with a depth limit
993N/A * @param files list of files to check if they contain a repo
993N/A * @param repos list of found repos
993N/A * @param ignoredNames what files to ignore
993N/A * @param recursiveSearch whether to use recursive search
1190N/A * @param depth current depth - using global scanningDepth - one can limit
1183N/A * this to improve scanning performance
993N/A */
1183N/A private void addRepositories(File[] files, Collection<RepositoryInfo> repos,
1183N/A IgnoredNames ignoredNames, boolean recursiveSearch, int depth) {
314N/A for (File file : files) {
314N/A Repository repository = null;
314N/A try {
314N/A repository = RepositoryFactory.getRepository(file);
314N/A } catch (InstantiationException ie) {
1190N/A log.log(Level.WARNING, "Could not create repoitory for '"
1183N/A + file + "', could not instantiate the repository.", ie);
314N/A } catch (IllegalAccessException iae) {
1190N/A log.log(Level.WARNING, "Could not create repoitory for '"
1183N/A + file + "', missing access rights.", iae);
314N/A }
1250N/A if (repository == null) {
1250N/A // Not a repository, search it's sub-dirs
1250N/A if (file.isDirectory() && !ignoredNames.ignore(file)) {
1250N/A File subFiles[] = file.listFiles();
1250N/A if (subFiles == null) {
1250N/A log.log(Level.WARNING,
1250N/A "Failed to get sub directories for '"
1250N/A + file.getAbsolutePath()
1250N/A + "', check access permissions.");
1250N/A } else if (depth<=scanningDepth) {
1250N/A addRepositories(subFiles, repos, ignoredNames, depth+1);
1250N/A }
1250N/A }
1250N/A } else {
314N/A try {
314N/A String path = file.getCanonicalPath();
314N/A repository.setDirectoryName(path);
314N/A if (RuntimeEnvironment.getInstance().isVerbose()) {
1183N/A log.log(Level.CONFIG, "Adding <{0}> repository: <{1}>",
1183N/A new Object[]{repository.getClass().getName(), path});
314N/A }
1190N/A
664N/A repos.add(new RepositoryInfo(repository));
191N/A
460N/A // @TODO: Search only for one type of repository - the one found here
317N/A if (recursiveSearch && repository.supportsSubRepositories()) {
314N/A File subFiles[] = file.listFiles();
460N/A if (subFiles == null) {
1190N/A log.log(Level.WARNING,
1190N/A "Failed to get sub directories for '"
1190N/A + file.getAbsolutePath()
1182N/A + "', check access permissions.");
1182N/A } else if (depth<=scanningDepth) {
1190N/A // Search only one level down - if not: too much
1182N/A // stat'ing for huge Mercurial repositories
1190N/A addRepositories(subFiles, repos, ignoredNames,
1182N/A false, depth+1);
314N/A }
314N/A }
1190N/A
314N/A } catch (IOException exp) {
1183N/A log.log(Level.WARNING, "Failed to get canonical path for "
1183N/A + file.getAbsolutePath() + ": " + exp.getMessage());
590N/A log.log(Level.WARNING, "Repository will be ignored...", exp);
314N/A }
191N/A }
1190N/A }
11N/A }
1190N/A
99N/A /**
99N/A * Search through the all of the directories and add all of the source
99N/A * repositories found.
1190N/A *
99N/A * @param dir the root directory to start the search in.
99N/A */
290N/A public void addRepositories(String dir) {
664N/A List<RepositoryInfo> repos = new ArrayList<RepositoryInfo>();
664N/A addRepositories(new File[] {new File(dir)}, repos,
994N/A RuntimeEnvironment.getInstance().getIgnoredNames(),0);
58N/A RuntimeEnvironment.getInstance().setRepositories(repos);
664N/A invalidateRepositories(repos);
58N/A }
58N/A
203N/A /**
203N/A * Update the source the contents in the source repositories.
203N/A */
203N/A public void updateRepositories() {
203N/A boolean verbose = RuntimeEnvironment.getInstance().isVerbose();
590N/A
664N/A for (Map.Entry<String, Repository> entry : repositories.entrySet()) {
290N/A Repository repository = entry.getValue();
1190N/A
203N/A String path = entry.getKey();
203N/A String type = repository.getClass().getSimpleName();
517N/A
578N/A if (repository.isWorking()) {
517N/A if (verbose) {
1190N/A log.info(String.format("Update %s repository in %s",
1183N/A type, path));
517N/A }
517N/A
517N/A try {
517N/A repository.update();
519N/A } catch (UnsupportedOperationException e) {
1183N/A log.warning(String.format("Skipping update of %s repository"
1183N/A + " in %s: Not implemented", type, path));
517N/A } catch (Exception e) {
1190N/A log.log(Level.WARNING, "An error occured while updating "
1183N/A + path + " (" + type + ")", e);
517N/A }
578N/A } else {
1183N/A log.warning(String.format("Skipping update of %s repository in "
1183N/A + "%s: Missing SCM dependencies?", type, path));
203N/A }
203N/A }
203N/A }
1190N/A
668N/A /**
668N/A * Update the source the contents in the source repositories.
668N/A * @param paths A list of files/directories to update
668N/A */
1182N/A public void updateRepositories(Collection<String> paths) {
668N/A boolean verbose = RuntimeEnvironment.getInstance().isVerbose();
668N/A
1182N/A List<Repository> repos = getReposFromString(paths);
668N/A
668N/A for (Repository repository : repos) {
668N/A String type = repository.getClass().getSimpleName();
668N/A
668N/A if (repository.isWorking()) {
668N/A if (verbose) {
1190N/A log.info(String.format("Update %s repository in %s", type,
1183N/A repository.getDirectoryName()));
668N/A }
668N/A
668N/A try {
668N/A repository.update();
668N/A } catch (UnsupportedOperationException e) {
1183N/A log.warning(String.format("Skipping update of %s repository"
1190N/A + " in %s: Not implemented", type,
1183N/A repository.getDirectoryName()));
668N/A } catch (Exception e) {
1190N/A log.log(Level.WARNING, "An error occured while updating "
1183N/A + repository.getDirectoryName() + " (" + type + ")", e);
668N/A }
668N/A } else {
1183N/A log.warning(String.format("Skipping update of %s repository in"
1190N/A + " %s: Missing SCM dependencies?", type,
1183N/A repository.getDirectoryName()));
668N/A }
668N/A }
668N/A }
668N/A
771N/A private void createCache(Repository repository, String sinceRevision) {
772N/A if (!useCache()) {
772N/A return;
772N/A }
772N/A
240N/A String path = repository.getDirectoryName();
240N/A String type = repository.getClass().getSimpleName();
543N/A
578N/A if (repository.isWorking()) {
543N/A boolean verbose = RuntimeEnvironment.getInstance().isVerbose();
543N/A long start = System.currentTimeMillis();
543N/A
543N/A if (verbose) {
1190N/A log.log(Level.INFO, "Create historycache for {0} ({1})",
1183N/A new Object[]{path, type});
543N/A }
240N/A
543N/A try {
771N/A repository.createCache(historyCache, sinceRevision);
543N/A } catch (Exception e) {
1190N/A log.log(Level.WARNING,
1190N/A "An error occured while creating cache for " + path + " ("
1183N/A + type + ")", e);
543N/A }
543N/A
543N/A if (verbose) {
543N/A long stop = System.currentTimeMillis();
1183N/A log.log(Level.INFO, "Creating historycache for {0} took ({1}ms)",
1183N/A new Object[]{path, String.valueOf(stop - start)});
543N/A }
578N/A } else {
1190N/A log.log(Level.WARNING, "Skipping creation of historycache of "
1183N/A + type + " repository in " + path + ": Missing SCM dependencies?");
240N/A }
240N/A }
543N/A
966N/A private void createCacheReal(Collection<Repository> repositories) {
1339N/A int num = Runtime.getRuntime().availableProcessors() * 2;
1339N/A String total = System.getProperty("org.opensolaris.opengrok.history.NumCacheThreads");
1339N/A if (total != null) {
1339N/A try {
1339N/A num = Integer.valueOf(total);
1339N/A } catch (Throwable t) {
1339N/A log.log(Level.WARNING, "Failed to parse the number of cache threads to use for cache creation", t);
1339N/A }
1339N/A }
1339N/A ExecutorService executor = Executors.newFixedThreadPool(num);
701N/A
701N/A for (final Repository repos : repositories) {
771N/A final String latestRev;
771N/A try {
771N/A latestRev = historyCache.getLatestCachedRevision(repos);
771N/A } catch (HistoryException he) {
771N/A log.log(Level.WARNING,
771N/A String.format(
771N/A "Failed to retrieve latest cached revision for %s",
771N/A repos.getDirectoryName()), he);
771N/A continue;
771N/A }
701N/A executor.submit(new Runnable() {
815N/A @Override
701N/A public void run() {
771N/A createCache(repos, latestRev);
701N/A }
701N/A });
701N/A }
701N/A executor.shutdown();
701N/A while (!executor.isTerminated()) {
701N/A try {
1190N/A // Wait forever
930N/A executor.awaitTermination(999,TimeUnit.DAYS);
701N/A } catch (InterruptedException exp) {
1190N/A OpenGrokLogger.getLogger().log(Level.WARNING,
1183N/A "Received interrupt while waiting for executor to finish", exp);
701N/A }
543N/A }
795N/A
795N/A // The cache has been populated. Now, optimize how it is stored on
795N/A // disk to enhance performance and save space.
795N/A try {
795N/A historyCache.optimize();
795N/A } catch (HistoryException he) {
795N/A OpenGrokLogger.getLogger().log(Level.WARNING,
795N/A "Failed optimizing the history cache database", he);
795N/A }
543N/A }
543N/A
1182N/A public void createCache(Collection<String> repositories) {
1182N/A if (!useCache()) {
1182N/A return;
1182N/A }
1182N/A createCacheReal(getReposFromString(repositories));
1182N/A }
1182N/A
1182N/A public void removeCache(Collection<String> repositories) throws HistoryException {
1182N/A List<Repository> repos = getReposFromString(repositories);
1182N/A HistoryCache cache = historyCache;
1182N/A if (cache == null) {
1182N/A if (RuntimeEnvironment.getInstance().storeHistoryCacheInDB()) {
1182N/A cache = new JDBCHistoryCache();
1182N/A cache.initialize();
1182N/A } else {
1182N/A cache = new FileHistoryCache();
1182N/A }
1182N/A }
1182N/A for (Repository r : repos) {
1182N/A try {
1182N/A cache.clear(r);
1182N/A log.info("History cache for " + r.getDirectoryName() + " cleared.");
1182N/A } catch (HistoryException e) {
1182N/A log.warning("Clearing history cache for repository " +
1182N/A r.getDirectoryName() + " failed: " + e.getLocalizedMessage());
1182N/A }
1182N/A }
1182N/A invalidateRepositories(repos);
1182N/A }
1182N/A
203N/A /**
203N/A * Create the history cache for all of the repositories
203N/A */
203N/A public void createCache() {
772N/A if (!useCache()) {
772N/A return;
772N/A }
772N/A
966N/A createCacheReal(repositories.values());
240N/A }
240N/A
1182N/A private List<Repository> getReposFromString(Collection<String> repositories) {
543N/A ArrayList<Repository> repos = new ArrayList<Repository>();
240N/A File root = RuntimeEnvironment.getInstance().getSourceRootFile();
240N/A for (String file : repositories) {
543N/A File f = new File(root, file);
543N/A Repository r = getRepository(f);
578N/A if (r == null) {
1182N/A log.log(Level.WARNING, "Could not locate a repository for {0}",
1182N/A f.getAbsolutePath());
1182N/A } else if (!repos.contains(r)){
543N/A repos.add(r);
203N/A }
240N/A }
1182N/A return repos;
203N/A }
1190N/A
651N/A /**
771N/A * Ensure that we have a directory in the cache. If it's not there, fetch
771N/A * its history and populate the cache. If it's already there, and the
771N/A * cache is able to tell how recent it is, attempt to update it to the
771N/A * most recent revision.
651N/A *
651N/A * @param file the root path to test
678N/A * @throws HistoryException if an error occurs while accessing the
678N/A * history cache
651N/A */
764N/A public void ensureHistoryCacheExists(File file) throws HistoryException {
772N/A if (!useCache()) {
772N/A return;
772N/A }
772N/A
715N/A Repository repository = getRepository(file);
771N/A
771N/A if (repository == null) {
771N/A // no repository -> no history :(
771N/A return;
687N/A }
771N/A
771N/A String sinceRevision = null;
771N/A
771N/A if (historyCache.hasCacheForDirectory(file, repository)) {
771N/A sinceRevision = historyCache.getLatestCachedRevision(repository);
771N/A if (sinceRevision == null) {
771N/A // Cache already exists, but we don't know how recent it is,
771N/A // so don't do anything.
771N/A return;
771N/A }
771N/A }
771N/A
771N/A // Create cache from the beginning if it doesn't exist, or update it
771N/A // incrementally otherwise.
771N/A createCache(getRepository(file), sinceRevision);
687N/A }
651N/A
687N/A protected Repository getRepository(File path) {
664N/A Map<String, Repository> repos = repositories;
439N/A
543N/A File file = path;
212N/A try {
543N/A file = path.getCanonicalFile();
212N/A } catch (IOException e) {
590N/A log.log(Level.WARNING, "Failed to get canonical path for " + path, e);
212N/A return null;
212N/A }
543N/A while (file != null) {
543N/A Repository r = repos.get(file.getAbsolutePath());
543N/A if (r != null) {
543N/A return r;
8N/A }
543N/A file = file.getParentFile();
8N/A }
96N/A
96N/A return null;
664N/A }
664N/A
664N/A /**
664N/A * Invalidate the current list of known repositories!
1190N/A *
664N/A * @param repos The new repositories
664N/A */
1190N/A public void invalidateRepositories(Collection<? extends RepositoryInfo> repos)
1182N/A {
693N/A if (repos == null || repos.isEmpty()) {
693N/A repositories.clear();
693N/A } else {
1190N/A Map<String, Repository> nrep =
1183N/A new HashMap<String, Repository>(repos.size());
693N/A for (RepositoryInfo i : repos) {
693N/A try {
693N/A Repository r = RepositoryFactory.getRepository(i);
693N/A if (r == null) {
1190N/A log.log(Level.WARNING,
1183N/A "Failed to instanciate internal repository data for "
1183N/A + i.getType() + " in " + i.getDirectoryName());
693N/A } else {
693N/A nrep.put(r.getDirectoryName(), r);
693N/A }
693N/A } catch (InstantiationException ex) {
1190N/A log.log(Level.WARNING, "Could not create " + i.getType()
1190N/A + " for '" + i.getDirectoryName()
1183N/A + "', could not instantiate the repository.", ex);
693N/A } catch (IllegalAccessException iae) {
1190N/A log.log(Level.WARNING, "Could not create " + i.getType()
1190N/A + " for '" + i.getDirectoryName()
1183N/A + "', missing access rights.", iae);
664N/A }
664N/A }
693N/A repositories = nrep;
664N/A }
664N/A }
0N/A}