org.obiba.opal.core.vcs.command.OpalWriteViewsCommand.java Source code

Java tutorial

Introduction

Here is the source code for org.obiba.opal.core.vcs.command.OpalWriteViewsCommand.java

Source

/*
 * Copyright (c) 2014 OBiBa. All rights reserved.
 *
 * This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.obiba.opal.core.vcs.command;

import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.validation.constraints.NotNull;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.transport.PushResult;
import org.obiba.git.GitException;
import org.obiba.git.command.AbstractGitWriteCommand;
import org.obiba.magma.MagmaEngine;
import org.obiba.magma.ValueTable;
import org.obiba.magma.Variable;
import org.obiba.magma.js.views.JavascriptClause;
import org.obiba.magma.views.View;
import org.obiba.magma.views.WhereClause;
import org.obiba.magma.views.support.VariableOperationContext;
import org.obiba.magma.xstream.MagmaXStreamExtension;
import org.obiba.opal.core.vcs.OpalGitUtils;

import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.thoughtworks.xstream.XStream;

import static org.obiba.magma.views.support.VariableOperationContext.Operation;

public class OpalWriteViewsCommand extends AbstractGitWriteCommand {

    private final Set<View> views;

    private final VariableOperationContext context;

    private OpalWriteViewsCommand(@NotNull File repositoryPath, @NotNull Set<View> views,
            @NotNull String commitMessage, VariableOperationContext context) {
        super(repositoryPath, OpalGitUtils.getGitViewsWorkFolder(), commitMessage);
        this.views = views;
        this.context = context;
    }

    @Override
    public Iterable<PushResult> execute(Git git) {
        try {
            File localRepo = git.getRepository().getWorkTree();
            List<String> varFilesToRemove = Lists.newArrayList();
            StringBuilder message = new StringBuilder();
            serializeAllViewFiles(localRepo, varFilesToRemove, message);
            String currentMessage = getCommitMessage();
            setCommitMessage((Strings.isNullOrEmpty(currentMessage) ? "Update " : currentMessage + " ") + message);

            for (String toRemove : varFilesToRemove) {
                git.rm().addFilepattern(toRemove).call();
            }
            git.add().addFilepattern(".").call();
            return commitAndPush(git);
        } catch (IOException | GitAPIException e) {
            throw new GitException(e);
        }
    }

    private void serializeAllViewFiles(File localRepo, Collection<String> varFilesToRemove, StringBuilder message)
            throws IOException {
        message.append("[");
        for (View view : views) {
            doWriteGitView(localRepo, view, varFilesToRemove);
            if (message.length() > 1) {
                message.append(", ");
            }
            message.append(view.getName());
        }
        message.append("]");
    }

    private void doWriteGitView(File localRepo, View view, Collection<String> varFilesToRemove) throws IOException {
        File viewRepo = new File(localRepo, view.getName());
        viewRepo.mkdirs();

        // Write serialized view
        File viewFile = new File(viewRepo, OpalGitUtils.VIEW_FILE_NAME);
        try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(viewFile), Charsets.UTF_8)) {
            getXStream().toXML(view, writer);
        }

        doWriteGitViewWhere(viewRepo, view, varFilesToRemove);
        if (context != null && context.hasOperations(view)) {
            doWriteGitViewVariables(viewRepo, view, context.getOperations(view), varFilesToRemove);
        } else {
            doWriteGitViewVariables(viewRepo, view, varFilesToRemove);
        }
    }

    private void doWriteGitViewWhere(File viewRepo, View view, Collection<String> varFilesToRemove)
            throws IOException {
        File scriptFile = new File(viewRepo, OpalGitUtils.VIEW_WHERE_FILE_NAME);
        WhereClause where = view.getWhereClause();

        if (where != null && where instanceof JavascriptClause) {
            String script = ((JavascriptClause) where).getScript();
            try (FileWriter fileWriter = new FileWriter(scriptFile)) {
                fileWriter.append(script);
                fileWriter.flush();
            }
        } else if (scriptFile.exists()) {
            varFilesToRemove.add(viewRepo.getName() + "/" + scriptFile.getName());
        }
    }

    private void doWriteGitViewVariables(File viewRepo, ValueTable view,
            Map<Operation, Collection<Variable>> operations, Collection<String> varFilesToRemove)
            throws IOException {
        // Write variable script files
        Collection<Variable> variablesToWrite = operations.get(Operation.ADD);
        if (variablesToWrite != null) {
            for (Variable variable : variablesToWrite) {
                doWriteGitViewVariable(viewRepo, variable);
            }
        }

        // Remove variable script files
        Collection<Variable> variablesToDelete = operations.get(Operation.DELETE);
        if (variablesToDelete != null) {
            for (Variable variable : variablesToDelete) {
                varFilesToRemove.add(OpalGitUtils.getVariableFilePath(view.getName(), variable.getName()));
            }
        }

    }

    private void doWriteGitViewVariables(File viewRepo, ValueTable view, Collection<String> varFilesToRemove)
            throws IOException {
        // Write variable script files
        for (Variable variable : view.getVariables()) {
            doWriteGitViewVariable(viewRepo, variable);
        }
        // Detect removed variables

        for (File f : viewRepo.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.getName().endsWith(OpalGitUtils.VARIABLE_FILE_EXTENSION);
            }
        })) {
            String varName = f.getName().substring(0, f.getName().length() - 3);
            if (!view.hasVariable(varName)) {
                varFilesToRemove.add(f.getParentFile().getName() + File.separator + f.getName());
            }
        }
    }

    private void doWriteGitViewVariable(File viewRepo, Variable variable) throws IOException {
        String script = variable.hasAttribute("script") ? variable.getAttributeStringValue("script") : "null";
        File variableFile = new File(viewRepo, variable.getName() + OpalGitUtils.VARIABLE_FILE_EXTENSION);

        try (FileWriter fileWriter = new FileWriter(variableFile)) {
            fileWriter.append(script);
            fileWriter.flush();
        }
    }

    private XStream getXStream() {
        return MagmaEngine.get().getExtension(MagmaXStreamExtension.class).getXStreamFactory().createXStream();
    }

    public static class Builder {

        private final OpalWriteViewsCommand command;

        public Builder(@NotNull File repositoryPath, @NotNull Set<View> views, @NotNull String comment,
                VariableOperationContext context) {
            command = new OpalWriteViewsCommand(repositoryPath, views, comment, context);
        }

        public OpalWriteViewsCommand build() {
            return command;
        }
    }

}