hudson.plugins.clearcase.action.AbstractCheckoutAction.java Source code

Java tutorial

Introduction

Here is the source code for hudson.plugins.clearcase.action.AbstractCheckoutAction.java

Source

/**
 * The MIT License
 *
 * Copyright (c) 2007-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Erik Ramfelt,
 *                          Henrik Lynggaard, Peter Liljenberg, Andrew Bayer, Vincent Latombe
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package hudson.plugins.clearcase.action;

import hudson.FilePath;
import hudson.Launcher;
import hudson.plugins.clearcase.ClearTool;
import hudson.plugins.clearcase.ConfigSpec;
import hudson.plugins.clearcase.MkViewParameters;
import hudson.plugins.clearcase.ViewType;
import hudson.plugins.clearcase.viewstorage.ViewStorage;

import java.io.IOException;
import java.io.PrintStream;
import java.util.LinkedHashSet;
import java.util.Set;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.Validate;

/**
 * Check out action that will check out files into a snapshot view.
 */
public abstract class AbstractCheckoutAction implements CheckOutAction {

    public static class LoadRulesDelta {
        private final Set<String> removed;
        private final Set<String> added;

        public LoadRulesDelta(Set<String> removed, Set<String> added) {
            super();
            this.removed = removed;
            this.added = added;
        }

        public String[] getAdded() {
            return added.toArray(new String[added.size()]);
        }

        public String[] getRemoved() {
            return removed.toArray(new String[removed.size()]);
        }

        public boolean isEmpty() {
            return added.isEmpty() && removed.isEmpty();
        }
    }

    protected final ClearTool cleartool;
    protected final String[] loadRules;
    protected final boolean useUpdate;
    protected final String viewPath;
    protected final ViewStorage viewStorage;

    public AbstractCheckoutAction(ClearTool cleartool, String[] loadRules, boolean useUpdate, String viewPath,
            ViewStorage viewStorage) {
        Validate.notNull(cleartool);
        this.cleartool = cleartool;
        this.loadRules = loadRules;
        this.useUpdate = useUpdate;
        this.viewPath = viewPath;
        this.viewStorage = viewStorage;
    }

    @Override
    public boolean isViewValid(Launcher launcher, FilePath workspace, String viewTag)
            throws IOException, InterruptedException {
        Validate.notEmpty(viewPath);
        FilePath filePath = new FilePath(workspace, viewPath);
        boolean viewPathExists = filePath.exists();
        try {
            String currentViewTag = cleartool.lscurrentview(viewPath);
            return cleartool.doesViewExist(viewTag) && viewPathExists && viewTag.equals(currentViewTag);
        } catch (IOException e) {
            return false;
        }
    }

    /**
     * Manages the re-creation of the view if needed. If something exists but not referenced correctly as a view, it will be renamed and the view will be created
     * @param workspace The job's workspace
     * @param viewTag The view identifier on server. Must be unique on server
     * @param viewPath The workspace relative path of the view
     * @param streamSelector The stream selector, using streamName[@pvob] format
     * @return true if a mkview has been done, false if a view existed and is reused
     * @throws IOException
     * @throws InterruptedException
     */
    protected boolean cleanAndCreateViewIfNeeded(FilePath workspace, String viewTag, String viewPath,
            String streamSelector) throws IOException, InterruptedException {
        Validate.notEmpty(viewPath);
        FilePath filePath = new FilePath(workspace, viewPath);
        boolean viewPathExists = filePath.exists();
        boolean doViewCreation = true;
        if (cleartool.doesViewExist(viewTag)) {
            if (viewPathExists) {
                if (viewTag.equals(cleartool.lscurrentview(viewPath))) {
                    if (useUpdate) {
                        doViewCreation = false;
                    } else {
                        cleartool.rmview(viewPath);
                    }
                } else {
                    filePath.renameTo(getUnusedFilePath(workspace, viewPath));
                    rmviewtag(viewTag);
                }
            } else {
                rmviewtag(viewTag);
            }
        } else {
            if (viewPathExists) {
                filePath.renameTo(getUnusedFilePath(workspace, viewPath));
            }
        }
        if (doViewCreation) {
            MkViewParameters params = new MkViewParameters();
            params.setType(ViewType.Snapshot);
            params.setViewPath(viewPath);
            params.setViewTag(viewTag);
            params.setStreamSelector(streamSelector);
            params.setViewStorage(viewStorage);
            cleartool.mkview(params);
        }
        return doViewCreation;
    }

    private void rmviewtag(String viewTag) throws InterruptedException, IOException {
        try {
            cleartool.rmviewtag(viewTag);
        } catch (IOException e) {
            // ClearCase RT doesn't support rmview -tag
            cleartool.rmtag(viewTag);
        }
    }

    protected AbstractCheckoutAction.LoadRulesDelta getLoadRulesDelta(Set<String> configSpecLoadRules,
            Launcher launcher) {
        Set<String> removedLoadRules = new LinkedHashSet<String>(configSpecLoadRules);
        Set<String> addedLoadRules = new LinkedHashSet<String>();
        if (!ArrayUtils.isEmpty(loadRules)) {
            for (String loadRule : loadRules) {
                addedLoadRules.add(ConfigSpec.cleanLoadRule(loadRule, launcher.isUnix()));
            }
            removedLoadRules.removeAll(addedLoadRules);
            addedLoadRules.removeAll(configSpecLoadRules);
            PrintStream logger = launcher.getListener().getLogger();
            for (String removedLoadRule : removedLoadRules) {
                logger.println("Removed load rule : " + removedLoadRule);
            }
            for (String addedLoadRule : addedLoadRules) {
                logger.println("Added load rule : " + addedLoadRule);
            }
        }
        return new AbstractCheckoutAction.LoadRulesDelta(removedLoadRules, addedLoadRules);
    }

    private FilePath getUnusedFilePath(FilePath workspace, String viewName)
            throws IOException, InterruptedException {
        for (int i = 1; i < Integer.MAX_VALUE; i++) {
            FilePath result = new FilePath(workspace, viewName + ".keep." + i);
            if (!result.exists()) {
                return result;
            }
        }
        return null;
    }
}