kitaev@213: /* kitaev@213: * Copyright (c) 2010-2011 TMate Software Ltd kitaev@213: * kitaev@213: * This program is free software; you can redistribute it and/or modify kitaev@213: * it under the terms of the GNU General Public License as published by kitaev@213: * the Free Software Foundation; version 2 of the License. kitaev@213: * kitaev@213: * This program is distributed in the hope that it will be useful, kitaev@213: * but WITHOUT ANY WARRANTY; without even the implied warranty of kitaev@213: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the kitaev@213: * GNU General Public License for more details. kitaev@213: * kitaev@213: * For information on how to redistribute this software under kitaev@213: * the terms of a license other than GNU General Public License kitaev@213: * contact TMate Software at support@hg4j.com kitaev@213: */ kitaev@213: package org.tmatesoft.hg.repo; kitaev@213: kitaev@213: import java.io.File; kitaev@213: import java.io.IOException; kitaev@213: import java.net.MalformedURLException; kitaev@213: import java.net.URL; kitaev@213: kitaev@213: import org.tmatesoft.hg.core.HgBadArgumentException; kitaev@213: import org.tmatesoft.hg.core.HgException; kitaev@213: import org.tmatesoft.hg.internal.ConfigFile; kitaev@213: import org.tmatesoft.hg.internal.DataAccessProvider; kitaev@213: import org.tmatesoft.hg.internal.Internals; kitaev@213: kitaev@213: /** kitaev@213: * Utility methods to find Mercurial repository at a given location kitaev@213: * kitaev@213: * @author Artem Tikhomirov kitaev@213: * @author TMate Software Ltd. kitaev@213: */ kitaev@213: public class HgLookup { kitaev@213: kitaev@213: private ConfigFile globalCfg; kitaev@213: kitaev@213: public HgRepository detectFromWorkingDir() throws HgException { kitaev@213: return detect(System.getProperty("user.dir")); kitaev@213: } kitaev@213: kitaev@213: public HgRepository detect(String location) throws HgException { kitaev@213: return detect(new File(location)); kitaev@213: } kitaev@213: kitaev@213: // look up in specified location and above kitaev@213: public HgRepository detect(File location) throws HgException { kitaev@213: File dir = location.getAbsoluteFile(); kitaev@213: File repository; kitaev@213: do { kitaev@213: repository = new File(dir, ".hg"); kitaev@213: if (repository.exists() && repository.isDirectory()) { kitaev@213: break; kitaev@213: } kitaev@213: repository = null; kitaev@213: dir = dir.getParentFile(); kitaev@213: kitaev@213: } while(dir != null); kitaev@213: if (repository == null) { kitaev@213: // return invalid repository kitaev@213: return new HgRepository(location.getPath()); kitaev@213: } kitaev@213: try { kitaev@213: String repoPath = repository.getParentFile().getCanonicalPath(); kitaev@213: return new HgRepository(repoPath, repository); kitaev@213: } catch (IOException ex) { kitaev@213: throw new HgException(location.toString(), ex); kitaev@213: } kitaev@213: } kitaev@213: kitaev@213: public HgBundle loadBundle(File location) throws HgException { kitaev@213: if (location == null || !location.canRead()) { kitaev@213: throw new IllegalArgumentException(); kitaev@213: } kitaev@213: return new HgBundle(new DataAccessProvider(), location).link(); kitaev@213: } kitaev@213: kitaev@213: /** kitaev@213: * Try to instantiate remote server. kitaev@213: * @param key either URL or a key from configuration file that points to remote server kitaev@213: * @param hgRepo NOT USED YET local repository that may have extra config, or default remote location kitaev@213: * @return an instance featuring access to remote repository, check {@link HgRemoteRepository#isInvalid()} before actually using it kitaev@213: * @throws HgBadArgumentException if anything is wrong with the remote server's URL kitaev@213: */ kitaev@213: public HgRemoteRepository detectRemote(String key, HgRepository hgRepo) throws HgBadArgumentException { kitaev@213: URL url; kitaev@213: Exception toReport; kitaev@213: try { kitaev@213: url = new URL(key); kitaev@213: toReport = null; kitaev@213: } catch (MalformedURLException ex) { kitaev@213: url = null; kitaev@213: toReport = ex; kitaev@213: } kitaev@213: if (url == null) { kitaev@213: String server = getGlobalConfig().getSection("paths").get(key); kitaev@213: if (server == null) { kitaev@213: throw new HgBadArgumentException(String.format("Can't find server %s specification in the config", key), toReport); kitaev@213: } kitaev@213: try { kitaev@213: url = new URL(server); kitaev@213: } catch (MalformedURLException ex) { kitaev@213: throw new HgBadArgumentException(String.format("Found %s server spec in the config, but failed to initialize with it", key), ex); kitaev@213: } kitaev@213: } kitaev@213: return new HgRemoteRepository(url); kitaev@213: } kitaev@213: kitaev@213: public HgRemoteRepository detect(URL url) throws HgException { kitaev@213: if (url == null) { kitaev@213: throw new IllegalArgumentException(); kitaev@213: } kitaev@213: if (Boolean.FALSE.booleanValue()) { kitaev@213: throw HgRepository.notImplemented(); kitaev@213: } kitaev@213: return new HgRemoteRepository(url); kitaev@213: } kitaev@213: kitaev@213: private ConfigFile getGlobalConfig() { kitaev@213: if (globalCfg == null) { kitaev@213: globalCfg = new Internals().newConfigFile(); kitaev@213: globalCfg.addLocation(new File(System.getProperty("user.home"), ".hgrc")); kitaev@213: } kitaev@213: return globalCfg; kitaev@213: } kitaev@213: }