org.sventon.web.ctrl.template.DiffController.java Source code

Java tutorial

Introduction

Here is the source code for org.sventon.web.ctrl.template.DiffController.java

Source

/*
 * ====================================================================
 * Copyright (c) 2005-2012 sventon project. All rights reserved.
 *
 * This software is licensed as described in the file LICENSE, which
 * you should have received as part of this distribution. The terms
 * are also available at http://www.sventon.org.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 * ====================================================================
 */
package org.sventon.web.ctrl.template;

import org.apache.commons.lang.Validate;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.sventon.SVNConnection;
import org.sventon.SventonException;
import org.sventon.diff.DiffException;
import org.sventon.diff.IdenticalFilesException;
import org.sventon.diff.IllegalFileFormatException;
import org.sventon.model.DiffStatus;
import org.sventon.model.DiffStyle;
import org.sventon.model.DirEntry;
import org.sventon.model.FileRevision;
import org.sventon.web.UserRepositoryContext;
import org.sventon.web.command.BaseCommand;
import org.sventon.web.command.DiffCommand;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * The DiffController generates a Side-by-side diff between two repository entries.
 *
 * @author jesper@sventon.org
 */
public final class DiffController extends AbstractTemplateController {

    /**
     * User preferred diff style.
     */
    private DiffStyle preferredDiffStyle = DiffStyle.sidebyside;

    @Override
    protected ModelAndView svnHandle(final SVNConnection connection, final BaseCommand cmd, final long headRevision,
            final UserRepositoryContext userRepositoryContext, final HttpServletRequest request,
            final HttpServletResponse response, final BindException exception) throws Exception {

        final DiffCommand command = (DiffCommand) cmd;

        final Map<String, Object> model = new HashMap<String, Object>();
        final ModelAndView modelAndView = new ModelAndView();
        final String charset = userRepositoryContext.getCharset();

        handleDiffPrevious(connection, command);
        handleDiffStyle(command);

        try {
            final DirEntry.Kind nodeKind = getRepositoryService().getNodeKind(connection, command.getPath(),
                    command.getRevisionNumber());
            model.put("isFile", DirEntry.Kind.FILE == nodeKind);

            final DirEntry.Kind nodeKindForDiff = getRepositoryService().getNodeKindForDiff(connection,
                    command.getFrom(), command.getTo(), command.getPegRevision());
            if (DirEntry.Kind.DIR == nodeKindForDiff) {
                model.putAll(handlePathDiff(connection, modelAndView, command));
            } else if (DirEntry.Kind.FILE == nodeKindForDiff) {
                model.putAll(handleFileDiff(connection, modelAndView, command, charset));
            } else {
                throw new DiffException("Unable to diff entry of kind: " + nodeKindForDiff);
            }
        } catch (final IdenticalFilesException ife) {
            logger.debug("Files are identical");
            model.put("isIdentical", true);
        } catch (final IllegalFileFormatException iffe) {
            logger.info(iffe.getMessage());
            model.put("isBinary", true); // Indicates that one or both files are in binary format.
        }
        modelAndView.addAllObjects(model);
        return modelAndView;
    }

    private void handleDiffPrevious(SVNConnection connection, DiffCommand command) throws SventonException {
        if (!command.hasEntries()) {
            logger.debug("No entries has been set - diffing with previous");
            final List<FileRevision> revisions = getRepositoryService().getFileRevisions(connection,
                    command.getPath(), command.getRevisionNumber());
            command.setEntries(revisions.toArray(new FileRevision[revisions.size()]));
        }
    }

    private void handleDiffStyle(DiffCommand command) {
        if (DiffStyle.unspecified == command.getStyle()) {
            logger.debug("Setting user preferred diff style: " + preferredDiffStyle);
            command.setStyle(preferredDiffStyle);
        }
    }

    private Map<String, Object> handleFileDiff(final SVNConnection connection, final ModelAndView modelAndView,
            final DiffCommand command, final String charset) throws SventonException, DiffException {

        final Map<String, Object> model = new HashMap<String, Object>();

        switch (command.getStyle()) {
        case inline:
            modelAndView.setViewName("inlineDiff");
            model.put("diffResult", getRepositoryService().diffInline(connection, command.getFrom(),
                    command.getTo(), command.getPegRevision(), charset));
            break;
        case sidebyside:
            modelAndView.setViewName("sideBySideDiff");
            model.put("diffResult", getRepositoryService().diffSideBySide(connection, command.getFrom(),
                    command.getTo(), command.getPegRevision(), charset));
            break;
        case unified:
            modelAndView.setViewName("unifiedDiff");
            model.put("diffResult", getRepositoryService().diffUnified(connection, command.getFrom(),
                    command.getTo(), command.getPegRevision(), charset));
            break;
        default:
            throw new IllegalStateException();
        }
        model.put("isIdentical", false);
        model.put("isBinary", false);
        return model;
    }

    private Map<String, Object> handlePathDiff(final SVNConnection connection, final ModelAndView modelAndView,
            final DiffCommand command) throws SventonException {

        final Map<String, Object> model = new HashMap<String, Object>();
        logger.debug("Diffing dirs");
        modelAndView.setViewName("pathDiff");

        final List<DiffStatus> diffResult = getRepositoryService().diffPaths(connection, command.getFrom(),
                command.getTo());
        logger.debug("Number of path diffs: " + diffResult.size());
        model.put("isIdentical", diffResult.isEmpty());
        model.put("diffResult", diffResult);
        return model;
    }

    /**
     * Sets the preferred diff style for diff previous view.
     *
     * @param diffStyle Preferred diff style.
     */
    public void setPreferredDiffStyle(final DiffStyle diffStyle) {
        Validate.notNull(diffStyle);
        this.preferredDiffStyle = diffStyle;

    }
}