Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
JazzAddCommand |
|
| 5.25;5,25 |
1 | package org.apache.maven.scm.provider.jazz.command.add; | |
2 | ||
3 | /* | |
4 | * Licensed to the Apache Software Foundation (ASF) under one | |
5 | * or more contributor license agreements. See the NOTICE file | |
6 | * distributed with this work for additional information | |
7 | * regarding copyright ownership. The ASF licenses this file | |
8 | * to you under the Apache License, Version 2.0 (the | |
9 | * "License"); you may not use this file except in compliance | |
10 | * with the License. You may obtain a copy of the License at | |
11 | * | |
12 | * http://www.apache.org/licenses/LICENSE-2.0 | |
13 | * | |
14 | * Unless required by applicable law or agreed to in writing, | |
15 | * software distributed under the License is distributed on an | |
16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
17 | * KIND, either express or implied. See the License for the | |
18 | * specific language governing permissions and limitations | |
19 | * under the License. | |
20 | */ | |
21 | ||
22 | import org.apache.maven.scm.ScmException; | |
23 | import org.apache.maven.scm.ScmFile; | |
24 | import org.apache.maven.scm.ScmFileSet; | |
25 | import org.apache.maven.scm.ScmFileStatus; | |
26 | import org.apache.maven.scm.ScmResult; | |
27 | import org.apache.maven.scm.command.add.AbstractAddCommand; | |
28 | import org.apache.maven.scm.command.add.AddScmResult; | |
29 | import org.apache.maven.scm.command.status.StatusScmResult; | |
30 | import org.apache.maven.scm.provider.ScmProviderRepository; | |
31 | import org.apache.maven.scm.provider.jazz.command.JazzConstants; | |
32 | import org.apache.maven.scm.provider.jazz.command.JazzScmCommand; | |
33 | import org.apache.maven.scm.provider.jazz.command.consumer.ErrorConsumer; | |
34 | import org.apache.maven.scm.provider.jazz.command.status.JazzStatusCommand; | |
35 | ||
36 | import java.io.File; | |
37 | import java.util.ArrayList; | |
38 | import java.util.Iterator; | |
39 | import java.util.List; | |
40 | ||
41 | // RTC does not have the equivalent of the "add" goal. The closest we have is the "share" command, however | |
42 | // that only shares directories (not individual or specific files), and it is recursive (which can not be | |
43 | // switched off!). | |
44 | // | |
45 | // The Maven SCM plugin "add" goal's job is to add files to source control, but not commit them. | |
46 | // The SVN equivalent of this is "svn add", which places a file under source control (Working Copy in svn terms) | |
47 | // but does not commit them (svn commit). | |
48 | // So, this provider will use the RTC "checkin" command for the implementation of the "add" goal. | |
49 | // This will checkin the code into a remote repository workspace. It will not deliver. | |
50 | // | |
51 | // Additionally, "svn add" does not take a message, whereas commit does. Under RTC, the only way we can preserve | |
52 | // the message, is to create a changeset. So we do that in the "checkin" goal, not the "add" goal. | |
53 | // | |
54 | // The Maven SCM plugin "add" goal is roughly equivalent to the RTC "checkin" command. | |
55 | // | |
56 | // See the following links for additional information on the RTC "checkin" command. | |
57 | // RTC 2.0.0.2: | |
58 | // http://publib.boulder.ibm.com/infocenter/rtc/v2r0m0/topic/com.ibm.team.scm.doc/topics/r_scm_cli_checkin.html | |
59 | // RTC 3.0: | |
60 | // http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0/topic/com.ibm.team.scm.doc/topics/r_scm_cli_checkin.html | |
61 | // RTC 3.0.1: | |
62 | // http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0m1/topic/com.ibm.team.scm.doc/topics/r_scm_cli_checkin.html | |
63 | // | |
64 | // Currently this implementation does not use the comment message. | |
65 | // Perhaps in the future this method can be used to deliver a change-set with the given comment message. | |
66 | // However some users may want the checkin goal to only check in to the desired repository workspace. | |
67 | // While some users may want the checkin goal to both check in to the desired repository workspace and deliver it to a | |
68 | // stream. | |
69 | // Currently this implementation only checks in the unresolved changes to the repository workspace. | |
70 | // | |
71 | // See the following links for additional information on the RTC "deliver" command. | |
72 | // RTC 2.0.0.2: | |
73 | // http://publib.boulder.ibm.com/infocenter/rtc/v2r0m0/topic/com.ibm.team.scm.doc/topics/r_scm_cli_deliver.html | |
74 | // RTC 3.0: | |
75 | // http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0/topic/com.ibm.team.scm.doc/topics/r_scm_cli_deliver.html | |
76 | // RTC 3.0.1: | |
77 | // http://publib.boulder.ibm.com/infocenter/clmhelp/v3r0m1/topic/com.ibm.team.scm.doc/topics/r_scm_cli_deliver.html | |
78 | // | |
79 | ||
80 | /** | |
81 | * @author <a href="mailto:ChrisGWarp@gmail.com">Chris Graham</a> | |
82 | */ | |
83 | 1 | public class JazzAddCommand |
84 | extends AbstractAddCommand | |
85 | { | |
86 | /** | |
87 | * {@inheritDoc} | |
88 | */ | |
89 | protected ScmResult executeAddCommand( ScmProviderRepository repo, ScmFileSet fileSet, String message, | |
90 | boolean binary ) | |
91 | throws ScmException | |
92 | { | |
93 | 0 | if ( getLogger().isDebugEnabled() ) |
94 | { | |
95 | 0 | getLogger().debug( "Executing add command..." ); |
96 | } | |
97 | ||
98 | // The message can only be used when we create a change set, which is only done on the checkin command. | |
99 | // So that can be ignored. | |
100 | // The binary flag, is not needed for RTC. | |
101 | 0 | return executeAddCommand( repo, fileSet ); |
102 | } | |
103 | ||
104 | public AddScmResult executeAddCommand( ScmProviderRepository repo, ScmFileSet fileSet ) | |
105 | throws ScmException | |
106 | { | |
107 | // NOTE: THIS IS ALSO CALLED DIRECTLY FROM THE CHECKIN COMMAND. | |
108 | // | |
109 | // The "checkin" command does not produce consumable output as to which individual files were checked in. (in | |
110 | // 2.0.0.2 at least). Since only "locally modified" changes get checked in, we call a "status" command to | |
111 | // generate a list of these files. | |
112 | 0 | File baseDir = fileSet.getBasedir(); |
113 | 0 | File parentFolder = ( baseDir.getParentFile() != null ) ? baseDir.getParentFile() : baseDir; |
114 | ||
115 | 0 | List<ScmFile> changedScmFiles = new ArrayList<ScmFile>(); |
116 | 0 | List<File> changedFiles = new ArrayList<File>(); |
117 | 0 | List<ScmFile> commitedFiles = new ArrayList<ScmFile>(); |
118 | ||
119 | 0 | JazzStatusCommand statusCmd = new JazzStatusCommand(); |
120 | 0 | statusCmd.setLogger( getLogger() ); |
121 | 0 | StatusScmResult statusCmdResult = statusCmd.executeStatusCommand( repo, fileSet ); |
122 | 0 | List<ScmFile> statusScmFiles = statusCmdResult.getChangedFiles(); |
123 | ||
124 | 0 | for ( Iterator<ScmFile> it = statusScmFiles.iterator(); it.hasNext(); ) |
125 | { | |
126 | 0 | ScmFile file = (ScmFile) it.next(); |
127 | 0 | getLogger().debug( "Iterating over statusScmFiles: " + file ); |
128 | 0 | if ( file.getStatus() == ScmFileStatus.ADDED || |
129 | file.getStatus() == ScmFileStatus.DELETED || | |
130 | file.getStatus() == ScmFileStatus.MODIFIED ) | |
131 | { | |
132 | 0 | changedScmFiles.add( new ScmFile( file.getPath(), ScmFileStatus.CHECKED_IN ) ); |
133 | 0 | changedFiles.add( new File( parentFolder, file.getPath() ) ); |
134 | } | |
135 | 0 | } |
136 | ||
137 | 0 | List<File> files = fileSet.getFileList(); |
138 | 0 | if ( files.size() == 0 ) |
139 | { | |
140 | // Either commit all local changes | |
141 | 0 | commitedFiles = changedScmFiles; |
142 | } | |
143 | else | |
144 | { | |
145 | // Or commit specific files | |
146 | 0 | for ( int i = 0; i < files.size(); i++ ) |
147 | { | |
148 | 0 | if ( fileExistsInFileList( (File) ( files.get( i ) ), changedFiles ) ) |
149 | { | |
150 | 0 | commitedFiles.add( new ScmFile( ( (File) files.get( i ) ).getPath(), ScmFileStatus.CHECKED_IN ) ); |
151 | } | |
152 | } | |
153 | } | |
154 | ||
155 | // Now that we have a list of files to process, we can "add" (scm checkin) them. | |
156 | 0 | JazzAddConsumer addConsumer = new JazzAddConsumer( repo, getLogger() ); |
157 | 0 | ErrorConsumer errConsumer = new ErrorConsumer( getLogger() ); |
158 | 0 | JazzScmCommand command = createAddCommand( repo, fileSet ); |
159 | ||
160 | 0 | int status = command.execute( addConsumer, errConsumer ); |
161 | 0 | if ( status != 0 || errConsumer.hasBeenFed() ) |
162 | { | |
163 | 0 | return new AddScmResult( command.getCommandString(), |
164 | "Error code for Jazz SCM add (checkin) command - " + status, | |
165 | errConsumer.getOutput(), false ); | |
166 | } | |
167 | ||
168 | 0 | return new AddScmResult( command.getCommandString(), addConsumer.getFiles() ); |
169 | } | |
170 | ||
171 | public JazzScmCommand createAddCommand( ScmProviderRepository repo, ScmFileSet fileSet ) | |
172 | { | |
173 | 1 | JazzScmCommand command = |
174 | new JazzScmCommand( JazzConstants.CMD_CHECKIN, null, repo, false, fileSet, getLogger() ); | |
175 | ||
176 | 1 | List<File> files = fileSet.getFileList(); |
177 | 1 | if ( files != null && !files.isEmpty() ) |
178 | { | |
179 | 1 | Iterator<File> it = files.iterator(); |
180 | 3 | while ( it.hasNext() ) |
181 | { | |
182 | 2 | File file = (File) it.next(); |
183 | 2 | command.addArgument( file.getPath() ); // Check in only the files specified |
184 | 2 | } |
185 | 1 | } |
186 | else | |
187 | { | |
188 | 0 | command.addArgument( "." ); // This will check in all local changes |
189 | } | |
190 | ||
191 | 1 | return command; |
192 | } | |
193 | ||
194 | private boolean fileExistsInFileList( File file, List<File> fileList ) | |
195 | { | |
196 | 0 | boolean exists = false; |
197 | 0 | for ( Iterator<File> it = fileList.iterator(); it.hasNext(); ) |
198 | { | |
199 | 0 | File changedFile = (File) it.next(); |
200 | 0 | if ( changedFile.compareTo( file ) == 0 ) |
201 | { | |
202 | 0 | exists = true; |
203 | 0 | break; |
204 | } | |
205 | 0 | } |
206 | 0 | return exists; |
207 | } | |
208 | ||
209 | } |