From 00e3f79945f9ed322ef501c65181ec09aa39871d Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sat, 16 Apr 2011 17:24:59 +0200 Subject: [PATCH] implement new ChangesetViewer api --- .../java/sonia/scm/repository/Changesets.java | 102 ------- .../scm/repository/HgChangesetParser.java | 259 ++++++++++++++++++ .../scm/repository/HgChangesetViewer.java | 103 ++----- .../scm/repository/HgRepositoryHandler.java | 36 --- 4 files changed, 288 insertions(+), 212 deletions(-) delete mode 100644 plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/Changesets.java create mode 100644 plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgChangesetParser.java diff --git a/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/Changesets.java b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/Changesets.java deleted file mode 100644 index 4a7fc66553..0000000000 --- a/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/Changesets.java +++ /dev/null @@ -1,102 +0,0 @@ -/** - * 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; - -//~--- JDK imports ------------------------------------------------------------ - -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -/** - * - * @author Sebastian Sdorra - */ -@XmlRootElement(name = "changesets") -@XmlAccessorType(XmlAccessType.FIELD) -public class Changesets -{ - - /** - * Constructs ... - * - */ - public Changesets() {} - - /** - * Constructs ... - * - * - * @param changesets - */ - public Changesets(List changesets) - { - this.changesets = changesets; - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @return - */ - public List getChangesets() - { - return changesets; - } - - //~--- set methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @param changesets - */ - public void setChangesets(List changesets) - { - this.changesets = changesets; - } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - @XmlElement(name = "changeset") - private List changesets; -} diff --git a/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgChangesetParser.java b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgChangesetParser.java new file mode 100644 index 0000000000..bb9c24efa6 --- /dev/null +++ b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgChangesetParser.java @@ -0,0 +1,259 @@ +/** + * 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; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +import java.text.ParseException; +import java.text.SimpleDateFormat; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +/** + * + * @author Sebastian Sdorra + */ +public class HgChangesetParser +{ + + /** the logger for HgChangesetParser */ + private static final Logger logger = + LoggerFactory.getLogger(HgChangesetParser.class); + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param in + * + * @return + * + * @throws IOException + * @throws ParserConfigurationException + * @throws SAXException + */ + public List parse(InputSource in) + throws SAXException, IOException, ParserConfigurationException + { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + + return parse(builder.parse(in)); + } + + /** + * Method description + * + * + * @param document + * + * @return + */ + private List parse(Document document) + { + List changesetList = new ArrayList(); + NodeList changesetNodeList = document.getElementsByTagName("changeset"); + + if (changesetNodeList != null) + { + for (int i = 0; i < changesetNodeList.getLength(); i++) + { + Node changesetNode = changesetNodeList.item(i); + Changeset changeset = parseChangesetNode(changesetNode); + + if ((changeset != null) && changeset.isValid()) + { + changesetList.add(changeset); + } + } + } + + return changesetList; + } + + /** + * Method description + * + * + * @param changeset + * @param node + */ + private void parseChangesetChildNode(Changeset changeset, Node node) + { + String name = node.getNodeName(); + String value = node.getTextContent(); + + if (Util.isNotEmpty(value)) + { + if ("id".equals(name)) + { + changeset.setId(value); + } + else if ("author".equals(name)) + { + changeset.setAuthor(value); + } + else if ("description".equals(name)) + { + changeset.setDescription(value); + } + else if ("date".equals(name)) + { + try + { + Date date = dateFormat.parse(value); + + changeset.setDate(date.getTime()); + } + catch (ParseException ex) + { + logger.warn("could not parse date", ex); + } + } + else if ("tags".equals(name)) + { + changeset.setTags(getList(value)); + } + else if ("branches".equals(name)) + { + changeset.setBranches(getList(value)); + } + else if ("files-added".equals(name)) + { + getModifications(changeset).setAdded(getList(value)); + } + else if ("files-mods".equals(name)) + { + getModifications(changeset).setModified(getList(value)); + } + else if ("files-dels".equals(name)) + { + getModifications(changeset).setRemoved(getList(value)); + } + } + } + + /** + * Method description + * + * + * @param changesetNode + * + * @return + */ + private Changeset parseChangesetNode(Node changesetNode) + { + Changeset changeset = new Changeset(); + NodeList childrenNodeList = changesetNode.getChildNodes(); + + if (childrenNodeList != null) + { + for (int i = 0; i < childrenNodeList.getLength(); i++) + { + Node child = childrenNodeList.item(i); + + parseChangesetChildNode(changeset, child); + } + } + + return changeset; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param value + * + * @return + */ + private List getList(String value) + { + return Arrays.asList(value.split(" ")); + } + + /** + * Method description + * + * + * @param changeset + * + * @return + */ + private Modifications getModifications(Changeset changeset) + { + Modifications mods = changeset.getModifications(); + + if (mods == null) + { + mods = new Modifications(); + changeset.setModifications(mods); + } + + return mods; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private SimpleDateFormat dateFormat = + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); +} diff --git a/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgChangesetViewer.java b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgChangesetViewer.java index 4d04d2a311..a9254e1f2d 100644 --- a/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgChangesetViewer.java +++ b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgChangesetViewer.java @@ -38,11 +38,13 @@ package sonia.scm.repository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + import sonia.scm.io.Command; import sonia.scm.io.CommandResult; import sonia.scm.io.SimpleCommand; import sonia.scm.util.IOUtil; -import sonia.scm.util.Util; //~--- JDK imports ------------------------------------------------------------ @@ -50,16 +52,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.StringReader; -import java.text.ParseException; -import java.text.SimpleDateFormat; +import java.util.List; -import java.util.Date; -import java.util.StringTokenizer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; +import javax.xml.parsers.ParserConfigurationException; /** * @@ -72,8 +67,20 @@ public class HgChangesetViewer implements ChangesetViewer public static final String ID_TIP = "tip"; /** Field description */ + //J- public static final String TEMPLATE_CHANGESETS = - "{rev}:{node|short}{author|escape}{desc|escape}{date|isodatesec}\n"; + "" + + "{rev}:{node|short}" + + "{author|escape}" + + "{desc|escape}" + + "{date|isodatesec}" + + "{tags}" + + "{branches}" + + "{file_adds}" + + "{file_mods}" + + "{file_dels}" + + "\n"; + //J+ /** Field description */ public static final String TEMPLATE_TOTAL = "{rev}"; @@ -82,10 +89,6 @@ public class HgChangesetViewer implements ChangesetViewer private static final Logger logger = LoggerFactory.getLogger(HgChangesetViewer.class); - /** Field description */ - public static final Pattern REGEX_DATE = - Pattern.compile("([^<]+)"); - //~--- constructors --------------------------------------------------------- /** @@ -138,36 +141,26 @@ public class HgChangesetViewer implements ChangesetViewer if (result.isSuccessfull()) { - StringReader reader = - new StringReader(getFixedOutput(result.getOutput())); - Unmarshaller unmarshaller = handler.createChangesetUnmarshaller(); - Changesets cs = (Changesets) unmarshaller.unmarshal(reader); + StringBuilder sb = new StringBuilder(""); - if ((cs != null) && Util.isNotEmpty(cs.getChangesets())) - { - changesets = new ChangesetPagingResult(total, cs.getChangesets()); - } - else if (logger.isWarnEnabled()) - { - logger.warn("could not find any changeset from {} to {}", start, - start + max); - } - } - else - { - logger.error("could not load changesets, hg return code: {}\n{}", - result.getReturnCode(), result.getOutput()); + sb.append(result.getOutput()).append(""); + + List changesetList = new HgChangesetParser().parse( + new InputSource( + new StringReader(sb.toString()))); + + changesets = new ChangesetPagingResult(total, changesetList); } } - catch (ParseException ex) + catch (ParserConfigurationException ex) { - logger.error("could not parse changeset dates", ex); + logger.error("could not parse changesets", ex); } catch (IOException ex) { logger.error("could not load changesets", ex); } - catch (JAXBException ex) + catch (SAXException ex) { logger.error("could not unmarshall changesets", ex); } @@ -179,44 +172,6 @@ public class HgChangesetViewer implements ChangesetViewer return changesets; } - /** - * Method description - * - * - * @param output - * - * @return - * - * @throws ParseException - */ - private String getFixedOutput(String output) throws ParseException - { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); - StringBuilder changesetLog = new StringBuilder(""); - StringTokenizer st = new StringTokenizer(output, "\n"); - - while (st.hasMoreElements()) - { - String line = st.nextToken(); - Matcher m = REGEX_DATE.matcher(line); - - if (m.find()) - { - String dateString = m.group(1); - Date date = sdf.parse(dateString); - - line = m.replaceAll( - "".concat(Long.toString(date.getTime())).concat("")); - } - - changesetLog.append(line); - } - - changesetLog.append(""); - - return changesetLog.toString(); - } - /** * Method description * diff --git a/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHandler.java b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHandler.java index fd08897789..5a10f8b87e 100644 --- a/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHandler.java +++ b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHandler.java @@ -40,7 +40,6 @@ import com.google.inject.Singleton; import org.slf4j.LoggerFactory; -import sonia.scm.ConfigurationException; import sonia.scm.Type; import sonia.scm.installer.HgInstaller; import sonia.scm.installer.UnixHgInstaller; @@ -62,8 +61,6 @@ import java.io.File; import java.io.IOException; import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; /** * @@ -101,16 +98,6 @@ public class HgRepositoryHandler public HgRepositoryHandler(StoreFactory storeFactory, FileSystem fileSystem) { super(storeFactory, fileSystem); - - try - { - changesetContext = JAXBContext.newInstance(Changesets.class); - } - catch (JAXBException ex) - { - throw new ConfigurationException( - "could not create JAXBContext for Changesets-Class", ex); - } } //~--- methods -------------------------------------------------------------- @@ -236,29 +223,6 @@ public class HgRepositoryHandler //~--- methods -------------------------------------------------------------- - /** - * Method description - * - * - * @return - */ - Unmarshaller createChangesetUnmarshaller() - { - Unmarshaller unmarshaller = null; - - try - { - unmarshaller = changesetContext.createUnmarshaller(); - } - catch (JAXBException ex) - { - throw new ConfigurationException( - "could not create Unmarshaller for Changeset-Class", ex); - } - - return unmarshaller; - } - /** * Method description *