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