org.tigris.subversion.svnclientadapter.AbstractClientAdapter.java Source code

Java tutorial

Introduction

Here is the source code for org.tigris.subversion.svnclientadapter.AbstractClientAdapter.java

Source

/*******************************************************************************
 * Copyright (c) 2005, 2006 svnClientAdapter project and others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Contributors:
 *     svnClientAdapter project committers - initial API and implementation
 ******************************************************************************/
package org.tigris.subversion.svnclientadapter;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

/**
 * Default implementation of some of the methods of ISVNClientAdapter
 * 
 * @author Cdric Chabanois (cchabanois at no-log.org)
 * @author Panagiotis Korros (pkorros at bigfoot.com)   
 */
public abstract class AbstractClientAdapter implements ISVNClientAdapter {

    /* (non-Javadoc)
     * @see org.tigris.subversion.svnclientadapter.ISVNClientAdapter#setKeywords(java.io.File, org.tigris.subversion.svnclientadapter.SVNKeywords, boolean)
     */
    public void setKeywords(File path, SVNKeywords keywords, boolean recurse) throws SVNClientException {
        propertySet(path, ISVNProperty.KEYWORDS, keywords.toString(), recurse);
    }

    /* (non-Javadoc)
     * @see org.tigris.subversion.svnclientadapter.ISVNClientAdapter#addKeywords(java.io.File, org.tigris.subversion.svnclientadapter.SVNKeywords)
     */
    public SVNKeywords addKeywords(File path, SVNKeywords keywords) throws SVNClientException {
        SVNKeywords currentKeywords = getKeywords(path);
        if (keywords.isHeadUrl())
            currentKeywords.setHeadUrl(true);
        if (keywords.isId())
            currentKeywords.setId(true);
        if (keywords.isLastChangedBy())
            currentKeywords.setLastChangedBy(true);
        if (keywords.isLastChangedDate())
            currentKeywords.setLastChangedBy(true);
        if (keywords.isLastChangedRevision())
            currentKeywords.setLastChangedRevision(true);
        setKeywords(path, currentKeywords, false);

        return currentKeywords;
    }

    /* (non-Javadoc)
     * @see org.tigris.subversion.svnclientadapter.ISVNClientAdapter#removeKeywords(java.io.File, org.tigris.subversion.svnclientadapter.SVNKeywords)
     */
    public SVNKeywords removeKeywords(File path, SVNKeywords keywords) throws SVNClientException {
        SVNKeywords currentKeywords = getKeywords(path);
        if (keywords.isHeadUrl())
            currentKeywords.setHeadUrl(false);
        if (keywords.isId())
            currentKeywords.setId(false);
        if (keywords.isLastChangedBy())
            currentKeywords.setLastChangedBy(false);
        if (keywords.isLastChangedDate())
            currentKeywords.setLastChangedBy(false);
        if (keywords.isLastChangedRevision())
            currentKeywords.setLastChangedRevision(false);
        setKeywords(path, currentKeywords, false);

        return currentKeywords;
    }

    /* (non-Javadoc)
     * @see org.tigris.subversion.svnclientadapter.ISVNClientAdapter#getIgnoredPatterns(java.io.File)
     */
    public List getIgnoredPatterns(File path) throws SVNClientException {
        if (!path.isDirectory())
            return null;
        List list = new ArrayList();
        ISVNProperty pd = propertyGet(path, ISVNProperty.IGNORE);
        if (pd == null)
            return list;
        String patterns = pd.getValue();
        StringTokenizer st = new StringTokenizer(patterns, "\n\r");
        while (st.hasMoreTokens()) {
            String entry = st.nextToken();
            if ((entry != null) && (entry.length() > 0)) {
                list.add(entry);
            }
        }
        return list;
    }

