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;
020
021import java.io.File;
022import java.util.ArrayList;
023import java.util.Date;
024import java.util.List;
025
026import org.apache.maven.scm.CommandParameter;
027import org.apache.maven.scm.CommandParameters;
028import org.apache.maven.scm.NoSuchCommandScmException;
029import org.apache.maven.scm.ScmBranch;
030import org.apache.maven.scm.ScmBranchParameters;
031import org.apache.maven.scm.ScmException;
032import org.apache.maven.scm.ScmFileSet;
033import org.apache.maven.scm.ScmRevision;
034import org.apache.maven.scm.ScmTagParameters;
035import org.apache.maven.scm.ScmVersion;
036import org.apache.maven.scm.command.add.AddScmResult;
037import org.apache.maven.scm.command.blame.BlameScmRequest;
038import org.apache.maven.scm.command.blame.BlameScmResult;
039import org.apache.maven.scm.command.branch.BranchScmResult;
040import org.apache.maven.scm.command.changelog.ChangeLogScmRequest;
041import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
042import org.apache.maven.scm.command.checkin.CheckInScmResult;
043import org.apache.maven.scm.command.checkout.CheckOutScmResult;
044import org.apache.maven.scm.command.diff.DiffScmResult;
045import org.apache.maven.scm.command.edit.EditScmResult;
046import org.apache.maven.scm.command.export.ExportScmResult;
047import org.apache.maven.scm.command.info.InfoScmResult;
048import org.apache.maven.scm.command.list.ListScmResult;
049import org.apache.maven.scm.command.login.LoginScmResult;
050import org.apache.maven.scm.command.mkdir.MkdirScmResult;
051import org.apache.maven.scm.command.remoteinfo.RemoteInfoScmResult;
052import org.apache.maven.scm.command.remove.RemoveScmResult;
053import org.apache.maven.scm.command.status.StatusScmResult;
054import org.apache.maven.scm.command.tag.TagScmResult;
055import org.apache.maven.scm.command.unedit.UnEditScmResult;
056import org.apache.maven.scm.command.untag.UntagScmResult;
057import org.apache.maven.scm.command.update.UpdateScmResult;
058import org.apache.maven.scm.repository.ScmRepository;
059import org.apache.maven.scm.repository.ScmRepositoryException;
060import org.apache.maven.scm.repository.UnknownRepositoryStructure;
061import org.slf4j.Logger;
062import org.slf4j.LoggerFactory;
063
064/**
065 * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
066 * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
067 * @author Olivier Lamy
068 *
069 */
070public abstract class AbstractScmProvider implements ScmProvider {
071    protected final Logger logger = LoggerFactory.getLogger(getClass());
072
073    // ----------------------------------------------------------------------
074    //
075    // ----------------------------------------------------------------------
076
077    /**
078     * {@inheritDoc}
079     */
080    @Override
081    public String getScmSpecificFilename() {
082        return null;
083    }
084
085    /**
086     * {@inheritDoc}
087     */
088    @Override
089    public String sanitizeTagName(String tag) {
090        /* by default, we assume all tags are valid. */
091        return tag;
092    }
093
094    /**
095     * {@inheritDoc}
096     */
097    @Override
098    public boolean validateTagName(String tag) {
099        /* by default, we assume all tags are valid. */
100        return true;
101    }
102
103    /**
104     * {@inheritDoc}
105     */
106    @Override
107    public List<String> validateScmUrl(String scmSpecificUrl, char delimiter) {
108        List<String> messages = new ArrayList<String>();
109
110        try {
111            makeProviderScmRepository(scmSpecificUrl, delimiter);
112        } catch (ScmRepositoryException e) {
113            messages.add(e.getMessage());
114        }
115
116        return messages;
117    }
118
119    /**
120     * {@inheritDoc}
121     */
122    @Override
123    public boolean requiresEditMode() {
124        return false;
125    }
126
127    // ----------------------------------------------------------------------
128    // Scm Implementation
129    // ----------------------------------------------------------------------
130
131    /**
132     * {@inheritDoc}
133     */
134    @Override
135    public AddScmResult add(ScmRepository repository, ScmFileSet fileSet) throws ScmException {
136        return add(repository, fileSet, (String) null);
137    }
138
139    /**
140     * {@inheritDoc}
141     */
142    @Override
143    public AddScmResult add(ScmRepository repository, ScmFileSet fileSet, String message) throws ScmException {
144        login(repository, fileSet);
145
146        CommandParameters parameters = new CommandParameters();
147
148        parameters.setString(CommandParameter.MESSAGE, message == null ? "" : message);
149
150        // TODO: binary may be dependant on particular files though
151        // TODO: set boolean?
152        parameters.setString(CommandParameter.BINARY, "false");
153
154        return add(repository.getProviderRepository(), fileSet, parameters);
155    }
156
157    @Override
158    public AddScmResult add(ScmRepository repository, ScmFileSet fileSet, CommandParameters parameters)
159            throws ScmException {
160        login(repository, fileSet);
161
162        if (parameters.getString(CommandParameter.BINARY, null) == null) {
163            // TODO: binary may be dependant on particular files though
164            // TODO: set boolean?
165            parameters.setString(CommandParameter.BINARY, "false");
166        }
167
168        return add(repository.getProviderRepository(), fileSet, parameters);
169    }
170
171    /**
172     * TODO: why public? This should be protected, no?
173     */
174    public AddScmResult add(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
175            throws ScmException {
176        throw new NoSuchCommandScmException("add");
177    }
178
179    /**
180     * {@inheritDoc}
181     */
182    @Override
183    public BranchScmResult branch(ScmRepository repository, ScmFileSet fileSet, String branchName) throws ScmException {
184        return branch(repository, fileSet, branchName, new ScmBranchParameters());
185    }
186
187    /**
188     * {@inheritDoc}
189     */
190    @Override
191    public BranchScmResult branch(ScmRepository repository, ScmFileSet fileSet, String branchName, String message)
192            throws ScmException {
193        ScmBranchParameters scmBranchParameters = new ScmBranchParameters();
194
195        if (message != null && !message.isEmpty()) {
196            scmBranchParameters.setMessage(message);
197        }
198
199        return branch(repository, fileSet, branchName, scmBranchParameters);
200    }
201
202    @Override
203    public BranchScmResult branch(
204            ScmRepository repository, ScmFileSet fileSet, String branchName, ScmBranchParameters scmBranchParameters)
205            throws ScmException {
206        login(repository, fileSet);
207
208        CommandParameters parameters = new CommandParameters();
209
210        parameters.setString(CommandParameter.BRANCH_NAME, branchName);
211
212        parameters.setScmBranchParameters(CommandParameter.SCM_BRANCH_PARAMETERS, scmBranchParameters);
213
214        return branch(repository.getProviderRepository(), fileSet, parameters);
215    }
216
217    protected BranchScmResult branch(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
218            throws ScmException {
219        throw new NoSuchCommandScmException("branch");
220    }
221
222    /**
223     * {@inheritDoc}
224     *
225     * @deprecated
226     */
227    @Deprecated
228    @Override
229    public ChangeLogScmResult changeLog(
230            ScmRepository repository, ScmFileSet fileSet, Date startDate, Date endDate, int numDays, String branch)
231            throws ScmException {
232        return changeLog(repository, fileSet, startDate, endDate, numDays, branch, null);
233    }
234
235    /**
236     * {@inheritDoc}
237     *
238     * @deprecated
239     */
240    @Deprecated
241    @Override
242    public ChangeLogScmResult changeLog(
243            ScmRepository repository,
244            ScmFileSet fileSet,
245            Date startDate,
246            Date endDate,
247            int numDays,
248            String branch,
249            String datePattern)
250            throws ScmException {
251        ScmBranch scmBranch = null;
252
253        if (branch != null && !branch.isEmpty()) {
254            scmBranch = new ScmBranch(branch);
255        }
256        return changeLog(repository, fileSet, startDate, endDate, numDays, scmBranch, null);
257    }
258
259    /**
260     * {@inheritDoc}
261     */
262    @Override
263    public ChangeLogScmResult changeLog(
264            ScmRepository repository, ScmFileSet fileSet, Date startDate, Date endDate, int numDays, ScmBranch branch)
265            throws ScmException {
266        return changeLog(repository, fileSet, startDate, endDate, numDays, branch, null);
267    }
268
269    /**
270     * {@inheritDoc}
271     */
272    @Override
273    public ChangeLogScmResult changeLog(
274            ScmRepository repository,
275            ScmFileSet fileSet,
276            Date startDate,
277            Date endDate,
278            int numDays,
279            ScmBranch branch,
280            String datePattern)
281            throws ScmException {
282        final ChangeLogScmRequest request = new ChangeLogScmRequest(repository, fileSet);
283        request.setDateRange(startDate, endDate);
284        request.setNumDays(numDays);
285        request.setScmBranch(branch);
286        request.setDatePattern(datePattern);
287        return changeLog(request);
288    }
289
290    /**
291     * {@inheritDoc}
292     */
293    @Override
294    public ChangeLogScmResult changeLog(ChangeLogScmRequest request) throws ScmException {
295        final ScmRepository scmRepository = request.getScmRepository();
296        final ScmFileSet scmFileSet = request.getScmFileSet();
297        login(scmRepository, scmFileSet);
298        return changelog(scmRepository.getProviderRepository(), scmFileSet, request.getCommandParameters());
299    }
300
301    /**
302     * {@inheritDoc}
303     *
304     * @deprecated
305     */
306    @Deprecated
307    @Override
308    public ChangeLogScmResult changeLog(ScmRepository repository, ScmFileSet fileSet, String startTag, String endTag)
309            throws ScmException {
310        return changeLog(repository, fileSet, startTag, endTag, null);
311    }
312
313    /**
314     * {@inheritDoc}
315     *
316     * @deprecated
317     */
318    @Deprecated
319    @Override
320    public ChangeLogScmResult changeLog(
321            ScmRepository repository, ScmFileSet fileSet, String startTag, String endTag, String datePattern)
322            throws ScmException {
323        ScmVersion startRevision = null;
324        ScmVersion endRevision = null;
325
326        if (startTag != null && !startTag.isEmpty()) {
327            startRevision = new ScmRevision(startTag);
328        }
329
330        if (endTag != null && !endTag.isEmpty()) {
331            endRevision = new ScmRevision(endTag);
332        }
333
334        return changeLog(repository, fileSet, startRevision, endRevision, null);
335    }
336
337    /**
338     * {@inheritDoc}
339     */
340    @Override
341    public ChangeLogScmResult changeLog(
342            ScmRepository repository, ScmFileSet fileSet, ScmVersion startVersion, ScmVersion endVersion)
343            throws ScmException {
344        return changeLog(repository, fileSet, startVersion, endVersion, null);
345    }
346
347    /**
348     * {@inheritDoc}
349     */
350    @Override
351    public ChangeLogScmResult changeLog(
352            ScmRepository repository,
353            ScmFileSet fileSet,
354            ScmVersion startVersion,
355            ScmVersion endVersion,
356            String datePattern)
357            throws ScmException {
358        login(repository, fileSet);
359
360        CommandParameters parameters = new CommandParameters();
361
362        parameters.setScmVersion(CommandParameter.START_SCM_VERSION, startVersion);
363
364        parameters.setScmVersion(CommandParameter.END_SCM_VERSION, endVersion);
365
366        parameters.setString(CommandParameter.CHANGELOG_DATE_PATTERN, datePattern);
367
368        return changelog(repository.getProviderRepository(), fileSet, parameters);
369    }
370
371    protected ChangeLogScmResult changelog(
372            ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) throws ScmException {
373        throw new NoSuchCommandScmException("changelog");
374    }
375
376    /**
377     * {@inheritDoc}
378     *
379     * @deprecated
380     */
381    @Deprecated
382    @Override
383    public CheckInScmResult checkIn(ScmRepository repository, ScmFileSet fileSet, String tag, String message)
384            throws ScmException {
385        ScmVersion scmVersion = null;
386
387        if (tag != null && !tag.isEmpty()) {
388            scmVersion = new ScmBranch(tag);
389        }
390
391        return checkIn(repository, fileSet, scmVersion, message);
392    }
393
394    /**
395     * {@inheritDoc}
396     */
397    @Override
398    public CheckInScmResult checkIn(ScmRepository repository, ScmFileSet fileSet, String message) throws ScmException {
399        return checkIn(repository, fileSet, (ScmVersion) null, message);
400    }
401
402    /**
403     * {@inheritDoc}
404     */
405    @Override
406    public CheckInScmResult checkIn(ScmRepository repository, ScmFileSet fileSet, ScmVersion scmVersion, String message)
407            throws ScmException {
408        login(repository, fileSet);
409
410        CommandParameters parameters = new CommandParameters();
411
412        parameters.setScmVersion(CommandParameter.SCM_VERSION, scmVersion);
413
414        parameters.setString(CommandParameter.MESSAGE, message);
415
416        return checkin(repository.getProviderRepository(), fileSet, parameters);
417    }
418
419    protected CheckInScmResult checkin(
420            ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) throws ScmException {
421        throw new NoSuchCommandScmException("checkin");
422    }
423
424    /**
425     * {@inheritDoc}
426     *
427     * @deprecated
428     */
429    @Deprecated
430    @Override
431    public CheckOutScmResult checkOut(ScmRepository repository, ScmFileSet fileSet, String tag) throws ScmException {
432        return checkOut(repository, fileSet, tag, true);
433    }
434
435    /**
436     * {@inheritDoc}
437     *
438     * @deprecated
439     */
440    @Deprecated
441    @Override
442    public CheckOutScmResult checkOut(ScmRepository repository, ScmFileSet fileSet, String tag, boolean recursive)
443            throws ScmException {
444        ScmVersion scmVersion = null;
445
446        if (tag != null && !tag.isEmpty()) {
447            scmVersion = new ScmBranch(tag);
448        }
449
450        return checkOut(repository, fileSet, scmVersion, recursive);
451    }
452
453    /**
454     * {@inheritDoc}
455     */
456    @Override
457    public CheckOutScmResult checkOut(ScmRepository repository, ScmFileSet fileSet) throws ScmException {
458        return checkOut(repository, fileSet, (ScmVersion) null, true);
459    }
460
461    /**
462     * {@inheritDoc}
463     */
464    @Override
465    public CheckOutScmResult checkOut(ScmRepository repository, ScmFileSet fileSet, ScmVersion scmVersion)
466            throws ScmException {
467        return checkOut(repository, fileSet, scmVersion, true);
468    }
469
470    /**
471     * {@inheritDoc}
472     */
473    @Override
474    public CheckOutScmResult checkOut(ScmRepository repository, ScmFileSet fileSet, boolean recursive)
475            throws ScmException {
476        return checkOut(repository, fileSet, (ScmVersion) null, recursive);
477    }
478
479    /**
480     * {@inheritDoc}
481     */
482    @Override
483    public CheckOutScmResult checkOut(
484            ScmRepository repository, ScmFileSet fileSet, ScmVersion scmVersion, boolean recursive)
485            throws ScmException {
486        login(repository, fileSet);
487
488        CommandParameters parameters = new CommandParameters();
489
490        parameters.setScmVersion(CommandParameter.SCM_VERSION, scmVersion);
491
492        parameters.setString(CommandParameter.RECURSIVE, Boolean.toString(recursive));
493
494        return checkout(repository.getProviderRepository(), fileSet, parameters);
495    }
496
497    @Override
498    public CheckOutScmResult checkOut(
499            ScmRepository repository, ScmFileSet fileSet, ScmVersion scmVersion, CommandParameters commandParameters)
500            throws ScmException {
501        login(repository, fileSet);
502        if (scmVersion != null && commandParameters.getScmVersion(CommandParameter.SCM_VERSION, null) == null) {
503            commandParameters.setScmVersion(CommandParameter.SCM_VERSION, scmVersion);
504        }
505
506        return checkout(repository.getProviderRepository(), fileSet, commandParameters);
507    }
508
509    protected CheckOutScmResult checkout(
510            ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) throws ScmException {
511        throw new NoSuchCommandScmException("checkout");
512    }
513
514    /**
515     * {@inheritDoc}
516     *
517     * @deprecated
518     */
519    @Deprecated
520    @Override
521    public DiffScmResult diff(ScmRepository repository, ScmFileSet fileSet, String startRevision, String endRevision)
522            throws ScmException {
523        ScmVersion startVersion = null;
524        ScmVersion endVersion = null;
525
526        if (startRevision != null && !startRevision.isEmpty()) {
527            startVersion = new ScmRevision(startRevision);
528        }
529
530        if (endRevision != null && !endRevision.isEmpty()) {
531            endVersion = new ScmRevision(endRevision);
532        }
533
534        return diff(repository, fileSet, startVersion, endVersion);
535    }
536
537    /**
538     * {@inheritDoc}
539     */
540    @Override
541    public DiffScmResult diff(
542            ScmRepository repository, ScmFileSet fileSet, ScmVersion startVersion, ScmVersion endVersion)
543            throws ScmException {
544        login(repository, fileSet);
545
546        CommandParameters parameters = new CommandParameters();
547
548        parameters.setScmVersion(CommandParameter.START_SCM_VERSION, startVersion);
549
550        parameters.setScmVersion(CommandParameter.END_SCM_VERSION, endVersion);
551
552        return diff(repository.getProviderRepository(), fileSet, parameters);
553    }
554
555    protected DiffScmResult diff(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
556            throws ScmException {
557        throw new NoSuchCommandScmException("diff");
558    }
559
560    /**
561     * {@inheritDoc}
562     */
563    @Override
564    public EditScmResult edit(ScmRepository repository, ScmFileSet fileSet) throws ScmException {
565        login(repository, fileSet);
566
567        CommandParameters parameters = new CommandParameters();
568
569        return edit(repository.getProviderRepository(), fileSet, parameters);
570    }
571
572    protected EditScmResult edit(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
573            throws ScmException {
574        if (logger.isWarnEnabled()) {
575            logger.warn("Provider " + this.getScmType() + " does not support edit operation.");
576        }
577
578        return new EditScmResult("", null, null, true);
579    }
580
581    /**
582     * {@inheritDoc}
583     *
584     * @deprecated
585     */
586    @Deprecated
587    @Override
588    public ExportScmResult export(ScmRepository repository, ScmFileSet fileSet, String tag) throws ScmException {
589        return export(repository, fileSet, tag, null);
590    }
591
592    /**
593     * {@inheritDoc}
594     *
595     * @deprecated
596     */
597    @Deprecated
598    @Override
599    public ExportScmResult export(ScmRepository repository, ScmFileSet fileSet, String tag, String outputDirectory)
600            throws ScmException {
601        ScmVersion scmVersion = null;
602
603        if (tag != null && !tag.isEmpty()) {
604            scmVersion = new ScmRevision(tag);
605        }
606
607        return export(repository, fileSet, scmVersion, outputDirectory);
608    }
609
610    /**
611     * {@inheritDoc}
612     */
613    @Override
614    public ExportScmResult export(ScmRepository repository, ScmFileSet fileSet) throws ScmException {
615        return export(repository, fileSet, (ScmVersion) null, null);
616    }
617
618    /**
619     * {@inheritDoc}
620     */
621    @Override
622    public ExportScmResult export(ScmRepository repository, ScmFileSet fileSet, ScmVersion scmVersion)
623            throws ScmException {
624        return export(repository, fileSet, scmVersion, null);
625    }
626
627    /**
628     * {@inheritDoc}
629     */
630    @Override
631    public ExportScmResult export(
632            ScmRepository repository, ScmFileSet fileSet, ScmVersion scmVersion, String outputDirectory)
633            throws ScmException {
634        login(repository, fileSet);
635
636        CommandParameters parameters = new CommandParameters();
637
638        parameters.setScmVersion(CommandParameter.SCM_VERSION, scmVersion);
639
640        parameters.setString(CommandParameter.OUTPUT_DIRECTORY, outputDirectory);
641
642        return export(repository.getProviderRepository(), fileSet, parameters);
643    }
644
645    protected ExportScmResult export(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
646            throws ScmException {
647        throw new NoSuchCommandScmException("export");
648    }
649
650    /**
651     * {@inheritDoc}
652     */
653    @Override
654    public ListScmResult list(ScmRepository repository, ScmFileSet fileSet, boolean recursive, String tag)
655            throws ScmException {
656        ScmVersion scmVersion = null;
657
658        if (tag != null && !tag.isEmpty()) {
659            scmVersion = new ScmRevision(tag);
660        }
661
662        return list(repository, fileSet, recursive, scmVersion);
663    }
664
665    /**
666     * {@inheritDoc}
667     */
668    @Override
669    public ListScmResult list(ScmRepository repository, ScmFileSet fileSet, boolean recursive, ScmVersion scmVersion)
670            throws ScmException {
671        login(repository, fileSet);
672
673        CommandParameters parameters = new CommandParameters();
674
675        parameters.setString(CommandParameter.RECURSIVE, Boolean.toString(recursive));
676
677        if (scmVersion != null) {
678            parameters.setScmVersion(CommandParameter.SCM_VERSION, scmVersion);
679        }
680
681        return list(repository.getProviderRepository(), fileSet, parameters);
682    }
683
684    /**
685     * List each element (files and directories) of <B>fileSet</B> as they exist in the repository.
686     *
687     * @param repository the source control system
688     * @param fileSet    the files to list
689     * @param parameters TODO
690     * @return The list of files in the repository
691     * @throws NoSuchCommandScmException unless overriden by subclass
692     * @throws ScmException              if any
693     */
694    protected ListScmResult list(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
695            throws ScmException {
696        throw new NoSuchCommandScmException("list");
697    }
698
699    /**
700     * {@inheritDoc}
701     */
702    @Override
703    public MkdirScmResult mkdir(ScmRepository repository, ScmFileSet fileSet, String message, boolean createInLocal)
704            throws ScmException {
705        login(repository, fileSet);
706
707        CommandParameters parameters = new CommandParameters();
708
709        if (message == null) {
710            message = "";
711            if (!createInLocal) {
712                logger.warn("Commit message is empty!");
713            }
714        }
715
716        parameters.setString(CommandParameter.MESSAGE, message);
717
718        parameters.setString(CommandParameter.SCM_MKDIR_CREATE_IN_LOCAL, Boolean.toString(createInLocal));
719
720        return mkdir(repository.getProviderRepository(), fileSet, parameters);
721    }
722
723    /**
724     * Create directory/directories in the repository.
725     *
726     * @param repository TODO
727     * @param fileSet TODO
728     * @param parameters TODO
729     * @return TODO
730     * @throws ScmException if any
731     */
732    protected MkdirScmResult mkdir(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
733            throws ScmException {
734        throw new NoSuchCommandScmException("mkdir");
735    }
736
737    private void login(ScmRepository repository, ScmFileSet fileSet) throws ScmException {
738        LoginScmResult result = login(repository.getProviderRepository(), fileSet, new CommandParameters());
739
740        if (!result.isSuccess()) {
741            throw new ScmException("Can't login.\n" + result.getCommandOutput());
742        }
743    }
744
745    protected LoginScmResult login(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
746            throws ScmException {
747        return new LoginScmResult(null, null, null, true);
748    }
749
750    /**
751     * {@inheritDoc}
752     */
753    @Override
754    public RemoveScmResult remove(ScmRepository repository, ScmFileSet fileSet, String message) throws ScmException {
755        login(repository, fileSet);
756
757        CommandParameters parameters = new CommandParameters();
758
759        parameters.setString(CommandParameter.MESSAGE, message == null ? "" : message);
760
761        return remove(repository.getProviderRepository(), fileSet, parameters);
762    }
763
764    protected RemoveScmResult remove(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
765            throws ScmException {
766        throw new NoSuchCommandScmException("remove");
767    }
768
769    /**
770     * {@inheritDoc}
771     */
772    @Override
773    public StatusScmResult status(ScmRepository repository, ScmFileSet fileSet) throws ScmException {
774        login(repository, fileSet);
775
776        CommandParameters parameters = new CommandParameters();
777
778        return status(repository.getProviderRepository(), fileSet, parameters);
779    }
780
781    protected StatusScmResult status(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
782            throws ScmException {
783        throw new NoSuchCommandScmException("status");
784    }
785
786    /**
787     * {@inheritDoc}
788     */
789    @Override
790    public TagScmResult tag(ScmRepository repository, ScmFileSet fileSet, String tagName) throws ScmException {
791        return tag(repository, fileSet, tagName, new ScmTagParameters());
792    }
793
794    /**
795     * {@inheritDoc}
796     */
797    @Override
798    public TagScmResult tag(ScmRepository repository, ScmFileSet fileSet, String tagName, String message)
799            throws ScmException {
800        login(repository, fileSet);
801
802        CommandParameters parameters = new CommandParameters();
803
804        parameters.setString(CommandParameter.TAG_NAME, tagName);
805
806        if (message != null && !message.isEmpty()) {
807            parameters.setString(CommandParameter.MESSAGE, message);
808        }
809
810        ScmTagParameters scmTagParameters = new ScmTagParameters(message);
811
812        parameters.setScmTagParameters(CommandParameter.SCM_TAG_PARAMETERS, scmTagParameters);
813
814        return tag(repository.getProviderRepository(), fileSet, parameters);
815    }
816
817    /**
818     * {@inheritDoc}
819     */
820    @Override
821    public TagScmResult tag(
822            ScmRepository repository, ScmFileSet fileSet, String tagName, ScmTagParameters scmTagParameters)
823            throws ScmException {
824        login(repository, fileSet);
825
826        CommandParameters parameters = new CommandParameters();
827
828        parameters.setString(CommandParameter.TAG_NAME, tagName);
829
830        parameters.setScmTagParameters(CommandParameter.SCM_TAG_PARAMETERS, scmTagParameters);
831
832        return tag(repository.getProviderRepository(), fileSet, parameters);
833    }
834
835    protected TagScmResult tag(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
836            throws ScmException {
837        throw new NoSuchCommandScmException("tag");
838    }
839
840    /**
841     * {@inheritDoc}
842     */
843    @Override
844    public UnEditScmResult unedit(ScmRepository repository, ScmFileSet fileSet) throws ScmException {
845        login(repository, fileSet);
846
847        CommandParameters parameters = new CommandParameters();
848
849        return unedit(repository.getProviderRepository(), fileSet, parameters);
850    }
851
852    protected UnEditScmResult unedit(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
853            throws ScmException {
854        if (logger.isWarnEnabled()) {
855            logger.warn("Provider " + this.getScmType() + " does not support unedit operation.");
856        }
857
858        return new UnEditScmResult("", null, null, true);
859    }
860
861    /**
862     * {@inheritDoc}
863     */
864    @Override
865    public UntagScmResult untag(ScmRepository repository, ScmFileSet fileSet, CommandParameters parameters)
866            throws ScmException {
867        logger.warn("Provider " + this.getScmType() + " does not support untag operation.");
868        return new UntagScmResult("", null, null, true);
869    }
870
871    /**
872     * {@inheritDoc}
873     *
874     * @deprecated
875     */
876    @Deprecated
877    @Override
878    public UpdateScmResult update(ScmRepository repository, ScmFileSet fileSet, String tag) throws ScmException {
879        return update(repository, fileSet, tag, true);
880    }
881
882    /**
883     * {@inheritDoc}
884     *
885     * @deprecated
886     */
887    @Deprecated
888    @Override
889    public UpdateScmResult update(ScmRepository repository, ScmFileSet fileSet, String tag, boolean runChangelog)
890            throws ScmException {
891        return update(repository, fileSet, tag, "", runChangelog);
892    }
893
894    /**
895     * {@inheritDoc}
896     */
897    @Override
898    public UpdateScmResult update(ScmRepository repository, ScmFileSet fileSet) throws ScmException {
899        return update(repository, fileSet, (ScmVersion) null, true);
900    }
901
902    /**
903     * {@inheritDoc}
904     */
905    @Override
906    public UpdateScmResult update(ScmRepository repository, ScmFileSet fileSet, ScmVersion scmVersion)
907            throws ScmException {
908        return update(repository, fileSet, scmVersion, true);
909    }
910
911    /**
912     * {@inheritDoc}
913     */
914    @Override
915    public UpdateScmResult update(ScmRepository repository, ScmFileSet fileSet, boolean runChangelog)
916            throws ScmException {
917        return update(repository, fileSet, (ScmVersion) null, "", runChangelog);
918    }
919
920    /**
921     * {@inheritDoc}
922     */
923    @Override
924    public UpdateScmResult update(
925            ScmRepository repository, ScmFileSet fileSet, ScmVersion scmVersion, boolean runChangelog)
926            throws ScmException {
927        return update(repository, fileSet, scmVersion, "", runChangelog);
928    }
929
930    /**
931     * {@inheritDoc}
932     *
933     * @deprecated
934     */
935    @Override
936    public UpdateScmResult update(ScmRepository repository, ScmFileSet fileSet, String tag, String datePattern)
937            throws ScmException {
938        return update(repository, fileSet, tag, datePattern, true);
939    }
940
941    /**
942     * {@inheritDoc}
943     */
944    @Override
945    public UpdateScmResult update(
946            ScmRepository repository, ScmFileSet fileSet, ScmVersion scmVersion, String datePattern)
947            throws ScmException {
948        return update(repository, fileSet, scmVersion, datePattern, true);
949    }
950
951    /**
952     * @deprecated
953     */
954    private UpdateScmResult update(
955            ScmRepository repository, ScmFileSet fileSet, String tag, String datePattern, boolean runChangelog)
956            throws ScmException {
957        ScmBranch scmBranch = null;
958
959        if (tag != null && !tag.isEmpty()) {
960            scmBranch = new ScmBranch(tag);
961        }
962
963        return update(repository, fileSet, scmBranch, datePattern, runChangelog);
964    }
965
966    private UpdateScmResult update(
967            ScmRepository repository,
968            ScmFileSet fileSet,
969            ScmVersion scmVersion,
970            String datePattern,
971            boolean runChangelog)
972            throws ScmException {
973        login(repository, fileSet);
974
975        CommandParameters parameters = new CommandParameters();
976
977        parameters.setScmVersion(CommandParameter.SCM_VERSION, scmVersion);
978
979        parameters.setString(CommandParameter.CHANGELOG_DATE_PATTERN, datePattern);
980
981        parameters.setString(CommandParameter.RUN_CHANGELOG_WITH_UPDATE, String.valueOf(runChangelog));
982
983        return update(repository.getProviderRepository(), fileSet, parameters);
984    }
985
986    /**
987     * {@inheritDoc}
988     *
989     * @deprecated
990     */
991    @Deprecated
992    @Override
993    public UpdateScmResult update(ScmRepository repository, ScmFileSet fileSet, String tag, Date lastUpdate)
994            throws ScmException {
995        return update(repository, fileSet, tag, lastUpdate, null);
996    }
997
998    /**
999     * {@inheritDoc}
1000     */
1001    @Override
1002    public UpdateScmResult update(ScmRepository repository, ScmFileSet fileSet, ScmVersion scmVersion, Date lastUpdate)
1003            throws ScmException {
1004        return update(repository, fileSet, scmVersion, lastUpdate, null);
1005    }
1006
1007    /**
1008     * {@inheritDoc}
1009     *
1010     * @deprecated
1011     */
1012    @Deprecated
1013    @Override
1014    public UpdateScmResult update(
1015            ScmRepository repository, ScmFileSet fileSet, String tag, Date lastUpdate, String datePattern)
1016            throws ScmException {
1017        ScmBranch scmBranch = null;
1018
1019        if (tag != null && !tag.isEmpty()) {
1020            scmBranch = new ScmBranch(tag);
1021        }
1022
1023        return update(repository, fileSet, scmBranch, lastUpdate, datePattern);
1024    }
1025
1026    /**
1027     * {@inheritDoc}
1028     */
1029    @Override
1030    public UpdateScmResult update(
1031            ScmRepository repository, ScmFileSet fileSet, ScmVersion scmVersion, Date lastUpdate, String datePattern)
1032            throws ScmException {
1033        login(repository, fileSet);
1034
1035        CommandParameters parameters = new CommandParameters();
1036
1037        parameters.setScmVersion(CommandParameter.SCM_VERSION, scmVersion);
1038
1039        if (lastUpdate != null) {
1040            parameters.setDate(CommandParameter.START_DATE, lastUpdate);
1041        }
1042
1043        parameters.setString(CommandParameter.CHANGELOG_DATE_PATTERN, datePattern);
1044
1045        parameters.setString(CommandParameter.RUN_CHANGELOG_WITH_UPDATE, "true");
1046
1047        return update(repository.getProviderRepository(), fileSet, parameters);
1048    }
1049
1050    protected UpdateScmResult update(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
1051            throws ScmException {
1052        throw new NoSuchCommandScmException("update");
1053    }
1054
1055    /**
1056     * {@inheritDoc}
1057     */
1058    @Override
1059    public BlameScmResult blame(ScmRepository repository, ScmFileSet fileSet, String filename) throws ScmException {
1060        login(repository, fileSet);
1061
1062        CommandParameters parameters = new CommandParameters();
1063
1064        parameters.setString(CommandParameter.FILE, filename);
1065
1066        return blame(repository.getProviderRepository(), fileSet, parameters);
1067    }
1068
1069    protected BlameScmResult blame(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
1070            throws ScmException {
1071        throw new NoSuchCommandScmException("blame");
1072    }
1073
1074    @Override
1075    public BlameScmResult blame(BlameScmRequest blameScmRequest) throws ScmException {
1076        return blame(
1077                blameScmRequest.getScmRepository().getProviderRepository(),
1078                blameScmRequest.getScmFileSet(),
1079                blameScmRequest.getCommandParameters());
1080    }
1081
1082    @Override
1083    public InfoScmResult info(ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters)
1084            throws ScmException {
1085        return null;
1086    }
1087
1088    @Override
1089    public RemoteInfoScmResult remoteInfo(
1090            ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters) throws ScmException {
1091        return null;
1092    }
1093
1094    /**
1095     * {@inheritDoc}
1096     */
1097    @Override
1098    public ScmProviderRepository makeProviderScmRepository(File path)
1099            throws ScmRepositoryException, UnknownRepositoryStructure {
1100        throw new UnknownRepositoryStructure();
1101    }
1102}