Java tutorial
/* * ==================================================================== * 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; } }