    /* (non-Javadoc)
    * @see org.tigris.subversion.subclipse.client.ISVNClientAdapter#getLogMessages(java.io.File, org.tigris.subversion.subclipse.client.ISVNRevision, org.tigris.subversion.subclipse.client.ISVNRevision)
    */
    public ISVNLogMessage[] getLogMessages(File arg0, SVNRevision arg1, SVNRevision arg2)
            throws SVNClientException {
        return getLogMessages(arg0, arg1, arg2, true);
    }

    /* (non-Javadoc)
    * @see org.tigris.subversion.subclipse.client.ISVNClientAdapter#getLogMessages(java.net.URL, org.tigris.subversion.subclipse.client.ISVNRevision, org.tigris.subversion.subclipse.client.ISVNRevision)
    */
    public ISVNLogMessage[] getLogMessages(SVNUrl arg0, SVNRevision arg1, SVNRevision arg2)
            throws SVNClientException {
        return getLogMessages(arg0, arg1, arg2, true);
    }

    /* (non-Javadoc)
     * @see org.tigris.subversion.svnclientadapter.ISVNClientAdapter#getLogMessages(org.tigris.subversion.svnclientadapter.SVNUrl, java.lang.String[], org.tigris.subversion.svnclientadapter.SVNRevision, org.tigris.subversion.svnclientadapter.SVNRevision, boolean, boolean)
     */
    public ISVNLogMessage[] getLogMessages(final SVNUrl url, final String[] paths, SVNRevision revStart,
            SVNRevision revEnd, boolean stopOnCopy, boolean fetchChangePath) throws SVNClientException {
        return this.getLogMessages(url, SVNRevision.HEAD, revStart, revEnd, stopOnCopy, fetchChangePath, 0, false);
    }

    /* (non-Javadoc)
     * @see org.tigris.subversion.svnclientadapter.ISVNClientAdapter#getLogMessages(java.io.File, org.tigris.subversion.svnclientadapter.SVNRevision, org.tigris.subversion.svnclientadapter.SVNRevision, boolean)
     */
    public ISVNLogMessage[] getLogMessages(File path, SVNRevision revisionStart, SVNRevision revisionEnd,
            boolean fetchChangePath) throws SVNClientException {
        return this.getLogMessages(path, SVNRevision.HEAD, revisionStart, revisionEnd, false, fetchChangePath, 0,
                false);
    }

    /* (non-Javadoc)
     * @see org.tigris.subversion.svnclientadapter.ISVNClientAdapter#getLogMessages(java.io.File, org.tigris.subversion.svnclientadapter.SVNRevision, org.tigris.subversion.svnclientadapter.SVNRevision, boolean, boolean)
     */
    public ISVNLogMessage[] getLogMessages(File path, SVNRevision revisionStart, SVNRevision revisionEnd,
            boolean stopOnCopy, boolean fetchChangePath) throws SVNClientException {
        return this.getLogMessages(path, SVNRevision.HEAD, revisionStart, revisionEnd, stopOnCopy, fetchChangePath,
                0, false);
    }

    /* (non-Javadoc)
     * @see org.tigris.subversion.svnclientadapter.ISVNClientAdapter#getLogMessages(java.io.File, org.tigris.subversion.svnclientadapter.SVNRevision, org.tigris.subversion.svnclientadapter.SVNRevision, boolean, boolean, long)
     */
    public ISVNLogMessage[] getLogMessages(File path, SVNRevision revisionStart, SVNRevision revisionEnd,
            boolean stopOnCopy, boolean fetchChangePath, long limit) throws SVNClientException {
        //If the file is an uncommitted rename/move, we have to refer to original/source, not the new copy.
        ISVNInfo info = getInfoFromWorkingCopy(path);
        if ((SVNScheduleKind.ADD == info.getSchedule()) && (info.getCopyUrl() != null)) {
            return this.getLogMessages(info.getCopyUrl(), SVNRevision.HEAD, revisionStart, revisionEnd, stopOnCopy,
                    fetchChangePath, limit, false);
        } else {
            return this.getLogMessages(path, SVNRevision.HEAD, revisionStart, revisionEnd, stopOnCopy,
                    fetchChangePath, limit, false);
        }
    }

