001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.maven.scm.provider.hg.command.changelog;
020
021import java.text.SimpleDateFormat;
022import java.util.ArrayList;
023import java.util.Arrays;
024import java.util.Date;
025import java.util.List;
026
027import org.apache.maven.scm.ChangeSet;
028import org.apache.maven.scm.ScmBranch;
029import org.apache.maven.scm.ScmException;
030import org.apache.maven.scm.ScmFileSet;
031import org.apache.maven.scm.ScmResult;
032import org.apache.maven.scm.ScmVersion;
033import org.apache.maven.scm.command.Command;
034import org.apache.maven.scm.command.changelog.AbstractChangeLogCommand;
035import org.apache.maven.scm.command.changelog.ChangeLogScmRequest;
036import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
037import org.apache.maven.scm.command.changelog.ChangeLogSet;
038import org.apache.maven.scm.provider.ScmProviderRepository;
039import org.apache.maven.scm.provider.hg.HgUtils;
040import org.apache.maven.scm.provider.hg.command.HgCommandConstants;
041
042/**
043 * @author <a href="mailto:thurner.rupert@ymono.net">thurner rupert</a>
044 * @author Olivier Lamy
045 */
046public class HgChangeLogCommand extends AbstractChangeLogCommand implements Command {
047    /**
048     * {@inheritDoc}
049     */
050    @Override
051    protected ChangeLogScmResult executeChangeLogCommand(ChangeLogScmRequest request) throws ScmException {
052        final ScmVersion startVersion = request.getStartRevision();
053        final ScmVersion endVersion = request.getEndRevision();
054        final ScmFileSet fileSet = request.getScmFileSet();
055        final String datePattern = request.getDatePattern();
056        if (startVersion != null || endVersion != null) {
057            final ScmProviderRepository scmProviderRepository =
058                    request.getScmRepository().getProviderRepository();
059            return executeChangeLogCommand(scmProviderRepository, fileSet, startVersion, endVersion, datePattern);
060        }
061        return executeChangeLogCommand(
062                fileSet, request.getStartDate(), request.getEndDate(), datePattern, request.getLimit());
063    }
064
065    /**
066     * {@inheritDoc}
067     */
068    protected ChangeLogScmResult executeChangeLogCommand(
069            ScmProviderRepository scmProviderRepository,
070            ScmFileSet fileSet,
071            Date startDate,
072            Date endDate,
073            ScmBranch branch,
074            String datePattern)
075            throws ScmException {
076        return executeChangeLogCommand(fileSet, startDate, endDate, datePattern, null);
077    }
078
079    private ChangeLogScmResult executeChangeLogCommand(
080            ScmFileSet fileSet, Date startDate, Date endDate, String datePattern, Integer limit) throws ScmException {
081        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
082        StringBuilder dateInterval = new StringBuilder();
083        // TRICK: Mercurial 1.9.3 don't accept 1970-01-01
084        dateInterval.append(
085                dateFormat.format(startDate == null ? new Date(1000L * 60 * 60 * 24) : startDate)); // From 2. Jan 1970
086        dateInterval.append(" to ");
087        dateInterval.append(dateFormat.format(endDate == null ? new Date() : endDate)); // Upto now
088
089        List<String> cmd = new ArrayList<>();
090        cmd.addAll(Arrays.asList(
091                HgCommandConstants.LOG_CMD, HgCommandConstants.TEMPLATE_OPTION,
092                HgCommandConstants.TEMPLATE_FORMAT, HgCommandConstants.NO_MERGES_OPTION,
093                HgCommandConstants.DATE_OPTION, dateInterval.toString()));
094
095        if (limit != null && limit > 0) {
096            cmd.add(HgCommandConstants.LIMIT_OPTION);
097            cmd.add(Integer.toString(limit));
098        }
099
100        HgChangeLogConsumer consumer = new HgChangeLogConsumer(datePattern);
101        ScmResult result = HgUtils.execute(consumer, fileSet.getBasedir(), cmd.toArray(new String[cmd.size()]));
102
103        List<ChangeSet> logEntries = consumer.getModifications();
104        ChangeLogSet changeLogSet = new ChangeLogSet(logEntries, startDate, endDate);
105        return new ChangeLogScmResult(changeLogSet, result);
106    }
107
108    @Override
109    protected ChangeLogScmResult executeChangeLogCommand(
110            ScmProviderRepository repository,
111            ScmFileSet fileSet,
112            ScmVersion startVersion,
113            ScmVersion endVersion,
114            String datePattern)
115            throws ScmException {
116        StringBuilder revisionInterval = new StringBuilder();
117        if (startVersion != null) {
118            revisionInterval.append(startVersion.getName());
119        }
120        revisionInterval.append(":");
121        if (endVersion != null) {
122            revisionInterval.append(endVersion.getName());
123        }
124
125        String[] cmd = new String[] {
126            HgCommandConstants.LOG_CMD,
127            HgCommandConstants.TEMPLATE_OPTION,
128            HgCommandConstants.TEMPLATE_FORMAT,
129            HgCommandConstants.NO_MERGES_OPTION,
130            HgCommandConstants.REVISION_OPTION,
131            revisionInterval.toString()
132        };
133        HgChangeLogConsumer consumer = new HgChangeLogConsumer(datePattern);
134        ScmResult result = HgUtils.execute(consumer, fileSet.getBasedir(), cmd);
135
136        List<ChangeSet> logEntries = consumer.getModifications();
137        Date startDate = null;
138        Date endDate = null;
139        if (!logEntries.isEmpty()) {
140            startDate = logEntries.get(0).getDate();
141            endDate = logEntries.get(logEntries.size() - 1).getDate();
142        }
143        ChangeLogSet changeLogSet = new ChangeLogSet(logEntries, startDate, endDate);
144        changeLogSet.setStartVersion(startVersion);
145        changeLogSet.setEndVersion(endVersion);
146        return new ChangeLogScmResult(changeLogSet, result);
147    }
148}