View Javadoc

1   package org.apache.continuum.buildagent.utils;
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.continuum.buildagent.buildcontext.BuildContext;
23  import org.apache.continuum.utils.build.BuildTrigger;
24  import org.apache.maven.continuum.ContinuumException;
25  import org.apache.maven.continuum.model.project.BuildDefinition;
26  import org.apache.maven.continuum.model.project.BuildResult;
27  import org.apache.maven.continuum.model.project.Project;
28  import org.apache.maven.continuum.model.scm.ChangeFile;
29  import org.apache.maven.continuum.model.scm.ChangeSet;
30  import org.apache.maven.continuum.model.scm.ScmResult;
31  import org.codehaus.plexus.util.StringUtils;
32  
33  import java.io.File;
34  import java.io.PrintWriter;
35  import java.io.StringWriter;
36  import java.util.ArrayList;
37  import java.util.Arrays;
38  import java.util.Date;
39  import java.util.HashMap;
40  import java.util.List;
41  import java.util.Map;
42  
43  public class ContinuumBuildAgentUtil
44  {
45      public static final String EOL = System.getProperty( "line.separator" );
46  
47      public static final String KEY_PROJECT_ID = "project-id";
48  
49      public static final String KEY_PROJECT_VERSION = "project-version";
50  
51      public static final String KEY_BUILD_NUMBER = "build-number";
52  
53      public static final String KEY_BUILD_DEFINITION_ID = "builddefinition-id";
54  
55      public static final String KEY_BUILD_DEFINITION_LABEL = "builddefinition-label";
56  
57      public static final String KEY_TRIGGER = "trigger";
58  
59      public static final String KEY_USERNAME = "username";
60  
61      public static final String KEY_EXECUTOR_ID = "executor-id";
62  
63      public static final String KEY_SCM_URL = "scm-url";
64  
65      public static final String KEY_SCM_USERNAME = "scm-username";
66  
67      public static final String KEY_SCM_PASSWORD = "scm-password";
68  
69      public static final String KEY_BUILD_FILE = "build-file";
70  
71      public static final String KEY_GOALS = "goals";
72  
73      public static final String KEY_ARGUMENTS = "arguments";
74  
75      public static final String KEY_BUILD_FRESH = "build-fresh";
76  
77      public static final String KEY_START_TIME = "start-time";
78  
79      public static final String KEY_END_TIME = "end-time";
80  
81      public static final String KEY_BUILD_ERROR = "build-error";
82  
83      public static final String KEY_BUILD_EXIT_CODE = "build-exit-code";
84  
85      public static final String KEY_BUILD_STATE = "build-state";
86  
87      public static final String KEY_SCM_STATE = "scm-state";
88  
89      public static final String KEY_SCM_COMMAND_OUTPUT = "scm-command-output";
90  
91      public static final String KEY_SCM_COMMAND_LINE = "scm-command-line";
92  
93      public static final String KEY_SCM_PROVIDER_MESSAGE = "scm-provider-message";
94  
95      public static final String KEY_SCM_EXCEPTION = "scm-exception";
96  
97      public static final String KEY_PROJECT_GROUP_ID = "project-group-id";
98  
99      public static final String KEY_PROJECT_GROUP_NAME = "project-group-name";
100 
101     public static final String KEY_SCM_ROOT_ADDRESS = "scm-root-address";
102 
103     public static final String KEY_SCM_ROOT_ID = "scm-root-id";
104 
105     public static final String KEY_SCM_ROOT_STATE = "scm-root-state";
106 
107     public static final String KEY_CHECKOUT_SCM_RESULT = "checkout-scm-result";
108 
109     public static final String KEY_UPDATE_SCM_RESULT = "update-scm-result";
110 
111     public static final String KEY_WORKING_DIRECTORY_EXISTS = "working-directory-exists";
112 
113     public static final String KEY_PROJECT = "project";
114 
115     public static final String KEY_BUILD_DEFINITION = "build-definition";
116 
117     public static final String KEY_SCM_RESULT = "scm-result";
118 
119     public static final String KEY_WORKING_DIRECTORY = "working-directory";
120 
121     public static final String KEY_SCM_SUCCESS = "scm-success";
122 
123     public static final String KEY_SCM_ERROR = "scm-error";
124 
125     public static final String KEY_BUILD_RESULT = "build-result";
126 
127     public static final String KEY_PROJECT_NAME = "project-name";
128 
129     public static final String KEY_BUILD_OUTPUT = "build-output";
130 
131     public static final String KEY_PROJECT_STATE = "project-state";
132 
133     public static final String KEY_INSTALLATION_NAME = "installation-name";
134 
135     public static final String KEY_INSTALLATION_TYPE = "installation-type";
136 
137     public static final String KEY_INSTALLATION_VAR_NAME = "installation-var-name";
138 
139     public static final String KEY_INSTALLATION_VAR_VALUE = "installation-var-value";
140 
141     public static final String KEY_ENVIRONMENTS = "environments";
142 
143     public static final String KEY_LOCAL_REPOSITORY = "local-repository";
144 
145     public static final String KEY_SCM_CHANGES = "scm-changes";
146 
147     public static final String KEY_CHANGESET_AUTHOR = "changeset-author";
148 
149     public static final String KEY_CHANGESET_COMMENT = "changeset-comment";
150 
151     public static final String KEY_CHANGESET_DATE = "changeset-date";
152 
153     public static final String KEY_CHANGESET_FILES = "changeset-files";
154 
155     public static final String KEY_CHANGEFILE_NAME = "changefile-name";
156 
157     public static final String KEY_CHANGEFILE_REVISION = "changefile-revision";
158 
159     public static final String KEY_CHANGEFILE_STATUS = "changefile-status";
160 
161     public static final String KEY_OLD_SCM_RESULT = "old-scm-result";
162 
163     public static final String KEY_OLD_SCM_CHANGES = "old-scm-changes";
164 
165     public static final String KEY_PROJECT_DESCRIPTION = "project-description";
166 
167     public static final String KEY_GROUP_ID = "group-id";
168 
169     public static final String KEY_ARTIFACT_ID = "artifact-id";
170 
171     public static final String KEY_PROJECT_DEVELOPERS = "project-developers";
172 
173     public static final String KEY_PROJECT_DEPENDENCIES = "project-dependencies";
174 
175     public static final String KEY_PROJECT_NOTIFIERS = "project-notifiers";
176 
177     public static final String KEY_PROJECT_URL = "project-url";
178 
179     public static final String KEY_SCM_TAG = "scm-tag";
180 
181     public static final String KEY_PROJECT_PARENT = "project-parent";
182 
183     public static final String KEY_NOTIFIER_TYPE = "notifier-type";
184 
185     public static final String KEY_NOTIFIER_CONFIGURATION = "notifier-configuration";
186 
187     public static final String KEY_NOTIFIER_FROM = "notifier-from";
188 
189     public static final String KEY_NOTIFIER_RECIPIENT_TYPE = "notifier-recipient-type";
190 
191     public static final String KEY_NOTIFIER_ENABLED = "notifier-enabled";
192 
193     public static final String KEY_NOTIFIER_SEND_ON_SUCCESS = "notifier-send-on-success";
194 
195     public static final String KEY_NOTIFIER_SEND_ON_FAILURE = "notifier-send-on-failure";
196 
197     public static final String KEY_NOTIFIER_SEND_ON_ERROR = "notifier-send-on-error";
198 
199     public static final String KEY_NOTIFIER_SEND_ON_SCMFAILURE = "notifier-send-on-scmfailure";
200 
201     public static final String KEY_NOTIFIER_SEND_ON_WARNING = "notifier-send-on-warning";
202 
203     public static final String KEY_PROJECT_DEVELOPER_NAME = "developer-name";
204 
205     public static final String KEY_PROJECT_DEVELOPER_EMAIL = "developer-email";
206 
207     public static final String KEY_PROJECT_DEVELOPER_SCMID = "developer-scmid";
208 
209     public static final String KEY_PROJECT_MODULES = "project-modules";
210 
211     public static final String KEY_MAVEN_PROJECT = "maven-project";
212 
213     public static final String KEY_LATEST_UPDATE_DATE = "latest-update-date";
214 
215     public static final String KEY_BUILD_AGENT_URL = "build-agent-url";
216 
217     public static final String KEY_SCM_TAGBASE = "scm-tagbase";
218 
219     public static final String KEY_PREPARE_GOALS = "preparation-goals";
220 
221     public static final String KEY_PERFORM_GOALS = "perform-goals";
222 
223     public static final String KEY_SCM_COMMENT_PREFIX = "scm-comment-prefix";
224 
225     public static final String KEY_AUTO_VERSION_SUBMODULES = "auto-version-submodules";
226 
227     public static final String KEY_ADD_SCHEMA = "add-schema";
228 
229     public static final String KEY_USE_RELEASE_PROFILE = "use-release-profile";
230 
231     public static final String KEY_RELEASE_VERSION = "release-version";
232 
233     public static final String KEY_DEVELOPMENT_VERSION = "development-version";
234 
235     public static final String KEY_USE_EDIT_MODE = "use-edit-mode";
236 
237     public static final String KEY_RELEASE_RESULT_CODE = "release-result-code";
238 
239     public static final String KEY_RELEASE_OUTPUT = "release-output";
240 
241     public static final String KEY_BUILD_CONTEXTS = "build-contexts";
242 
243     public static final String KEY_MAX_JOB_EXEC_TIME = "max-job-exec-time";
244 
245     public static final String KEY_RELEASE_STATE = "state";
246 
247     public static final String KEY_RELEASE_PHASES = "release-phases";
248 
249     public static final String KEY_RELEASE_IN_PROGRESS = "release-in-progress";
250 
251     public static final String KEY_COMPLETED_RELEASE_PHASES = "completed-release-phases";
252 
253     public static final String KEY_RELEASE_ERROR = "release-error";
254 
255     public static final String KEY_LOCAL_REPOSITORY_NAME = "repo-name";
256 
257     public static final String KEY_LOCAL_REPOSITORY_LAYOUT = "repo-layout";
258 
259     public static Integer getProjectId( Map<String, Object> context )
260     {
261         return getInteger( context, KEY_PROJECT_ID );
262     }
263 
264     public static String getProjectName( Map<String, Object> context )
265     {
266         return getString( context, KEY_PROJECT_NAME );
267     }
268 
269     public static Integer getProjectState( Map<String, Object> context )
270     {
271         return getInteger( context, KEY_PROJECT_STATE );
272     }
273 
274     public static Integer getBuildDefinitionId( Map<String, Object> context )
275     {
276         return getInteger( context, KEY_BUILD_DEFINITION_ID );
277     }
278 
279     public static String getBuildFile( Map<String, Object> context )
280     {
281         return getString( context, KEY_BUILD_FILE );
282     }
283 
284     public static String getExecutorId( Map<String, Object> context )
285     {
286         return getString( context, KEY_EXECUTOR_ID );
287     }
288 
289     public static String getGoals( Map<String, Object> context )
290     {
291         return getString( context, KEY_GOALS );
292     }
293 
294     public static String getArguments( Map<String, Object> context )
295     {
296         return getString( context, KEY_ARGUMENTS );
297     }
298 
299     public static String getScmUrl( Map<String, Object> context )
300     {
301         return getString( context, KEY_SCM_URL );
302     }
303 
304     public static String getScmUsername( Map<String, Object> context )
305     {
306         return getString( context, KEY_SCM_USERNAME, "" );
307     }
308 
309     public static String getScmPassword( Map<String, Object> context )
310     {
311         return getString( context, KEY_SCM_PASSWORD, "" );
312     }
313 
314     public static boolean isBuildFresh( Map<String, Object> context )
315     {
316         return getBoolean( context, KEY_BUILD_FRESH );
317     }
318 
319     public static int getProjectGroupId( Map<String, Object> context )
320     {
321         return getInteger( context, KEY_PROJECT_GROUP_ID );
322     }
323 
324     public static String getScmRootAddress( Map<String, Object> context )
325     {
326         return getString( context, KEY_SCM_ROOT_ADDRESS );
327     }
328 
329     public static int getScmRootState( Map<String, Object> context )
330     {
331         return getInteger( context, KEY_SCM_ROOT_STATE );
332     }
333 
334     public static Project getProject( Map<String, Object> context )
335     {
336         return (Project) getObject( context, KEY_PROJECT );
337     }
338 
339     public static BuildDefinition getBuildDefinition( Map<String, Object> context )
340     {
341         return (BuildDefinition) getObject( context, KEY_BUILD_DEFINITION );
342     }
343 
344     public static ScmResult getCheckoutScmResult( Map<String, Object> context, Object defaultValue )
345     {
346         return (ScmResult) getObject( context, KEY_CHECKOUT_SCM_RESULT, defaultValue );
347     }
348 
349     public static ScmResult getUpdateScmResult( Map<String, Object> context, Object defaultValue )
350     {
351         return (ScmResult) getObject( context, KEY_UPDATE_SCM_RESULT, defaultValue );
352     }
353 
354     public static ScmResult getScmResult( Map<String, Object> context, Object defaultValue )
355     {
356         return (ScmResult) getObject( context, KEY_SCM_RESULT, defaultValue );
357     }
358 
359     public static int getTrigger( Map<String, Object> context )
360     {
361         return getInteger( context, KEY_TRIGGER );
362     }
363 
364     public static String getUsername( Map<String, Object> context )
365     {
366         return getString( context, KEY_USERNAME, "scheduled" );
367     }
368 
369     public static BuildTrigger getBuildTrigger( Map<String, Object> context )
370     {
371         return new BuildTrigger( getTrigger( context ), getUsername( context ) );
372     }
373 
374     public static BuildResult getBuildResult( Map<String, Object> context, Object defaultValue )
375     {
376         return (BuildResult) getObject( context, KEY_BUILD_RESULT, defaultValue );
377     }
378 
379     public static Map<String, String> getEnvironments( Map<String, Object> context )
380     {
381         return (Map<String, String>) getObject( context, KEY_ENVIRONMENTS );
382     }
383 
384     public static String getLocalRepository( Map<String, Object> context )
385     {
386         return getString( context, KEY_LOCAL_REPOSITORY, "" );
387     }
388 
389     public static String getProjectVersion( Map<String, Object> context )
390     {
391         return getString( context, KEY_PROJECT_VERSION );
392     }
393 
394     public static String getProjectGroupName( Map<String, Object> context )
395     {
396         return getString( context, KEY_PROJECT_GROUP_NAME );
397     }
398 
399     public static int getBuildNumber( Map<String, Object> context )
400     {
401         return getInteger( context, KEY_BUILD_NUMBER );
402     }
403 
404     public static List<Map<String, Object>> getOldScmChanges( Map<String, Object> context )
405     {
406         return getList( context, KEY_OLD_SCM_CHANGES );
407     }
408 
409     public static String getChangeSetAuthor( Map<String, Object> context )
410     {
411         return getString( context, KEY_CHANGESET_AUTHOR );
412     }
413 
414     public static String getChangeSetComment( Map<String, Object> context )
415     {
416         return getString( context, KEY_CHANGESET_COMMENT );
417     }
418 
419     public static long getChangeSetDate( Map<String, Object> context )
420     {
421         Date date = getDate( context, KEY_CHANGESET_DATE );
422 
423         if ( date == null )
424         {
425             return 0;
426         }
427         else
428         {
429             return date.getTime();
430         }
431     }
432 
433     public static List getChangeSetFiles( Map<String, Object> context )
434     {
435         return getList( context, KEY_CHANGESET_FILES );
436     }
437 
438     public static String getChangeFileName( Map<String, Object> context )
439     {
440         return getString( context, KEY_CHANGEFILE_NAME );
441     }
442 
443     public static String getChangeFileRevision( Map<String, Object> context )
444     {
445         return getString( context, KEY_CHANGEFILE_REVISION );
446     }
447 
448     public static String getChangeFileStatus( Map<String, Object> context )
449     {
450         return getString( context, KEY_CHANGEFILE_STATUS );
451     }
452 
453     public static ScmResult getOldScmResult( Map<String, Object> context, ScmResult defaultValue )
454     {
455         return (ScmResult) getObject( context, KEY_OLD_SCM_RESULT, defaultValue );
456     }
457 
458     public static List getScmChanges( Map<String, Object> context )
459     {
460         return getList( context, KEY_SCM_CHANGES );
461     }
462 
463     public static Date getLatestUpdateDate( Map<String, Object> context )
464     {
465         return getDate( context, KEY_LATEST_UPDATE_DATE );
466     }
467 
468     public static String getBuildAgentUrl( Map<String, Object> context )
469     {
470         return getString( context, KEY_BUILD_AGENT_URL );
471     }
472 
473     public static String getGroupId( Map<String, Object> context )
474     {
475         return getString( context, KEY_GROUP_ID );
476     }
477 
478     public static String getArtifactId( Map<String, Object> context )
479     {
480         return getString( context, KEY_ARTIFACT_ID );
481     }
482 
483     public static Map getReleaseVersion( Map<String, Object> context )
484     {
485         return getMap( context, KEY_RELEASE_VERSION );
486     }
487 
488     public static Map getDevelopmentVersion( Map<String, Object> context )
489     {
490         return getMap( context, KEY_DEVELOPMENT_VERSION );
491     }
492 
493     public static String getScmTagBase( Map<String, Object> context )
494     {
495         return getString( context, KEY_SCM_TAGBASE, "" );
496     }
497 
498     public static String getScmCommentPrefix( Map<String, Object> context )
499     {
500         return getString( context, KEY_SCM_COMMENT_PREFIX, "" );
501     }
502 
503     public static String getScmTag( Map<String, Object> context )
504     {
505         return getString( context, KEY_SCM_TAG, "" );
506     }
507 
508     public static String getPrepareGoals( Map<String, Object> context )
509     {
510         return getString( context, KEY_PREPARE_GOALS, "" );
511     }
512 
513     public static String getPerformGoals( Map<String, Object> context )
514     {
515         return getString( context, KEY_PERFORM_GOALS, "" );
516     }
517 
518     public static String getUseEditMode( Map<String, Object> context )
519     {
520         return getString( context, KEY_USE_EDIT_MODE, "" );
521     }
522 
523     public static String getAddSchema( Map<String, Object> context )
524     {
525         return getString( context, KEY_ADD_SCHEMA, "" );
526     }
527 
528     public static String getAutoVersionSubmodules( Map<String, Object> context )
529     {
530         return getString( context, KEY_AUTO_VERSION_SUBMODULES, "" );
531     }
532 
533     public static List getBuildContexts( Map<String, Object> context )
534     {
535         return getList( context, KEY_BUILD_CONTEXTS );
536     }
537 
538     public static int getMaxExecutionTime( Map<String, Object> context )
539     {
540         return getInteger( context, KEY_MAX_JOB_EXEC_TIME );
541     }
542 
543     public static String getLocalRepositoryName( Map<String, Object> context )
544     {
545         return getString( context, KEY_LOCAL_REPOSITORY_NAME, "" );
546     }
547 
548     public static String getLocalRepositoryLayout( Map<String, Object> context )
549     {
550         return getString( context, KEY_LOCAL_REPOSITORY_LAYOUT, "" );
551     }
552 
553     public static int getScmRootId( Map<String, Object> context )
554     {
555         return getInteger( context, KEY_SCM_ROOT_ID );
556     }
557 
558     public static String getBuildDefinitionLabel( Map<String, Object> context )
559     {
560         return getString( context, KEY_BUILD_DEFINITION_LABEL, "" );
561     }
562 
563     // ----------------------------------------------------------------------
564     //
565     // ----------------------------------------------------------------------
566 
567     public static String getString( Map<String, Object> context, String key )
568     {
569         return (String) getObject( context, key );
570     }
571 
572     public static String getString( Map<String, Object> context, String key, String defaultValue )
573     {
574         return (String) getObject( context, key, defaultValue );
575     }
576 
577     public static boolean getBoolean( Map<String, Object> context, String key )
578     {
579         return (Boolean) getObject( context, key );
580     }
581 
582     public static boolean getBoolean( Map<String, Object> context, String key, boolean defaultValue )
583     {
584         return (Boolean) getObject( context, key, defaultValue );
585     }
586 
587     public static int getInteger( Map<String, Object> context, String key )
588     {
589         Object obj = getObject( context, key, null );
590 
591         if ( obj == null )
592         {
593             return 0;
594         }
595         else
596         {
597             return (Integer) obj;
598         }
599     }
600 
601     public static List getList( Map<String, Object> context, String key )
602     {
603         Object obj = getObject( context, key, null );
604 
605         if ( obj == null )
606         {
607             return null;
608         }
609         else
610         {
611             List<Object> list = new ArrayList<Object>();
612 
613             if ( obj instanceof Object[] )
614             {
615                 Object[] objA = (Object[]) obj;
616 
617                 list.addAll( Arrays.asList( objA ) );
618             }
619             else
620             {
621                 list = (List<Object>) obj;
622             }
623 
624             return list;
625         }
626     }
627 
628     public static Date getDate( Map<String, Object> context, String key )
629     {
630         Object obj = getObject( context, key, null );
631 
632         if ( obj == null )
633         {
634             return null;
635         }
636         else
637         {
638             return (Date) obj;
639         }
640     }
641 
642     protected static Map getMap( Map<String, Object> context, String key )
643     {
644         Object obj = getObject( context, key, null );
645 
646         if ( obj == null )
647         {
648             return null;
649         }
650         else
651         {
652             return (Map) obj;
653         }
654     }
655 
656     protected static Object getObject( Map<String, Object> context, String key )
657     {
658         if ( !context.containsKey( key ) )
659         {
660             throw new RuntimeException( "Missing key '" + key + "'." );
661         }
662 
663         Object value = context.get( key );
664 
665         if ( value == null )
666         {
667             throw new RuntimeException( "Missing value for key '" + key + "'." );
668         }
669 
670         return value;
671     }
672 
673     protected static Object getObject( Map<String, Object> context, String key, Object defaultValue )
674     {
675         Object value = context.get( key );
676 
677         if ( value == null )
678         {
679             return defaultValue;
680         }
681 
682         return value;
683     }
684 
685     public static String throwableToString( Throwable error )
686     {
687         if ( error == null )
688         {
689             return "";
690         }
691 
692         StringWriter writer = new StringWriter();
693 
694         PrintWriter printer = new PrintWriter( writer );
695 
696         error.printStackTrace( printer );
697 
698         printer.flush();
699 
700         return writer.getBuffer().toString();
701     }
702 
703     public static String throwableMessagesToString( Throwable error )
704     {
705         if ( error == null )
706         {
707             return "";
708         }
709 
710         StringBuffer buffer = new StringBuffer();
711 
712         buffer.append( error.getMessage() );
713 
714         error = error.getCause();
715 
716         while ( error != null )
717         {
718             buffer.append( EOL );
719 
720             buffer.append( error.getMessage() );
721 
722             error = error.getCause();
723         }
724 
725         return buffer.toString();
726     }
727 
728     public static Map<String, Object> createScmResult( BuildContext buildContext )
729     {
730         Map<String, Object> result = new HashMap<String, Object>();
731         ScmResult scmResult = buildContext.getScmResult();
732 
733         result.put( ContinuumBuildAgentUtil.KEY_PROJECT_ID, buildContext.getProjectId() );
734         if ( StringUtils.isEmpty( scmResult.getCommandLine() ) )
735         {
736             result.put( ContinuumBuildAgentUtil.KEY_SCM_COMMAND_LINE, "" );
737         }
738         else
739         {
740             result.put( ContinuumBuildAgentUtil.KEY_SCM_COMMAND_LINE, scmResult.getCommandLine() );
741         }
742         if ( StringUtils.isEmpty( scmResult.getCommandOutput() ) )
743         {
744             result.put( ContinuumBuildAgentUtil.KEY_SCM_COMMAND_OUTPUT, "" );
745         }
746         else
747         {
748             result.put( ContinuumBuildAgentUtil.KEY_SCM_COMMAND_OUTPUT, scmResult.getCommandOutput() );
749         }
750         if ( StringUtils.isEmpty( scmResult.getProviderMessage() ) )
751         {
752             result.put( ContinuumBuildAgentUtil.KEY_SCM_PROVIDER_MESSAGE, "" );
753         }
754         else
755         {
756             result.put( ContinuumBuildAgentUtil.KEY_SCM_PROVIDER_MESSAGE, scmResult.getProviderMessage() );
757         }
758         if ( StringUtils.isEmpty( scmResult.getException() ) )
759         {
760             result.put( ContinuumBuildAgentUtil.KEY_SCM_EXCEPTION, "" );
761         }
762         else
763         {
764             result.put( ContinuumBuildAgentUtil.KEY_SCM_EXCEPTION, scmResult.getException() );
765         }
766         result.put( ContinuumBuildAgentUtil.KEY_SCM_SUCCESS, scmResult.isSuccess() );
767         result.put( ContinuumBuildAgentUtil.KEY_SCM_CHANGES, getScmChanges( scmResult ) );
768 
769         return result;
770     }
771 
772     private static List<Map<String, Object>> getScmChanges( ScmResult scmResult )
773     {
774         List<Map<String, Object>> scmChanges = new ArrayList<Map<String, Object>>();
775 
776         List<ChangeSet> changes = scmResult.getChanges();
777 
778         if ( changes != null )
779         {
780             for ( ChangeSet cs : changes )
781             {
782                 Map<String, Object> changeSet = new HashMap<String, Object>();
783 
784                 if ( StringUtils.isNotEmpty( cs.getAuthor() ) )
785                 {
786                     changeSet.put( ContinuumBuildAgentUtil.KEY_CHANGESET_AUTHOR, cs.getAuthor() );
787                 }
788                 else
789                 {
790                     changeSet.put( ContinuumBuildAgentUtil.KEY_CHANGESET_AUTHOR, "" );
791                 }
792                 if ( StringUtils.isNotEmpty( cs.getComment() ) )
793                 {
794                     changeSet.put( ContinuumBuildAgentUtil.KEY_CHANGESET_COMMENT, cs.getComment() );
795                 }
796                 else
797                 {
798                     changeSet.put( ContinuumBuildAgentUtil.KEY_CHANGESET_COMMENT, "" );
799                 }
800                 if ( cs.getDateAsDate() != null )
801                 {
802                     changeSet.put( ContinuumBuildAgentUtil.KEY_CHANGESET_DATE, cs.getDateAsDate() );
803                 }
804                 changeSet.put( ContinuumBuildAgentUtil.KEY_CHANGESET_FILES, getChangeFiles( cs.getFiles() ) );
805 
806                 scmChanges.add( changeSet );
807             }
808         }
809 
810         return scmChanges;
811     }
812 
813     private static List<Map<String, String>> getChangeFiles( List<ChangeFile> changeFiles )
814     {
815         List<Map<String, String>> files = new ArrayList<Map<String, String>>();
816 
817         if ( changeFiles != null )
818         {
819             for ( ChangeFile file : changeFiles )
820             {
821                 Map<String, String> changeFile = new HashMap<String, String>();
822                 if ( StringUtils.isNotEmpty( file.getName() ) )
823                 {
824                     changeFile.put( ContinuumBuildAgentUtil.KEY_CHANGEFILE_NAME, file.getName() );
825                 }
826                 else
827                 {
828                     changeFile.put( ContinuumBuildAgentUtil.KEY_CHANGEFILE_NAME, "" );
829                 }
830                 if ( StringUtils.isNotEmpty( file.getRevision() ) )
831                 {
832                     changeFile.put( ContinuumBuildAgentUtil.KEY_CHANGEFILE_REVISION, file.getRevision() );
833                 }
834                 else
835                 {
836                     changeFile.put( ContinuumBuildAgentUtil.KEY_CHANGEFILE_REVISION, "" );
837                 }
838                 if ( StringUtils.isNotEmpty( file.getStatus() ) )
839                 {
840                     changeFile.put( ContinuumBuildAgentUtil.KEY_CHANGEFILE_STATUS, file.getStatus() );
841                 }
842                 else
843                 {
844                     changeFile.put( ContinuumBuildAgentUtil.KEY_CHANGEFILE_STATUS, "" );
845                 }
846 
847                 files.add( changeFile );
848             }
849         }
850 
851         return files;
852     }
853 
854     public static List<File> getFiles( String userDirectory, File workingDirectory )
855         throws ContinuumException
856     {
857         return getFiles( workingDirectory, null, userDirectory );
858     }
859 
860     private static List<File> getFiles( File baseDirectory, String currentSubDirectory, String userDirectory )
861     {
862         List<File> dirs = new ArrayList<File>();
863 
864         File workingDirectory;
865 
866         if ( currentSubDirectory != null )
867         {
868             workingDirectory = new File( baseDirectory, currentSubDirectory );
869         }
870         else
871         {
872             workingDirectory = baseDirectory;
873         }
874 
875         String[] files = workingDirectory.list();
876 
877         if ( files != null )
878         {
879             for ( String file : files )
880             {
881                 File current = new File( workingDirectory, file );
882 
883                 String currentFile;
884 
885                 if ( currentSubDirectory == null )
886                 {
887                     currentFile = file;
888                 }
889                 else
890                 {
891                     currentFile = currentSubDirectory + "/" + file;
892                 }
893 
894                 if ( userDirectory != null && current.isDirectory() && userDirectory.startsWith( currentFile ) )
895                 {
896                     dirs.add( current );
897 
898                     dirs.addAll( getFiles( baseDirectory, currentFile, userDirectory ) );
899                 }
900                 else
901                 {
902                     dirs.add( current );
903                 }
904             }
905         }
906 
907         return dirs;
908     }
909 }