    /* (non-Javadoc)
     * @see org.tigris.subversion.svnclientadapter.ISVNClientAdapter#getLogMessages(org.tigris.subversion.svnclientadapter.SVNUrl, org.tigris.subversion.svnclientadapter.SVNRevision, org.tigris.subversion.svnclientadapter.SVNRevision, boolean)
     */
    public ISVNLogMessage[] getLogMessages(SVNUrl url, SVNRevision revisionStart, SVNRevision revisionEnd,
            boolean fetchChangePath) throws SVNClientException {
        return this.getLogMessages(url, SVNRevision.HEAD, revisionStart, revisionEnd, false, fetchChangePath, 0,
                false);
    }

    /* (non-Javadoc)
     * @see org.tigris.subversion.svnclientadapter.ISVNClientAdapter#getLogMessages(org.tigris.subversion.svnclientadapter.SVNUrl, org.tigris.subversion.svnclientadapter.SVNRevision, org.tigris.subversion.svnclientadapter.SVNRevision, org.tigris.subversion.svnclientadapter.SVNRevision, boolean, boolean, long)
     */
    public ISVNLogMessage[] getLogMessages(SVNUrl url, SVNRevision pegRevision, SVNRevision revisionStart,
            SVNRevision revisionEnd, boolean stopOnCopy, boolean fetchChangePath, long limit)
            throws SVNClientException {
        return this.getLogMessages(url, pegRevision, revisionStart, revisionEnd, stopOnCopy, fetchChangePath, limit,
                false);
    }

    public ISVNLogMessage[] getLogMessages(File path, SVNRevision pegRevision, SVNRevision revisionStart,
            SVNRevision revisionEnd, boolean stopOnCopy, boolean fetchChangePath, long limit,
            boolean includeMergedRevisions) throws SVNClientException {
        SVNLogMessageCallback worker = new SVNLogMessageCallback();
        this.getLogMessages(path, pegRevision, revisionStart, revisionEnd, stopOnCopy, fetchChangePath, limit,
                includeMergedRevisions, ISVNClientAdapter.DEFAULT_LOG_PROPERTIES, worker);
        return worker.getLogMessages();
    }

    public ISVNLogMessage[] getLogMessages(SVNUrl url, SVNRevision pegRevision, SVNRevision revisionStart,
            SVNRevision revisionEnd, boolean stopOnCopy, boolean fetchChangePath, long limit,
            boolean includeMergedRevisions) throws SVNClientException {
        SVNLogMessageCallback worker = new SVNLogMessageCallback();
        this.getLogMessages(url, pegRevision, revisionStart, revisionEnd, stopOnCopy, fetchChangePath, limit,
                includeMergedRevisions, ISVNClientAdapter.DEFAULT_LOG_PROPERTIES, worker);
        return worker.getLogMessages();
    }

    /* (non-Javadoc)
     * @see org.tigris.subversion.svnclientadapter.ISVNClientAdapter#setIgnoredPatterns(java.io.File, java.util.List)
     */
    public void setIgnoredPatterns(File path, List patterns) throws SVNClientException {
        if (!path.isDirectory())
            return;
        String separator = System.getProperty("line.separator");
        StringBuffer value = new StringBuffer();
        for (Iterator it = patterns.iterator(); it.hasNext();) {
            String pattern = (String) it.next();
            value.append(pattern + separator);
        }
        propertySet(path, ISVNProperty.IGNORE, value.toString(), false);
    }

    /* (non-Javadoc)
     * @see org.tigris.subversion.svnclientadapter.ISVNClientAdapter#addToIgnoredPatterns(java.io.File, java.lang.String)
     */
    public void addToIgnoredPatterns(File path, String pattern) throws SVNClientException {
        List patterns = getIgnoredPatterns(path);
        if (patterns == null) // not a directory
            return;

        // verify that the pattern has not already been added
        for (Iterator it = patterns.iterator(); it.hasNext();) {
            if (((String) it.next()).equals(pattern))
                return; // already added
        }

        patterns.add(pattern);
        setIgnoredPatterns(path, patterns);
    }

