1 package org.apache.maven.scm.provider.integrity;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import com.mks.api.Command;
23 import com.mks.api.MultiValue;
24 import com.mks.api.Option;
25 import com.mks.api.response.APIException;
26 import com.mks.api.response.Field;
27 import com.mks.api.response.Response;
28 import com.mks.api.response.WorkItem;
29 import com.mks.api.response.WorkItemIterator;
30 import com.mks.api.si.SIModelTypeName;
31
32 import java.util.ArrayList;
33 import java.util.Calendar;
34 import java.util.Collections;
35 import java.util.Comparator;
36 import java.util.Date;
37 import java.util.Hashtable;
38 import java.util.List;
39 import java.util.NoSuchElementException;
40
41
42
43
44
45
46
47
48 public class Project
49 {
50 public static final String NORMAL_PROJECT = "Normal";
51
52 public static final String VARIANT_PROJECT = "Variant";
53
54 public static final String BUILD_PROJECT = "Build";
55
56 private String projectName;
57
58 private String projectType;
59
60 private String projectRevision;
61
62 private String fullConfigSyntax;
63
64 private Date lastCheckpoint;
65
66 private APISession api;
67
68
69 public static final Comparator<Member> FILES_ORDER = new Comparator<Member>()
70 {
71 public int compare( Member cmm1, Member cmm2 )
72 {
73 return cmm1.getMemberName().compareToIgnoreCase( cmm2.getMemberName() );
74 }
75 };
76
77
78
79
80
81
82
83
84 public static void validateTag( String tagName )
85 throws Exception
86 {
87 if ( tagName == null || tagName.length() == 0 )
88 {
89 throw new Exception( "The checkpoint label string is empty!" );
90 }
91
92 char ch = tagName.charAt( 0 );
93 if ( !( ( 'A' <= ch && ch <= 'Z' ) || ( 'a' <= ch && ch <= 'z' ) ) )
94 {
95 throw new Exception( "The checkpoint label must start with an alpha character!" );
96 }
97
98 for ( char invalid : "$,.:;/\\@".toCharArray() )
99 {
100 if ( tagName.indexOf( invalid ) >= 0 )
101 {
102 throw new Exception(
103 "The checkpoint label may cannot contain one of the following characters: $ , . : ; / \\ @" );
104 }
105 }
106 }
107
108
109
110
111
112
113
114
115 public Project( APISession api, String configPath )
116 throws APIException
117 {
118
119 this.api = api;
120 try
121 {
122
123 Command siProjectInfoCmd = new Command( Command.SI, "projectinfo" );
124 siProjectInfoCmd.addOption( new Option( "project", configPath ) );
125 api.getLogger().info( "Preparing to execute si projectinfo for " + configPath );
126 Response infoRes = api.runCommand( siProjectInfoCmd );
127
128 WorkItem wi = infoRes.getWorkItems().next();
129
130 Field pjNameFld = wi.getField( "projectName" );
131 Field pjTypeFld = wi.getField( "projectType" );
132 Field pjCfgPathFld = wi.getField( "fullConfigSyntax" );
133 Field pjChkptFld = wi.getField( "lastCheckpoint" );
134
135
136
137 if ( null != pjNameFld && null != pjNameFld.getValueAsString() )
138 {
139 projectName = pjNameFld.getValueAsString();
140 }
141 else
142 {
143 api.getLogger().warn( "Project info did not provide a value for the 'projectName' field!" );
144 projectName = "";
145 }
146
147 if ( null != pjTypeFld && null != pjTypeFld.getValueAsString() )
148 {
149 projectType = pjTypeFld.getValueAsString();
150 if ( isBuild() )
151 {
152
153 Field pjRevFld = wi.getField( "revision" );
154 if ( null != pjRevFld && null != pjRevFld.getItem() )
155 {
156 projectRevision = pjRevFld.getItem().getId();
157 }
158 else
159 {
160 projectRevision = "";
161 api.getLogger().warn( "Project info did not provide a vale for the 'revision' field!" );
162 }
163 }
164 }
165 else
166 {
167 api.getLogger().warn( "Project info did not provide a value for the 'projectType' field!" );
168 projectType = "";
169 }
170
171 if ( null != pjCfgPathFld && null != pjCfgPathFld.getValueAsString() )
172 {
173 fullConfigSyntax = pjCfgPathFld.getValueAsString();
174 }
175 else
176 {
177 api.getLogger().error( "Project info did not provide a value for the 'fullConfigSyntax' field!" );
178 fullConfigSyntax = "";
179 }
180
181 if ( null != pjChkptFld && null != pjChkptFld.getDateTime() )
182 {
183 lastCheckpoint = pjChkptFld.getDateTime();
184 }
185 else
186 {
187 api.getLogger().warn( "Project info did not provide a value for the 'lastCheckpoint' field!" );
188 lastCheckpoint = Calendar.getInstance().getTime();
189 }
190 }
191 catch ( NoSuchElementException nsee )
192 {
193 api.getLogger().error( "Project info did not provide a value for field " + nsee.getMessage() );
194 }
195 }
196
197
198
199
200
201
202 public String getProjectName()
203 {
204 return projectName;
205 }
206
207
208
209
210
211
212 public String getProjectRevision()
213 {
214 return projectRevision;
215 }
216
217
218
219
220
221
222 public boolean isNormal()
223 {
224 return projectType.equalsIgnoreCase( NORMAL_PROJECT );
225 }
226
227
228
229
230
231
232 public boolean isVariant()
233 {
234 return projectType.equalsIgnoreCase( VARIANT_PROJECT );
235 }
236
237
238
239
240
241
242 public boolean isBuild()
243 {
244 return projectType.equalsIgnoreCase( BUILD_PROJECT );
245 }
246
247
248
249
250
251
252 public String getConfigurationPath()
253 {
254 return fullConfigSyntax;
255 }
256
257
258
259
260
261
262 public Date getLastCheckpointDate()
263 {
264 return lastCheckpoint;
265 }
266
267
268
269
270
271
272
273
274 public List<Member> listFiles( String workspaceDir )
275 throws APIException
276 {
277
278 List<Member> memberList = new ArrayList<Member>();
279
280 Hashtable<String, String> pjConfigHash = new Hashtable<String, String>();
281
282 pjConfigHash.put( projectName, fullConfigSyntax );
283
284 String projectRoot = projectName.substring( 0, projectName.lastIndexOf( '/' ) );
285
286
287 Command siViewProjectCmd = new Command( Command.SI, "viewproject" );
288 siViewProjectCmd.addOption( new Option( "recurse" ) );
289 siViewProjectCmd.addOption( new Option( "project", fullConfigSyntax ) );
290 MultiValue mvFields = new MultiValue( "," );
291 mvFields.add( "name" );
292 mvFields.add( "context" );
293 mvFields.add( "memberrev" );
294 mvFields.add( "membertimestamp" );
295 mvFields.add( "memberdescription" );
296 siViewProjectCmd.addOption( new Option( "fields", mvFields ) );
297 api.getLogger().info( "Preparing to execute si viewproject for " + fullConfigSyntax );
298 Response viewRes = api.runCommand( siViewProjectCmd );
299
300
301 WorkItemIterator wit = viewRes.getWorkItems();
302 while ( wit.hasNext() )
303 {
304 WorkItem wi = wit.next();
305 if ( wi.getModelType().equals( SIModelTypeName.SI_SUBPROJECT ) )
306 {
307
308 pjConfigHash.put( wi.getField( "name" ).getValueAsString(), wi.getId() );
309 }
310 else if ( wi.getModelType().equals( SIModelTypeName.MEMBER ) )
311 {
312
313 String parentProject = wi.getField( "parent" ).getValueAsString();
314
315 Member iCMMember = new Member( wi, pjConfigHash.get( parentProject ), projectRoot, workspaceDir );
316
317 memberList.add( iCMMember );
318 }
319 else
320 {
321 api.getLogger().warn( "View project output contains an invalid model type: " + wi.getModelType() );
322 }
323 }
324
325
326 Collections.sort( memberList, FILES_ORDER );
327 return memberList;
328 }
329
330
331
332
333
334
335
336
337
338 public Response checkpoint( String message, String tag )
339 throws APIException
340 {
341
342 api.getLogger().debug( "Checkpointing project " + fullConfigSyntax + " with label '" + tag + "'" );
343
344 Command siCheckpoint = new Command( Command.SI, "checkpoint" );
345 siCheckpoint.addOption( new Option( "recurse" ) );
346
347 siCheckpoint.addOption( new Option( "project", fullConfigSyntax ) );
348
349 siCheckpoint.addOption( new Option( "label", tag ) );
350
351 if ( null != message && message.length() > 0 )
352 {
353 siCheckpoint.addOption( new Option( "description", message ) );
354 }
355
356 return api.runCommand( siCheckpoint );
357 }
358
359
360
361
362
363
364
365
366 public Response createDevPath( String devPath )
367 throws APIException
368 {
369
370 String chkpt = projectRevision;
371 if ( !isBuild() )
372 {
373 Response chkptRes = checkpoint( "Pre-checkpoint for development path " + devPath, devPath + " Baseline" );
374 WorkItem wi = chkptRes.getWorkItem( fullConfigSyntax );
375 chkpt = wi.getResult().getField( "resultant" ).getItem().getId();
376 }
377
378
379 api.getLogger().debug(
380 "Creating development path '" + devPath + "' for project " + projectName + " at revision '" + chkpt + "'" );
381 Command siCreateDevPath = new Command( Command.SI, "createdevpath" );
382 siCreateDevPath.addOption( new Option( "devpath", devPath ) );
383
384 siCreateDevPath.addOption( new Option( "project", projectName ) );
385
386 siCreateDevPath.addOption( new Option( "projectRevision", chkpt ) );
387
388 return api.runCommand( siCreateDevPath );
389 }
390 }
391