Author: tchemit Date: 2008-04-05 20:36:34 +0000 (Sat, 05 Apr 2008) New Revision: 359 Modified: trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/VCSHandler.java trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/VCSProvider.java trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/util/AbstractVCSConnexion.java trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/util/AbstractVCSHandler.java trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/util/AbstractVCSProvider.java Log: refactor PRovider, Handler and Connexion Modified: trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/VCSHandler.java =================================================================== --- trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/VCSHandler.java 2008-04-05 20:36:07 UTC (rev 358) +++ trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/VCSHandler.java 2008-04-05 20:36:34 UTC (rev 359) @@ -24,7 +24,6 @@ import java.io.FilenameFilter; import java.io.IOException; import java.util.Collection; -import java.util.EnumSet; import java.util.List; /** @@ -33,38 +32,32 @@ * @author chemit */ -public interface VCSHandler { +public interface VCSHandler<C extends VCSConnexion> { - /** @return the location to local working copy */ - File getLocalDatabasePath(); - /** * init working copy, says if it is the first we use it it, we will checkout * the databaseDirectory directory * + * @param connexion vcs connexion to use * @throws VCSException if any exception while init */ - void initWorkingCopy() throws VCSException; + void initWorkingCopy(C connexion) throws VCSException; - /** delete the local working copy with all his files */ - void deleteWorkingCopy(); + /** + * delete the local working copy with all his files + * + * @param connexion vcs connexion to use + */ + void deleteWorkingCopy(C connexion); - /** @return the complete remote url to acces repository */ - String getRemoteUrl(); - - /** @return the config used by this handler */ - VCSConfig getConfig(); - /** - * @return a - * <code>FilenameFilter<code> to detect all files and directories in a vcs working copy that + * @return a <code>FilenameFilter<code> to detect all files and directories in a vcs working copy that * must be handled by vcs */ FilenameFilter getVersionnableFilenameFilter(); /** - * @return a - * <code>FileFilter<code> to detect all files and directories in a vcs working copy that + * @return a <code>FileFilter<code> to detect all files and directories in a vcs working copy that * must be handled by vcs */ FileFilter getVersionnableFileFilter(); @@ -82,174 +75,190 @@ */ String getConfLocalEntriesFilename(); - VCSState getState(File fileState, Collection tmp) throws VCSException; + VCSState getState(C connexion, File file, Collection tmp) throws VCSException; - VCSState getState(File file, Collection tmp, boolean noremote) throws VCSException; + VCSState getState(C connexion, File file, Collection tmp, boolean noremote) throws VCSException; /** - * @param file file to test + * @param connexion vcs connexion to use + * @param file file to test * @return <code>true</code> if <code>file</code> is on remote * repository, <code>false</code> otherwise. */ - boolean isOnRemote(File file); + boolean isOnRemote(C connexion, File file); /** - * @param file file to test + * @param connexion vcs connexion to use + * @param file file to test * @return <code>true</code> if file is uptodate,<code>false</code> * otherwise. * @throws VCSException if any exception while operation */ - boolean isUpToDate(File file) throws VCSException; + boolean isUpToDate(C connexion, File file) throws VCSException; /** - * @param file file to test + * @param connexion vcs connexion to use + * @param file file to test * @return <code>true</code> if file is handled by VCS,<code>false</code> * otherwise. */ - boolean isVersionnableFile(File file); + boolean isVersionnableFile(C connexion, File file); /** * add on remote repository somes directories * + * @param connexion vcs connexion to use * @param commitMessage commit message * @param dirNames names of the directories to create on remote repository (could * used multi-level directories) * @throws VCSException if any exception while operation */ - void makeRemoteDir(String commitMessage, String... dirNames) + void makeRemoteDir(C connexion, String commitMessage, String... dirNames) throws VCSException; /** * delete on remote repository somes directories * + * @param connexion vcs connexion to use * @param commitMessage commit message * @param dirNames names of the directories to delete on remote repository (could * used multi-level directories) * @throws VCSException if any exception while operation */ - void deleteRemoteDir(String commitMessage, String... dirNames) + void deleteRemoteDir(C connexion, String commitMessage, String... dirNames) throws VCSException; /** * add a list of files into repository * - * @param files files to add - * @param msg message for VCS commit, if <code>null</code> then no commit - * is performed + * @param connexion vcs connexion to use + * @param files files to add + * @param msg message for VCS commit, if <code>null</code> then no commit + * is performed * @return revision of the operation * @throws VCSException if any exception while operation */ - long add(List<File> files, String msg) throws VCSException; + long add(C connexion, List<File> files, String msg) throws VCSException; // void add(File file, String msg) throws VCSException; /** * delete a list of files from repository * - * @param files files to delete - * @param msg message for VCS commit, if <code>null</code> then no commit - * is performed + * @param connexion vcs connexion to use + * @param files files to delete + * @param msg message for VCS commit, if <code>null</code> then no commit + * is performed * @throws VCSException if any exception while operation */ - void delete(List<File> files, String msg) throws VCSException; + void delete(C connexion, List<File> files, String msg) throws VCSException; /** * revert a list of files from repository * - * @param files files to revert + * @param connexion vcs connexion to use + * @param files files to revert * @throws VCSException if any exception while operation */ - void revert(List<File> files) throws VCSException; + void revert(C connexion, List<File> files) throws VCSException; /** * commit a list of files into repository * - * @param files files to commit - * @param msg message for VCS commit + * @param connexion vcs connexion to use + * @param files files to commit + * @param msg message for VCS commit * @return revision of the operation * @throws VCSException if any exception while operation */ - long commit(List<File> files, String msg) throws VCSException; + long commit(C connexion, List<File> files, String msg) throws VCSException; /** * update a file to repository to a certain revision * - * @param file file to update - * @param revision object representing a revision for the current VCS + * @param connexion vcs connexion to use + * @param file file to update + * @param revision object representing a revision for the current VCS * @throws VCSException if any exception while operation */ - void update(File file, Object revision) throws VCSException; + void update(C connexion, File file, Object revision) throws VCSException; /** * update a file to repository * - * @param file file to update + * @param connexion vcs connexion to use + * @param file file to update * @throws VCSException if any exception while operation */ - void update(File file) throws VCSException; + void update(C connexion, File file) throws VCSException; /** * checkout a module from repository to a local file * - * @param destDir local file where to checkout - * @param module module's name to checkout - * @param recurse flag to say to recurse checkout or not. + * @param connexion vcs connexion to use + * @param destDir local file where to checkout + * @param module module's name to checkout + * @param recurse flag to say to recurse checkout or not. * @throws VCSException if any exception while operation */ - void checkout(File destDir, String module, boolean recurse) - throws VCSException; + void checkout(C connexion, File destDir, String module, boolean recurse) throws VCSException; - void checkoutFile(File destDir, String module) throws VCSException; + void checkoutFile(C connexion, File destDir, String module) throws VCSException; - long checkoutOnlyTheDirectory(File root, Object revision) throws VCSException; + long checkoutOnlyTheDirectory(C connexion, File root, Object revision) throws VCSException; /** * TODO This is not the good place : VCS != Storage * + * @param connexion vcs connexion to use * @param directory directory to treate * @return TODO * @throws VCSException TODO */ - List<String> getRemoteStorageNames(File directory) throws VCSException; + List<String> getRemoteStorageNames(C connexion, File directory) throws VCSException; /** * TODO This is not the good place : VCS != Storage * + * @param connexion vcs connexion to use * @param directory directory to treate * @return TODO */ - List<String> getLocalStorageNames(File directory); + List<String> getLocalStorageNames(C connexion, File directory); /** - * @param f local file to treate + * @param connexion vcs connexion to use + * @param f local file to treate * @return current local revision of a file * @throws VCSException TODO */ - Object getRevision(File f) throws VCSException; + Object getRevision(C connexion, File f) throws VCSException; /** * Obtain the list of log entries for the file * + * @param connexion vcs connexion to use * @param startRevision TODO * @param endRevision TODO * @param file file to treate * @return list of log entries for this file between two revisions * @throws VCSException if any exception while grabbing infos */ - List getLog(Object startRevision, Object endRevision, File file) + List getLog(C connexion, Object startRevision, Object endRevision, File file) throws VCSException; /** * obtain the content of a file for a specific revision * - * @param file file to obtain - * @param revision revision treated + * @param connexion vcs connexion to use + * @param file file to obtain + * @param revision revision treated * @return the content of the file on repository for the specific revision * passed as arguement. * @throws VCSException if any exception while operation * @throws java.io.IOException TODO */ - String getFileContent(File file, Object revision) throws VCSException, IOException; + String getFileContent(C connexion, File file, Object revision) throws VCSException, IOException; /** * Build the changelog for <code>file</code> from current revision of this @@ -263,19 +272,21 @@ * <li>commit message</li> * </ul> * - * @param file file to treate + * @param connexion vcs connexion to use + * @param file file to treate * @return a string representation of change log for the local file to the * head ? * @throws VCSException if any exception while building changelog */ - String getChangeLog(File file) throws VCSException; + String getChangeLog(C connexion, File file) throws VCSException; /** * Generate in the ouputstream the diff between the current revision of the * local file against headest revision on repository. <br> * If file is uptodate, then does nothing. * - * @param file the file to treate + * @param connexion vcs connexion to use + * @param file the file to treate * @return the diff * @throws VCSException inf any exception while building diff, such as : * <ul> @@ -286,7 +297,7 @@ * </ul> * @throws java.io.IOException if io problem with streams */ - String getDiff(File file) throws VCSException, IOException; + String getDiff(C connexion, File file) throws VCSException, IOException; /** * Generate in the ouputstream the diff between the current revision of the @@ -294,6 +305,7 @@ * repository. <br> * If file is uptodate, then does nothing. * + * @param connexion vcs connexion to use * @param file the file to treate * @param againstRevision the against revision to use * @return the diff @@ -306,28 +318,9 @@ * </ul> * @throws java.io.IOException if problem with streams */ - String getDiff(File file, Object againstRevision) throws VCSException, IOException; + String getDiff(C connexion, File file, Object againstRevision) throws VCSException, IOException; - /** - * test if connection is ok - * - * @throws VCSException if any problem - */ - void testConnection() throws VCSException; - boolean hasProtocoleChanged() throws VCSException; + boolean hasProtocoleChanged(C connexion) throws VCSException; - void addVCSHandlerEventListener(VCSHandlerEventListener l); - - void removeVCSHandlerEventListener(VCSHandlerEventListener l); - - void open(); - - void close(); - - EnumSet<VCSAction> getAuthorizedActions(); - - public boolean isConnected(); - - public boolean hasWriteAccess(); } \ No newline at end of file Modified: trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/VCSProvider.java =================================================================== --- trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/VCSProvider.java 2008-04-05 20:36:07 UTC (rev 358) +++ trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/VCSProvider.java 2008-04-05 20:36:34 UTC (rev 359) @@ -14,8 +14,6 @@ */ package org.codelutin.vcs; -import java.util.List; - /** * The contract to be realized to provide vcs communication. * <p/> @@ -25,36 +23,30 @@ * @see VCSHandler * @see VCSConnexion */ -public interface VCSProvider<H extends VCSHandler, C extends VCSConnexion> { +public interface VCSProvider<C extends VCSConnexion, H extends VCSHandler<C>> { /** @return the identifier of the vcs provider (eg SVN, CVS, MOCK) */ String getName(); - /** @return list of known connexions. */ - List<C> getConnexions(); - /** * return a new VCSHandler instance for given config. * * @return the cached instance of handler - * @throws IllegalStateException if handler was not init via {@link #newInstance(VCSConfig)} + * @throws IllegalStateException if provider was not init via {@link #init()} */ H getHandler() throws IllegalStateException; - /** - * return a new VCSHandler instance for given config. - * - * @param config svn handler config - * @return the new instance - * @throws IllegalStateException if any pb while init handler - */ - H newInstance(VCSConfig config) throws IllegalStateException; + /** init the provider */ + void init(); /** + * Instanciate an new connexion for a given config, and init it. + * * @param mode the mode required * @param config the config to be used * @return the new connexion initializd <b>but not opened</b>. + * @throws IllegalStateException if provider was not init via {@link #init()} */ - C newConnection(VCSConnexionMode mode, VCSConfig config); + C newConnection(VCSConnexionMode mode, VCSConnexionConfig config) throws IllegalStateException; } Modified: trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/util/AbstractVCSConnexion.java =================================================================== --- trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/util/AbstractVCSConnexion.java 2008-04-05 20:36:07 UTC (rev 358) +++ trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/util/AbstractVCSConnexion.java 2008-04-05 20:36:34 UTC (rev 359) @@ -14,29 +14,62 @@ */ package org.codelutin.vcs.util; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.codelutin.util.ListenerSet; import org.codelutin.vcs.ConnectionState; +import org.codelutin.vcs.VCSAction; import org.codelutin.vcs.VCSConnexion; +import org.codelutin.vcs.VCSConnexionConfig; +import org.codelutin.vcs.VCSConnexionEvent; +import org.codelutin.vcs.VCSConnexionEvent.Type; +import org.codelutin.vcs.VCSConnexionEventListener; import org.codelutin.vcs.VCSConnexionMode; +import org.codelutin.vcs.VCSException; +import org.codelutin.vcs.VCSHandler; +import org.codelutin.vcs.VCSProvider; +import org.codelutin.vcs.VCSState; import java.io.File; +import java.io.FileFilter; +import java.io.FilenameFilter; +import java.io.IOException; import java.net.URI; -import java.util.Map; +import java.util.Collection; +import java.util.EnumSet; +import java.util.List; /** @author chemit */ public abstract class AbstractVCSConnexion implements VCSConnexion { - public static final String OPTION_LOGIN = "login"; - public static final String OPTION_PASSWORD = "password"; - public static final String OPTION_PASSPHRASE = "passphrase"; - public static final String OPTION_KEY_FILE = "keyfile"; + /** to use log facility, just put in your code: log.info(\"...\"); */ + static protected final Log log = LogFactory.getLog(AbstractVCSConnexion.class); protected File localRoot; protected URI remoteRoot; protected VCSConnexionMode mode; protected ConnectionState state; - protected Map<String, String> options; + protected VCSConnexionConfig config; + protected VCSProvider<AbstractVCSConnexion, ?> provider; + + protected ListenerSet<VCSConnexionEventListener> listeners = new ListenerSet<VCSConnexionEventListener>(); + + @SuppressWarnings({"unchecked"}) + protected AbstractVCSConnexion(VCSConnexionMode mode, VCSProvider provider) { + this.mode = mode; + this.provider = provider; + } + + public VCSHandler<AbstractVCSConnexion> getHandler() throws IllegalStateException { + return getProvider().getHandler(); + } + + public VCSProvider<AbstractVCSConnexion, ?> getProvider() { + return provider; + } + public File getWorkingCopy() throws IllegalStateException { checkInit(); return localRoot; @@ -52,9 +85,8 @@ return mode; } - public Map<String, String> getOptions() throws IllegalStateException { - checkInit(); - return options; + public VCSConnexionConfig getConfig() throws IllegalStateException { + return config; } public boolean isOpen() throws IllegalStateException { @@ -72,6 +104,180 @@ return state == ConnectionState.ERROR; } + public void addVCSConnexionEventListener(VCSConnexionEventListener l) { + listeners.add(l); + } + + public void removeVCSConnexionEventListener(VCSConnexionEventListener l) { + listeners.remove(l); + } + + public void initWorkingCopy() throws VCSException { + getHandler().initWorkingCopy(this); + } + + public void deleteWorkingCopy() { + getHandler().deleteWorkingCopy(this); + } + + public FilenameFilter getVersionnableFilenameFilter() { + return getHandler().getVersionnableFilenameFilter(); + } + + public FileFilter getVersionnableFileFilter() { + return getHandler().getVersionnableFileFilter(); + } + + public String getConfLocalDirname() { + return getHandler().getConfLocalDirname(); + } + + public String getConfLocalEntriesFilename() { + return getHandler().getConfLocalEntriesFilename(); + } + + public VCSState getState(File fileState, Collection tmp) throws VCSException { + return getHandler().getState(this, fileState, tmp); + } + + public VCSState getState(File file, Collection tmp, boolean noremote) throws VCSException { + return getHandler().getState(this, file, tmp, noremote); + } + + public boolean isOnRemote(File file) { + return getHandler().isOnRemote(this, file); + } + + public boolean isUpToDate(File file) throws VCSException { + return getHandler().isUpToDate(this, file); + } + + public boolean isVersionnableFile(File file) { + return getHandler().isVersionnableFile(this, file); + } + + public void makeRemoteDir(String commitMessage, String... dirNames) throws VCSException { + getHandler().makeRemoteDir(this, commitMessage, dirNames); + } + + public void deleteRemoteDir(String commitMessage, String... dirNames) throws VCSException { + getHandler().deleteRemoteDir(this, commitMessage, dirNames); + } + + public long add(List<File> files, String msg) throws VCSException { + return getHandler().add(this, files, msg); + } + + public void delete(List<File> files, String msg) throws VCSException { + getHandler().delete(this, files, msg); + } + + public void revert(List<File> files) throws VCSException { + getHandler().revert(this, files); + } + + public long commit(List<File> files, String msg) throws VCSException { + return getHandler().commit(this, files, msg); + } + + public void update(File file, Object revision) throws VCSException { + getHandler().update(this, file, revision); + } + + public void update(File file) throws VCSException { + getHandler().update(this, file); + } + + public void checkout(File destDir, String module, boolean recurse) throws VCSException { + getHandler().checkout(this, destDir, module, recurse); + } + + public void checkoutFile(File destDir, String module) throws VCSException { + getHandler().checkoutFile(this, destDir, module); + } + + public long checkoutOnlyTheDirectory(File root, Object revision) throws VCSException { + return getHandler().checkoutOnlyTheDirectory(this, root, revision); + } + + public List<String> getRemoteStorageNames(File directory) throws VCSException { + return getHandler().getRemoteStorageNames(this, directory); + } + + public List<String> getLocalStorageNames(File directory) { + return getHandler().getLocalStorageNames(this, directory); + } + + public Object getRevision(File f) throws VCSException { + return getHandler().getRevision(this, f); + } + + public List getLog(Object startRevision, Object endRevision, File file) throws VCSException { + return getHandler().getLog(this, startRevision, endRevision, file); + } + + public String getFileContent(File file, Object revision) throws VCSException, IOException { + return getHandler().getFileContent(this, file, revision); + } + + public String getChangeLog(File file) throws VCSException { + return getHandler().getChangeLog(this, file); + } + + public String getDiff(File file) throws VCSException, IOException { + return getHandler().getDiff(this, file); + } + + public String getDiff(File file, Object againstRevision) throws VCSException, IOException { + return getHandler().getDiff(this, file, againstRevision); + } + + public boolean hasProtocoleChanged() throws VCSException { + return getHandler().hasProtocoleChanged(this); + } + + /** + * Obtain the set of permitted vcs actions. + * + * @return the EnumSet of authorized action according to current vcs config + */ + public EnumSet<VCSAction> getAuthorizedActions() { + boolean canWrite = hasWriteAccess(); + EnumSet<VCSAction> result = EnumSet.noneOf(VCSAction.class); + for (VCSAction vcsAction : VCSAction.values()) { + if (!vcsAction.isWrite() || canWrite) { + result.add(vcsAction); + } + } + return result; + } + + public boolean hasWriteAccess() { + return !getConfig().isUseSshConnexion() && getMode() != VCSConnexionMode.ANONYMOUS; + } + + public void addVCSHandlerEventListener(VCSConnexionEventListener l) { + listeners.add(l); + } + + public void removeVCSHandlerEventListener(VCSConnexionEventListener l) { + listeners.remove(l); + } + + protected void fireOpen() { + VCSConnexionEvent e = new VCSConnexionEvent(this, Type.OPEN); + for (VCSConnexionEventListener l : listeners) { + l.open(e); + } + } + + protected void fireClose() { + VCSConnexionEvent e = new VCSConnexionEvent(this, Type.CLOSE); + for (VCSConnexionEventListener l : listeners) { + l.close(e); + } + } + protected void checkInit() throws IllegalStateException { if (state == null) { throw new IllegalStateException("connexion was not init"); @@ -85,4 +291,5 @@ } } + } Modified: trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/util/AbstractVCSHandler.java =================================================================== --- trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/util/AbstractVCSHandler.java 2008-04-05 20:36:07 UTC (rev 358) +++ trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/util/AbstractVCSHandler.java 2008-04-05 20:36:34 UTC (rev 359) @@ -21,15 +21,12 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import static org.codelutin.i18n.I18n._; import org.codelutin.util.FileUtil; -import org.codelutin.util.ListenerSet; -import org.codelutin.vcs.VCSHandlerEvent.Type; +import org.codelutin.vcs.VCSConnexion; import org.codelutin.vcs.VCSHandler; -import org.codelutin.vcs.VCSConfig; -import org.codelutin.vcs.VCSHandlerEventListener; -import org.codelutin.vcs.VCSHandlerEvent; import org.codelutin.vcs.VCSRuntimeException; -import org.codelutin.vcs.VCSAction; +import org.codelutin.vcs.VCSTypeRepo; import java.io.File; import java.io.FileFilter; @@ -37,14 +34,13 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.EnumSet; /** * abstract VCSHandler base with usefull methods that does not need vcs specific code. * * @author chemit */ -public abstract class AbstractVCSHandler implements VCSHandler { +public abstract class AbstractVCSHandler<C extends VCSConnexion> implements VCSHandler<C> { /** to use log facility, just put in your code: log.info(\"...\"); */ static protected final Log log = LogFactory.getLog(AbstractVCSHandler.class); @@ -58,13 +54,13 @@ protected final FileFilter versionnableFileFilter; protected final String confLocalDirName; protected final String confLocalEntriesFilename; + public static final String LOCAL_SEP = File.separator; + public static final String LOCAL_SEP_PATTERN = "\\".equals(LOCAL_SEP) ? + LOCAL_SEP + LOCAL_SEP : LOCAL_SEP; + public static final String REMOTE_SEP = "/"; + public static final String REMOTE_SEP_PATTERN = "/"; - protected final VCSConfig config; - - protected ListenerSet<VCSHandlerEventListener> listeners = new ListenerSet<VCSHandlerEventListener>(); - - protected AbstractVCSHandler(VCSConfig config, final String vCSConfLocalDirName, String vCSConfLocalEntriesFilename) { - this.config = config; + protected AbstractVCSHandler(final String vCSConfLocalDirName, String vCSConfLocalEntriesFilename) { this.confLocalDirName = vCSConfLocalDirName; this.confLocalEntriesFilename = vCSConfLocalEntriesFilename; this.versionnableFilenameFilter = new FilenameFilter() { @@ -77,24 +73,8 @@ return dir.isFile() || (!vCSConfLocalDirName.equals(dir.getName()) && !"CVS".equals(dir.getName())); } }; - fireInit(); } - public VCSConfig getConfig() { - return config; - } - - public File getLocalDatabasePath() { - return config.getLocalDatabasePath(); - } - - public void deleteWorkingCopy() { - if (getLocalDatabasePath().exists()) { - FileUtil.deleteRecursively(getLocalDatabasePath()); - getLocalDatabasePath().delete(); - } - } - public FilenameFilter getVersionnableFilenameFilter() { return versionnableFilenameFilter; } @@ -111,12 +91,19 @@ return confLocalEntriesFilename; } - public boolean isVersionnableFile(File file) { + public boolean isVersionnableFile(C connexion, File file) { assertFileExists(file, "file is empty or non existant"); return !confLocalDirName.equalsIgnoreCase(file.getName()); } - public List<String> getLocalStorageNames(File directory) { + public void deleteWorkingCopy(C connexion) { + if (connexion.getConfig().getLocalDatabasePath().exists()) { + FileUtil.deleteRecursively(connexion.getConfig().getLocalDatabasePath()); + connexion.getConfig().getLocalDatabasePath().delete(); + } + } + + public List<String> getLocalStorageNames(C connexion, File directory) { List<String> result = new ArrayList<String>(); if (directory.exists()) { getFiles0(directory, result, ""); @@ -125,49 +112,24 @@ return result; } - public void addVCSHandlerEventListener(VCSHandlerEventListener l) { - listeners.add(l); - } - - public void removeVCSHandlerEventListener(VCSHandlerEventListener l) { - listeners.remove(l); - } - - public void open() { - fireOpen(); - } - - public void close() { - fireClose(); - } - - protected void fireInit() { - VCSHandlerEvent e = new VCSHandlerEvent(this, Type.INIT); - for (VCSHandlerEventListener l : listeners) { - l.init(e); + public void doCheckoutDir(C connexion, File... dirs) { + for (File dir : dirs) { + try { + if (!dir.exists() || !isFileInWorkingCopy(dir, this, connexion, true)) { + checkoutOnlyTheDirectory(connexion, dir, null); + } + } catch (Exception eee) { + log.warn(_("lutinvcs.error.checkout.dir", dir), eee); + break; + } } } - protected void fireOpen() { - VCSHandlerEvent e = new VCSHandlerEvent(this, Type.OPEN); - for (VCSHandlerEventListener l : listeners) { - l.open(e); - } + protected void assertFileExists(File file, String msg) { + if (file == null || !file.exists()) + throw new VCSRuntimeException(msg + " (file passed : [" + file + "])"); } - protected void fireClose() { - VCSHandlerEvent e = new VCSHandlerEvent(this, Type.CLOSE); - for (VCSHandlerEventListener l : listeners) { - l.close(e); - } - } - - @Override - protected void finalize() throws Throwable { - super.finalize(); - close(); - } - protected void getFiles0(File directory, List<String> result, String prefix) { //TODO put the hardcored value in a property!!! if (directory.getName().equals("data")) return; @@ -183,32 +145,132 @@ } } - protected void assertFileExists(File file, String msg) { - if (file == null || !file.exists()) - throw new VCSRuntimeException(msg + " (file passed : [" + file + "])"); + public static boolean isFileInWorkingCopy(File parent, String name, VCSHandler handler, VCSConnexion connexion, boolean underVCS) { + if (parent == null || name == null) + throw new RuntimeException(AbstractVCSHandler.class.getName() + "#isFileInWorkingCopy can not be invoked with some null parameter but was. [" + parent + "," + name + "," + + handler + "]"); + return isFileInWorkingCopy(new File(parent, name), handler, connexion, underVCS); } + public static boolean isFileInWorkingCopy(File file, VCSHandler handler, VCSConnexion connexion, boolean underVCS) { + if (file == null || handler == null) + throw new RuntimeException(AbstractVCSHandler.class.getName() + "#isFileInWorkingCopy can not be invoked with some null parameter but was. [" + file + "," + handler + "]"); + String rootPath = connexion.getConfig().getLocalDatabasePath().getAbsolutePath(); + String localPath = file.getAbsolutePath(); + if (localPath.startsWith(rootPath) && !underVCS) { + return true; + } + final File realDir = file.isDirectory() ? file : file.getParentFile(); + return isFileInCheckedDir(realDir, handler); + } + + public static boolean isFileInCheckedDir(File file, VCSHandler handler) { + if (file == null || handler == null) + throw new RuntimeException(AbstractVCSHandler.class.getName() + "#isFileInCheckedDir can not be invoked with some null parameter but was. [" + file + "," + handler + "]"); + final File realDir = file.isDirectory() ? file : file.getParentFile(); + return (new File(realDir, handler.getConfLocalDirname()).exists()); + + } + + public static void assertFileInWC(File file, VCSHandler handler, VCSConnexion connexion) { + if (!isFileInWorkingCopy(file, handler, connexion, false)) + throw new VCSRuntimeException("the file [" + file + "] is not in the working copy [" + connexion.getConfig().getLocalDatabasePath() + "]"); + } + + public static String getRemoteRelativePath(File f, VCSHandler handler, VCSConnexion connexion) { + if (!isFileInWorkingCopy(f, handler, connexion, false)) return null; + //System.out.println("file on vcs working copy : "+f); + String rootPath = connexion.getConfig().getLocalDatabasePath().getAbsolutePath(); + String localPath = f.getAbsolutePath(); + if (!localPath.startsWith(rootPath)) return null; + localPath = localPath.substring(rootPath.length() + 1); + return convertToRemoteName(localPath); + } + + public static String getLocalRelativePath(String remoteRelativePath, VCSHandler handler, VCSConnexion connexion) { + String localPath = convertToLocalName(remoteRelativePath); + final File file = new File(connexion.getConfig().getLocalDatabasePath(), localPath); + if (!isFileInWorkingCopy(file, handler, connexion, false)) return null; + return localPath; + } + + public static String convertToRemoteName(String txt) { + return txt.replaceAll(LOCAL_SEP_PATTERN, REMOTE_SEP); + } + + public static String convertToLocalName(String txt) { + return txt.replaceAll(REMOTE_SEP_PATTERN, LOCAL_SEP); + } + /** - * Obtain the set of permitted vcs actions. - * - * @return the EnumSet of authorized action according to current vcs config + * @param typeRepo the type of repo to used + * @param remotePath the unclean remote path to use + * @return the remote path from the old one according to given type repo */ - public EnumSet<VCSAction> getAuthorizedActions() { - boolean canWrite = hasWriteAccess(); - EnumSet<VCSAction> result = EnumSet.noneOf(VCSAction.class); - for (VCSAction vcsAction : VCSAction.values()) { - if (!vcsAction.isWrite() || canWrite) { - result.add(vcsAction); - } + public static String getRemotePath(VCSTypeRepo typeRepo, String remotePath) { + String result = cleanRemotePath(remotePath); + switch (typeRepo) { + case BRANCH: + case TAG: + result = remotePath + '/' + typeRepo.getPath(); + break; + case HEAD: + result = remotePath; + break; } return result; } - public boolean isConnected() { - return getConfig().isConnected(); + /** + * @param typeRepo the type of repo to use + * @param version the version to use + * @return the remoteDatabase according to type of repo and version + */ + public static String getRemoteDatabase(VCSTypeRepo typeRepo, String version) { + String result = null; + switch (typeRepo) { + case BRANCH: + case TAG: + result = version; + break; + case HEAD: + result = VCSTypeRepo.HEAD.getPath(); + break; + } + return result; } - public boolean hasWriteAccess() { - return !getConfig().isReadOnly(); + /** + * to clean a remote path from typeRepo suffix. + * <p/> + * For example, having a url svn://XXX/trunk then remove /trunk. + * <p/> + * Or if having svn://XXX/branches/YYY then remove /branches/YYY + * Or if having svn://XXX/tags/YYY then remove /tags/YYY + * + * @param remotePath the remote path to clean + * @return the cleaned remote path + */ + public static String cleanRemotePath(String remotePath) { + int pos = remotePath.indexOf(VCSTypeRepo.BRANCH.getPath()); + if (pos > -1) { + // found a branch + remotePath = remotePath.substring(0, pos - 1); + } else { + pos = remotePath.indexOf(VCSTypeRepo.HEAD.getPath()); + if (pos > -1) { + // found a branch + remotePath = remotePath.substring(0, pos - 1); + } else { + pos = remotePath.indexOf(VCSTypeRepo.TAG.getPath()); + if (pos > -1) { + // found a tag + remotePath = remotePath.substring(0, pos - 1); + } else { + // remote path was clean + } + } + } + return remotePath; } } Modified: trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/util/AbstractVCSProvider.java =================================================================== --- trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/util/AbstractVCSProvider.java 2008-04-05 20:36:07 UTC (rev 358) +++ trunk/lutinvcs/lutinvcs-api/src/main/java/org/codelutin/vcs/util/AbstractVCSProvider.java 2008-04-05 20:36:34 UTC (rev 359) @@ -14,70 +14,76 @@ */ package org.codelutin.vcs.util; -import org.codelutin.vcs.VCSConfig; import org.codelutin.vcs.VCSConnexion; +import org.codelutin.vcs.VCSConnexionConfig; +import org.codelutin.vcs.VCSConnexionMode; import org.codelutin.vcs.VCSHandler; import org.codelutin.vcs.VCSProvider; import java.lang.reflect.InvocationTargetException; -import java.util.List; /** * base implementation of provider with a cached handler and list of connexions * * @author chemit */ -public abstract class AbstractVCSProvider<H extends VCSHandler, C extends VCSConnexion> implements VCSProvider<H, C> { +public abstract class AbstractVCSProvider<C extends VCSConnexion, H extends VCSHandler<C>> implements VCSProvider<C, H> { protected H handler; - protected List<C> connexions; - protected final String name; private final Class<H> handlerImpl; + private final Class<C> connexionImpl; - protected AbstractVCSProvider(String name, Class<H> handlerImpl) { + protected AbstractVCSProvider(String name, Class<H> handlerImpl, Class<C> connexionImpl) { this.name = name; this.handlerImpl = handlerImpl; + this.connexionImpl = connexionImpl; } public final String getName() { return name; } - public List<C> getConnexions() { - if (connexions == null) { - connexions = new java.util.ArrayList<C>(); - } - return connexions; - } - public H getHandler() throws IllegalStateException { checkHandlerInit(); return handler; } - public H newInstance(VCSConfig config) throws IllegalStateException { - if (handler != null) { - return handler; - } + public C newConnection(VCSConnexionMode mode, VCSConnexionConfig config) throws IllegalStateException { + checkHandlerInit(); try { - return handlerImpl.getConstructor(VCSConfig.class).newInstance(config); + C connexion = connexionImpl.getConstructor(VCSConnexionMode.class, getClass()).newInstance(mode, this); + connexion.init(config); + return connexion; } catch (InstantiationException e) { - throw new IllegalStateException("could not instanciate the handler " + handlerImpl + " for reason " + e.getMessage()); + throw new RuntimeException("could not instanciate connexion " + connexionImpl + " for reason " + e.getMessage()); } catch (IllegalAccessException e) { - throw new IllegalStateException("could not instanciate the handler " + handlerImpl + " for reason " + e.getMessage()); + throw new RuntimeException("could not instanciate connexion " + connexionImpl + " for reason " + e.getMessage()); } catch (InvocationTargetException e) { - throw new IllegalStateException("could not instanciate the handler " + handlerImpl + " for reason " + e.getMessage()); + throw new RuntimeException("could not instanciate connexion " + connexionImpl + " for reason " + e.getMessage()); } catch (NoSuchMethodException e) { - throw new IllegalStateException("could not instanciate the handler " + handlerImpl + " for reason " + e.getMessage()); + throw new RuntimeException("could not instanciate connexion " + connexionImpl + " for reason " + e.getMessage()); } } + public void init() { + if (handler == null) { + try { + handler = handlerImpl.newInstance(); + } catch (InstantiationException e) { + throw new RuntimeException("could not instanciate the handler " + handlerImpl + " for reason " + e.getMessage()); + } catch (IllegalAccessException e) { + throw new RuntimeException("could not instanciate the handler " + handlerImpl + " for reason " + e.getMessage()); + } + } + } + protected void checkHandlerInit() throws IllegalStateException { if (handler == null) { throw new IllegalStateException("handler was not init in " + this); } } + }
participants (1)
-
tchemit@users.labs.libre-entreprise.org