    /* (non-Javadoc)
     * @see org.tigris.subversion.svnclientadapter.ISVNClientAdapter#getKeywords(java.io.File)
     */
    public SVNKeywords getKeywords(File path) throws SVNClientException {
        ISVNProperty prop = propertyGet(path, ISVNProperty.KEYWORDS);
        if (prop == null)
            return new SVNKeywords();

        // value is a space-delimited list of the keywords names
        String value = prop.getValue();

        return new SVNKeywords(value);
    }

    /* (non-Javadoc)
     * @see org.tigris.subversion.svnclientadapter.ISVNClientAdapter#addPasswordCallback(org.tigris.subversion.svnclientadapter.ISVNPromptUserPassword)
     */
    public void addPasswordCallback(ISVNPromptUserPassword callback) {
        // Default implementation does nothing
    }

    public boolean statusReturnsRemoteInfo() {
        return false;
    }

    public long[] commitAcrossWC(File[] paths, String message, boolean recurse, boolean keepLocks, boolean Atomic)
            throws SVNClientException {
        notImplementedYet();
        return null;
    }

    protected void notImplementedYet() throws SVNClientException {
        throw new SVNClientException("Not implemented yet");
    }

    public boolean canCommitAcrossWC() {
        return false;
    }

    public void mkdir(SVNUrl url, boolean makeParents, String message) throws SVNClientException {
        if (makeParents) {
            SVNUrl parent = url.getParent();
            if (parent != null) {
                ISVNInfo info = null;
                try {
                    info = this.getInfo(parent);
                } catch (SVNClientException e) {
                }
                if (info == null)
                    this.mkdir(parent, makeParents, message);
            }
        }
        this.mkdir(url, message);
    }

    /**
     * Answer whether running on Windows OS.
     * (Actual code extracted from org.apache.commons.lang.SystemUtils.IS_OS_WINDOWS)
     * (For such one simple method it does make sense to introduce dependency on whole commons-lang.jar)
     * @return true when the underlying 
     */
    public static boolean isOsWindows() {
        try {
            return System.getProperty("os.name").startsWith("Windows");
        } catch (SecurityException ex) {
            // we are not allowed to look at this property
            return false;
        }
    }

    public ISVNInfo getInfo(SVNUrl url) throws SVNClientException {
        return getInfo(url, SVNRevision.HEAD, SVNRevision.HEAD);
    }

    /* (non-Javadoc)
     * @see org.tigris.subversion.svnclientadapter.ISVNClientAdapter#merge(org.tigris.subversion.svnclientadapter.SVNUrl, org.tigris.subversion.svnclientadapter.SVNRevision, org.tigris.subversion.svnclientadapter.SVNUrl, org.tigris.subversion.svnclientadapter.SVNRevision, java.io.File, boolean, boolean, boolean)
     */
    public void merge(SVNUrl path1, SVNRevision revision1, SVNUrl path2, SVNRevision revision2, File localPath,
            boolean force, boolean recurse, boolean dryRun) throws SVNClientException {
        merge(path1, revision1, path2, revision2, localPath, force, recurse, dryRun, false);
    }

    /* (non-Javadoc)
     * @see org.tigris.subversion.svnclientadapter.ISVNClientAdapter#merge(org.tigris.subversion.svnclientadapter.SVNUrl, org.tigris.subversion.svnclientadapter.SVNRevision, org.tigris.subversion.svnclientadapter.SVNUrl, org.tigris.subversion.svnclientadapter.SVNRevision, java.io.File, boolean, boolean)
     */
    public void merge(SVNUrl path1, SVNRevision revision1, SVNUrl path2, SVNRevision revision2, File localPath,
            boolean force, boolean recurse) throws SVNClientException {
        merge(path1, revision1, path2, revision2, localPath, force, recurse, false, false);
    }

