From 46223730fb4fb323d6ac7d2e7b3a7e201c3548ca Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 21 Jul 2011 22:13:42 +0200 Subject: [PATCH] fire mercurial hook events --- .../api/rest/resources/HgHookCallback.java | 61 ++++++- .../scm/repository/HgChangesetViewer.java | 107 ++++++++----- .../scm/repository/HgRepositoryHookEvent.java | 149 ++++++++++++++++++ 3 files changed, 273 insertions(+), 44 deletions(-) create mode 100644 scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHookEvent.java diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/api/rest/resources/HgHookCallback.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/api/rest/resources/HgHookCallback.java index e73cda683c..b970b08648 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/api/rest/resources/HgHookCallback.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/api/rest/resources/HgHookCallback.java @@ -35,9 +35,16 @@ package sonia.scm.api.rest.resources; //~--- non-JDK imports -------------------------------------------------------- +import com.google.inject.Inject; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import sonia.scm.repository.HgRepositoryHandler; +import sonia.scm.repository.HgRepositoryHookEvent; +import sonia.scm.repository.RepositoryManager; +import sonia.scm.repository.RepositoryNotFoundException; + //~--- JDK imports ------------------------------------------------------------ import javax.ws.rs.GET; @@ -58,10 +65,27 @@ public class HgHookCallback private static final Logger logger = LoggerFactory.getLogger(HgHookCallback.class); + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param repositoryManager + * @param handler + */ + @Inject + public HgHookCallback(RepositoryManager repositoryManager, + HgRepositoryHandler handler) + { + this.repositoryManager = repositoryManager; + this.handler = handler; + } + //~--- methods -------------------------------------------------------------- /** - * Method description + * TODO: protect * * * @@ -76,8 +100,39 @@ public class HgHookCallback @PathParam("type") String type, @QueryParam("node") String node) { - logger.warn("retrive hg hook {}, node {}", type, node); + Response response = null; - return Response.ok().build(); + try + { + repositoryManager.fireHookEvent(HgRepositoryHandler.TYPE_NAME, + repositoryName, + new HgRepositoryHookEvent(handler, + repositoryName, node)); + response = Response.ok().build(); + } + catch (RepositoryNotFoundException ex) + { + if (logger.isErrorEnabled()) + { + logger.error("could not find repository {}", repositoryName); + + if (logger.isTraceEnabled()) + { + logger.trace("repository not found", ex); + } + } + + response = Response.status(Response.Status.NOT_FOUND).build(); + } + + return response; } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private HgRepositoryHandler handler; + + /** Field description */ + private RepositoryManager repositoryManager; } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgChangesetViewer.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgChangesetViewer.java index 0404876768..922a2eaca4 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgChangesetViewer.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgChangesetViewer.java @@ -100,9 +100,21 @@ public class HgChangesetViewer implements ChangesetViewer * @param repository */ public HgChangesetViewer(HgRepositoryHandler handler, Repository repository) + { + this(handler, handler.getDirectory(repository).getAbsolutePath()); + } + + /** + * Constructs ... + * + * + * @param handler + * @param repositoryPath + */ + public HgChangesetViewer(HgRepositoryHandler handler, String repositoryPath) { this.handler = handler; - this.repository = repository; + this.repositoryPath = repositoryPath; } //~--- get methods ---------------------------------------------------------- @@ -123,7 +135,6 @@ public class HgChangesetViewer implements ChangesetViewer try { - String repositoryPath = getRepositoryPath(repository); int total = getTotalChangesets(repositoryPath); int startRev = total - start; int endRev = total - start - (max - 1); @@ -133,45 +144,18 @@ public class HgChangesetViewer implements ChangesetViewer endRev = 0; } - Command command = new SimpleCommand(handler.getConfig().getHgBinary(), - "-R", repositoryPath, "log", "-r", - startRev + ":" + endRev, "--template", - TEMPLATE_CHANGESETS); - CommandResult result = command.execute(); + List changesetList = getChangesets(Integer.toString(startRev), + Integer.toString(endRev)); - if (result.isSuccessfull()) + if (changesetList != null) { - StringBuilder sb = new StringBuilder(""); - - sb.append(result.getOutput()).append(""); - - List changesetList = new HgChangesetParser().parse( - new InputSource( - new StringReader(sb.toString()))); - changesets = new ChangesetPagingResult(total, changesetList); - } - else if ( logger.isErrorEnabled() ) - { - logger.error( - "command for fetching changesets failed with exit code {} and output {}", - result.getReturnCode(), - result.getOutput() - ); } } - catch (ParserConfigurationException ex) - { - logger.error("could not parse changesets", ex); - } catch (IOException ex) { logger.error("could not load changesets", ex); } - catch (SAXException ex) - { - logger.error("could not unmarshall changesets", ex); - } finally { IOUtil.close(in); @@ -184,13 +168,56 @@ public class HgChangesetViewer implements ChangesetViewer * Method description * * - * @param repository + * @param startRev + * @param endRev * * @return + * + * @throws IOException */ - private String getRepositoryPath(Repository repository) + public List getChangesets(String startRev, String endRev) + throws IOException { - return handler.getDirectory(repository).getAbsolutePath(); + List changesetList = null; + InputStream in = null; + + try + { + Command command = new SimpleCommand(handler.getConfig().getHgBinary(), + "-R", repositoryPath, "log", "-r", + startRev + ":" + endRev, "--template", + TEMPLATE_CHANGESETS); + CommandResult result = command.execute(); + + if (result.isSuccessfull()) + { + StringBuilder sb = new StringBuilder(""); + + sb.append(result.getOutput()).append(""); + changesetList = new HgChangesetParser().parse( + new InputSource(new StringReader(sb.toString()))); + } + else if (logger.isErrorEnabled()) + { + logger.error( + "command for fetching changesets failed with exit code {} and output {}", + result.getReturnCode(), result.getOutput()); + } + } + catch (ParserConfigurationException ex) + { + logger.error("could not parse changesets", ex); + } + catch (SAXException ex) + { + logger.error("could not unmarshall changesets", ex); + } + finally + { + IOUtil.close(in); + } + + return changesetList; } /** @@ -215,13 +242,11 @@ public class HgChangesetViewer implements ChangesetViewer { total = Integer.parseInt(result.getOutput().trim()); } - else if ( logger.isErrorEnabled() ) + else if (logger.isErrorEnabled()) { logger.error( - "could not read tip revision, command returned with exit code {} and content {}", - result.getReturnCode(), - result.getOutput() - ); + "could not read tip revision, command returned with exit code {} and content {}", + result.getReturnCode(), result.getOutput()); } return total; @@ -233,5 +258,5 @@ public class HgChangesetViewer implements ChangesetViewer private HgRepositoryHandler handler; /** Field description */ - private Repository repository; + private String repositoryPath; } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHookEvent.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHookEvent.java new file mode 100644 index 0000000000..3f503c54bc --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHookEvent.java @@ -0,0 +1,149 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.repository; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.IOException; + +import java.util.Collection; +import java.util.List; + +/** + * + * @author Sebastian Sdorra + */ +public class HgRepositoryHookEvent extends AbstractRepositoryHookEvent +{ + + /** Field description */ + public static final String REV_TIP = "tip"; + + /** the logger for HgRepositoryHookEvent */ + private static final Logger logger = + LoggerFactory.getLogger(HgRepositoryHookEvent.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param handler + * @param repositoryName + * @param startRev + */ + public HgRepositoryHookEvent(HgRepositoryHandler handler, + String repositoryName, String startRev) + { + this.handler = handler; + this.repositoryName = repositoryName; + this.startRev = startRev; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public Collection getChangesets() + { + if (changesets == null) + { + try + { + changesets = createChangesetViewer().getChangesets(startRev, REV_TIP); + } + catch (IOException ex) + { + logger.error("could not load changesets", ex); + } + } + + return changesets; + } + + /** + * Method description + * + * + * @return + */ + @Override + public RepositoryHookType getType() + { + return RepositoryHookType.POST_RECEIVE; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + private HgChangesetViewer createChangesetViewer() + { + File directory = handler.getConfig().getRepositoryDirectory(); + File repositoryDirectory = new File(directory, repositoryName); + + return new HgChangesetViewer(handler, + repositoryDirectory.getAbsolutePath()); + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private List changesets; + + /** Field description */ + private HgRepositoryHandler handler; + + /** Field description */ + private String repositoryName; + + /** Field description */ + private String startRev; +}