com.thoughtworks.go.util.SvnLogXmlParser.java Source code

Java tutorial

Introduction

Here is the source code for com.thoughtworks.go.util.SvnLogXmlParser.java

Source

/*
 * Copyright 2019 ThoughtWorks, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.thoughtworks.go.util;

import com.thoughtworks.go.domain.materials.Modification;
import com.thoughtworks.go.domain.materials.ModifiedAction;
import com.thoughtworks.go.domain.materials.svn.SvnCommand;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;

import java.io.StringReader;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.thoughtworks.go.util.ExceptionUtils.bomb;

public class SvnLogXmlParser {

    private static final TimeZone UTC = TimeZone.getTimeZone("UTC");

    public List<Modification> parse(String svnLogOutput, String path, SAXBuilder builder) {
        try {
            Document document = builder.build(new StringReader(svnLogOutput));
            return parseDOMTree(document, path);
        } catch (Exception e) {
            throw bomb("Unable to parse svn log output: " + svnLogOutput, e);
        }
    }

    private List<Modification> parseDOMTree(Document document, String path) throws ParseException {
        List<Modification> modifications = new ArrayList<>();

        Element rootElement = document.getRootElement();
        List logEntries = rootElement.getChildren("logentry");
        for (Iterator iterator = logEntries.iterator(); iterator.hasNext();) {
            Element logEntry = (Element) iterator.next();

            Modification modification = parseLogEntry(logEntry, path);
            if (modification != null) {
                modifications.add(modification);
            }
        }

        return modifications;
    }

    private Modification parseLogEntry(Element logEntry, String path) throws ParseException {
        Element logEntryPaths = logEntry.getChild("paths");
        if (logEntryPaths == null) {
            /* Path-based access control forbids us from learning
             * details of this log entry, so skip it. */
            return null;
        }

        Date modifiedTime = convertDate(logEntry.getChildText("date"));
        String author = logEntry.getChildText("author");
        String comment = logEntry.getChildText("msg");
        String revision = logEntry.getAttributeValue("revision");

        Modification modification = new Modification(author, comment, null, modifiedTime, revision);

        List paths = logEntryPaths.getChildren("path");
        for (Iterator iterator = paths.iterator(); iterator.hasNext();) {
            Element node = (Element) iterator.next();
            if (underPath(path, node.getText())) {
                ModifiedAction action = convertAction(node.getAttributeValue("action"));
                modification.createModifiedFile(node.getText(), null, action);
            }
        }

        return modification;
    }

    private boolean underPath(String path, String text) {
        return text.startsWith(path);
    }

    /**
     * Converts the specified SVN date string into a Date.
     *
     * @param date with format "yyyy-MM-dd'T'HH:mm:ss.SSS" + "...Z"
     * @return converted date
     * @throws java.text.ParseException if specified date doesn't match the expected format
     */
    static Date convertDate(String date) throws ParseException {
        final int zIndex = date.indexOf('Z');
        if (zIndex - 3 < 0) {
            throw new ParseException(date + " doesn't match the expected subversion date format", date.length());
        }
        String withoutMicroSeconds = date.substring(0, zIndex - 3);

        return getOutDateFormatter().parse(withoutMicroSeconds);
    }

    public static DateFormat getOutDateFormatter() {
        DateFormat f = new SimpleDateFormat(SvnCommand.SVN_DATE_FORMAT_OUT);
        f.setTimeZone(UTC);
        return f;
    }

    private ModifiedAction convertAction(String action) {
        if (action.equals("A")) {
            return ModifiedAction.added;
        }
        if (action.equals("M")) {
            return ModifiedAction.modified;
        }
        if (action.equals("D")) {
            return ModifiedAction.deleted;
        }
        return ModifiedAction.unknown;
    }

    public HashMap<String, String> parseInfoToGetUUID(String output, String queryURL, SAXBuilder builder) {
        HashMap<String, String> uidToUrlMap = new HashMap<>();
        try {
            Document document = builder.build(new StringReader(output));
            Element root = document.getRootElement();
            List<Element> entries = root.getChildren("entry");
            for (Element entry : entries) {
                uidToUrlMap.put(queryURL, entry.getChild("repository").getChild("uuid").getValue());
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return uidToUrlMap;
    }

}