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