    /* (non-Javadoc)
     * @see org.tigris.subversion.svnclientadapter.ISVNClientAdapter#propertyGet(org.tigris.subversion.svnclientadapter.SVNUrl, java.lang.String)
     */
    public ISVNProperty propertyGet(SVNUrl url, String propertyName) throws SVNClientException {
        return propertyGet(url, SVNRevision.HEAD, SVNRevision.HEAD, propertyName);
    }

    public void diff(File[] paths, File outFile, boolean recurse) throws SVNClientException {
        FileOutputStream os = null;
        try {
            ArrayList tempFiles = new ArrayList();
            for (int i = 0; i < paths.length; i++) {
                File tempFile = File.createTempFile("tempDiff", ".txt");
                tempFile.deleteOnExit();
                diff(paths[i], tempFile, recurse);
                tempFiles.add(tempFile);
            }
            os = new FileOutputStream(outFile);
            Iterator iter = tempFiles.iterator();
            while (iter.hasNext()) {
                File tempFile = (File) iter.next();
                FileInputStream is = new FileInputStream(tempFile);
                byte[] buffer = new byte[4096];
                int bytes_read;
                while ((bytes_read = is.read(buffer)) != -1)
                    os.write(buffer, 0, bytes_read);
                is.close();
            }
        } catch (Exception e) {
            throw new SVNClientException(e);
        } finally {
            if (os != null)
                try {
                    os.close();
                } catch (IOException e) {
                }
        }
    }

    /* (non-Javadoc)
     * @see org.tigris.subversion.svnclientadapter.ISVNClientAdapter#createPatch(java.io.File[], java.io.File, java.io.File, boolean)
     */
    public void createPatch(File[] paths, File relativeToPath, File outFile, boolean recurse)
            throws SVNClientException {
        File tmpFile;
        try {
            tmpFile = File.createTempFile("svn", "patch");
            tmpFile.deleteOnExit();
        } catch (IOException e) {
            throw new SVNClientException(e);
        }
        this.diff(paths, tmpFile, recurse);
        stripPathsFromPatch(tmpFile, outFile, relativeToPath);
    }

    /**
     * Takes svn diff output and processes it to remove absolute paths and
     * convert them to relative paths which makes it easier to apply patch
     * 
     * @param tmpFile - disk file containing diff output
     * @param outFile - file to store the updated diff output
     * @param relativeToPath - path to make file references relative to or null
     *             for absolute paths
     * @throws SVNClientException 
     */
    private void stripPathsFromPatch(File tmpFile, File outFile, File relativeToPath) throws SVNClientException {
        String relativeStr = null;
        if (relativeToPath != null) {
            try {
                if (relativeToPath.isDirectory())
                    relativeStr = relativeToPath.getCanonicalPath();
                else
                    relativeStr = relativeToPath.getParentFile().getCanonicalPath();
            } catch (IOException e1) {
                if (relativeToPath.isDirectory())
                    relativeStr = relativeToPath.getAbsolutePath();
                else
                    relativeStr = relativeToPath.getParentFile().getAbsolutePath();
            }
            relativeStr += "/";
            relativeStr = relativeStr.replace('\\', '/');
        }

        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(tmpFile);
            fos = new FileOutputStream(outFile);
            byte b[] = new byte[fis.available()];
            fis.read(b);
            if (relativeToPath != null) {
                byte o[] = new String(b).replaceAll(relativeStr, "").getBytes();
                fos.write(o);
            } else {
                fos.write(b);
            }
        } catch (FileNotFoundException e) {
            throw new SVNClientException(e);
        } catch (IOException e) {
            throw new SVNClientException(e);
        } finally {
            try {
                if (fis != null)
                    fis.close();
            } catch (IOException e) {
            }
            try {
                if (fos != null)
                    fos.close();
            } catch (IOException e) {
            }
        }
    }

}