View Javadoc

1   package org.apache.continuum.buildagent;
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.commons.io.FileUtils;
23  import org.apache.commons.lang.ArrayUtils;
24  import org.apache.commons.lang.StringEscapeUtils;
25  import org.apache.continuum.buildagent.buildcontext.BuildContext;
26  import org.apache.continuum.buildagent.buildcontext.manager.BuildContextManager;
27  import org.apache.continuum.buildagent.configuration.BuildAgentConfigurationService;
28  import org.apache.continuum.buildagent.manager.BuildAgentManager;
29  import org.apache.continuum.buildagent.manager.BuildAgentPurgeManager;
30  import org.apache.continuum.buildagent.manager.BuildAgentReleaseManager;
31  import org.apache.continuum.buildagent.model.Installation;
32  import org.apache.continuum.buildagent.taskqueue.PrepareBuildProjectsTask;
33  import org.apache.continuum.buildagent.taskqueue.manager.BuildAgentTaskQueueManager;
34  import org.apache.continuum.buildagent.utils.ContinuumBuildAgentUtil;
35  import org.apache.continuum.buildagent.utils.WorkingCopyContentGenerator;
36  import org.apache.continuum.taskqueue.BuildProjectTask;
37  import org.apache.continuum.taskqueue.manager.TaskQueueManagerException;
38  import org.apache.continuum.utils.build.BuildTrigger;
39  import org.apache.continuum.utils.release.ReleaseUtil;
40  import org.apache.maven.continuum.ContinuumException;
41  import org.apache.maven.continuum.model.project.BuildResult;
42  import org.apache.maven.continuum.model.scm.ChangeFile;
43  import org.apache.maven.continuum.model.scm.ChangeSet;
44  import org.apache.maven.continuum.model.scm.ScmResult;
45  import org.apache.maven.continuum.project.ContinuumProjectState;
46  import org.apache.maven.continuum.release.ContinuumReleaseException;
47  import org.apache.maven.shared.release.ReleaseResult;
48  import org.codehaus.plexus.taskqueue.TaskQueueException;
49  import org.codehaus.plexus.util.StringUtils;
50  import org.slf4j.Logger;
51  import org.slf4j.LoggerFactory;
52  
53  import java.io.File;
54  import java.io.IOException;
55  import java.text.MessageFormat;
56  import java.util.ArrayList;
57  import java.util.HashMap;
58  import java.util.List;
59  import java.util.Map;
60  import java.util.Properties;
61  import java.util.regex.Matcher;
62  import java.util.regex.Pattern;
63  import javax.activation.MimetypesFileTypeMap;
64  
65  /**
66   * @plexus.component role="org.apache.continuum.buildagent.ContinuumBuildAgentService"
67   */
68  public class ContinuumBuildAgentServiceImpl
69      implements ContinuumBuildAgentService
70  {
71      private static final Logger log = LoggerFactory.getLogger( ContinuumBuildAgentServiceImpl.class );
72  
73      private static final String FILE_SEPARATOR = System.getProperty( "file.separator" );
74  
75      /**
76       * @plexus.requirement
77       */
78      private BuildAgentConfigurationService buildAgentConfigurationService;
79  
80      /**
81       * @plexus.requirement
82       */
83      private BuildAgentTaskQueueManager buildAgentTaskQueueManager;
84  
85      /**
86       * @plexus.requirement
87       */
88      private BuildContextManager buildContextManager;
89  
90      /**
91       * @plexus.requirement
92       */
93      private WorkingCopyContentGenerator generator;
94  
95      /**
96       * @plexus.requirement
97       */
98      private BuildAgentReleaseManager buildAgentReleaseManager;
99  
100     /**
101      * @plexus.requirement
102      */
103     private BuildAgentManager buildAgentManager;
104 
105     /**
106      * @plexus.requirement
107      */
108     private BuildAgentPurgeManager purgeManager;
109 
110     public void buildProjects( List<Map<String, Object>> projectsBuildContext )
111         throws ContinuumBuildAgentException
112     {
113         List<BuildContext> buildContextList = initializeBuildContext( projectsBuildContext );
114 
115         PrepareBuildProjectsTask task = createPrepareBuildProjectsTask( buildContextList );
116 
117         if ( task == null )
118         {
119             return;
120         }
121 
122         try
123         {
124             log.info( "Adding project group {} to prepare build queue", task.getProjectGroupId() );
125             buildAgentTaskQueueManager.getPrepareBuildQueue().put( task );
126         }
127         catch ( TaskQueueException e )
128         {
129             throw new ContinuumBuildAgentException( "Error while enqueuing projects", e );
130         }
131 
132     }
133 
134     public List<Map<String, String>> getAvailableInstallations()
135         throws ContinuumBuildAgentException
136     {
137         List<Map<String, String>> installationsList = new ArrayList<Map<String, String>>();
138 
139         List<Installation> installations = buildAgentConfigurationService.getAvailableInstallations();
140 
141         for ( Installation installation : installations )
142         {
143             Map<String, String> map = new HashMap<String, String>();
144 
145             if ( StringUtils.isBlank( installation.getName() ) )
146             {
147                 map.put( ContinuumBuildAgentUtil.KEY_INSTALLATION_NAME, "" );
148             }
149             else
150             {
151                 map.put( ContinuumBuildAgentUtil.KEY_INSTALLATION_NAME, installation.getName() );
152             }
153 
154             if ( StringUtils.isBlank( installation.getType() ) )
155             {
156                 map.put( ContinuumBuildAgentUtil.KEY_INSTALLATION_TYPE, "" );
157             }
158             else
159             {
160                 map.put( ContinuumBuildAgentUtil.KEY_INSTALLATION_TYPE, installation.getType() );
161             }
162 
163             if ( StringUtils.isBlank( installation.getVarName() ) )
164             {
165                 map.put( ContinuumBuildAgentUtil.KEY_INSTALLATION_VAR_NAME, "" );
166             }
167             else
168             {
169                 map.put( ContinuumBuildAgentUtil.KEY_INSTALLATION_VAR_VALUE, installation.getVarValue() );
170             }
171 
172             if ( StringUtils.isBlank( installation.getVarValue() ) )
173             {
174                 map.put( ContinuumBuildAgentUtil.KEY_INSTALLATION_VAR_VALUE, "" );
175             }
176             else
177             {
178                 map.put( ContinuumBuildAgentUtil.KEY_INSTALLATION_VAR_VALUE, installation.getVarValue() );
179             }
180 
181             installationsList.add( map );
182         }
183 
184         return installationsList;
185     }
186 
187     public Map<String, Object> getBuildResult( int projectId )
188         throws ContinuumBuildAgentException
189     {
190         log.debug( "Get build result of project {}", projectId );
191 
192         Map<String, Object> result = new HashMap<String, Object>();
193 
194         int currentBuildId = 0;
195 
196         try
197         {
198             log.debug( "Get current build project" );
199             currentBuildId = buildAgentTaskQueueManager.getIdOfProjectCurrentlyBuilding();
200         }
201         catch ( TaskQueueManagerException e )
202         {
203             throw new ContinuumBuildAgentException( e.getMessage(), e );
204         }
205 
206         log.debug( "Check if project {} is the one currently building in the agent", projectId );
207         if ( projectId == currentBuildId )
208         {
209             BuildContext buildContext = buildContextManager.getBuildContext( projectId );
210 
211             result.put( ContinuumBuildAgentUtil.KEY_PROJECT_ID, buildContext.getProjectId() );
212             result.put( ContinuumBuildAgentUtil.KEY_BUILD_DEFINITION_ID, buildContext.getBuildDefinitionId() );
213             result.put( ContinuumBuildAgentUtil.KEY_TRIGGER, buildContext.getTrigger() );
214             result.put( ContinuumBuildAgentUtil.KEY_USERNAME, buildContext.getUsername() );
215 
216             BuildResult buildResult = buildContext.getBuildResult();
217 
218             if ( buildResult != null )
219             {
220                 if ( buildResult.getStartTime() <= 0 )
221                 {
222                     result.put( ContinuumBuildAgentUtil.KEY_START_TIME, Long.toString(
223                         buildContext.getBuildStartTime() ) );
224                 }
225                 else
226                 {
227                     result.put( ContinuumBuildAgentUtil.KEY_START_TIME, Long.toString( buildResult.getStartTime() ) );
228                 }
229 
230                 if ( buildResult.getError() == null )
231                 {
232                     result.put( ContinuumBuildAgentUtil.KEY_BUILD_ERROR, "" );
233                 }
234                 else
235                 {
236                     result.put( ContinuumBuildAgentUtil.KEY_BUILD_ERROR, buildResult.getError() );
237                 }
238 
239                 result.put( ContinuumBuildAgentUtil.KEY_BUILD_STATE, buildResult.getState() );
240                 result.put( ContinuumBuildAgentUtil.KEY_END_TIME, Long.toString( buildResult.getEndTime() ) );
241                 result.put( ContinuumBuildAgentUtil.KEY_BUILD_EXIT_CODE, buildResult.getExitCode() );
242             }
243             else
244             {
245                 result.put( ContinuumBuildAgentUtil.KEY_START_TIME, Long.toString( buildContext.getBuildStartTime() ) );
246                 result.put( ContinuumBuildAgentUtil.KEY_END_TIME, Long.toString( 0 ) );
247                 result.put( ContinuumBuildAgentUtil.KEY_BUILD_STATE, ContinuumProjectState.BUILDING );
248                 result.put( ContinuumBuildAgentUtil.KEY_BUILD_ERROR, "" );
249                 result.put( ContinuumBuildAgentUtil.KEY_BUILD_EXIT_CODE, 0 );
250             }
251 
252             String buildOutput = getBuildOutputText( projectId );
253             if ( buildOutput == null )
254             {
255                 result.put( ContinuumBuildAgentUtil.KEY_BUILD_OUTPUT, "" );
256             }
257             else
258             {
259                 result.put( ContinuumBuildAgentUtil.KEY_BUILD_OUTPUT, buildOutput );
260             }
261 
262             result.put( ContinuumBuildAgentUtil.KEY_SCM_RESULT, ContinuumBuildAgentUtil.createScmResult(
263                 buildContext ) );
264         }
265         else
266         {
267             log.debug( "Unable to get build result because project {} is not currently building in the agent",
268                        projectId );
269         }
270         return result;
271     }
272 
273     public void cancelBuild()
274         throws ContinuumBuildAgentException
275     {
276         try
277         {
278             log.debug( "Cancelling current build" );
279             buildAgentTaskQueueManager.cancelBuild();
280         }
281         catch ( TaskQueueManagerException e )
282         {
283             throw new ContinuumBuildAgentException( e.getMessage(), e );
284         }
285     }
286 
287     public String generateWorkingCopyContent( int projectId, String userDirectory, String baseUrl,
288                                               String imagesBaseUrl )
289         throws ContinuumBuildAgentException
290     {
291         File workingDirectory = buildAgentConfigurationService.getWorkingDirectory( projectId );
292 
293         try
294         {
295             List<File> files = ContinuumBuildAgentUtil.getFiles( userDirectory, workingDirectory );
296             return generator.generate( files, baseUrl, imagesBaseUrl, workingDirectory );
297         }
298         catch ( ContinuumException e )
299         {
300             log.error( "Failed to generate working copy content", e );
301         }
302 
303         return "";
304     }
305 
306     public Map<String, Object> getProjectFile( int projectId, String directory, String filename )
307         throws ContinuumBuildAgentException
308     {
309         Map<String, Object> projectFile = new HashMap<String, Object>();
310 
311         String relativePath = "\\.\\./"; // prevent users from using relative paths.
312         Pattern pattern = Pattern.compile( relativePath );
313         Matcher matcher = pattern.matcher( directory );
314         String filteredDirectory = matcher.replaceAll( "" );
315 
316         matcher = pattern.matcher( filename );
317         String filteredFilename = matcher.replaceAll( "" );
318 
319         File workingDirectory = buildAgentConfigurationService.getWorkingDirectory( projectId );
320 
321         File fileDirectory = new File( workingDirectory, filteredDirectory );
322 
323         File userFile = new File( fileDirectory, filteredFilename );
324         byte[] downloadFile;
325 
326         try
327         {
328             downloadFile = FileUtils.readFileToByteArray( userFile );
329         }
330         catch ( IOException e )
331         {
332             throw new ContinuumBuildAgentException( "Can't read file: " + filename );
333         }
334 
335         MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap();
336         mimeTypesMap.addMimeTypes( "application/java-archive jar war ear" );
337         mimeTypesMap.addMimeTypes( "application/java-class class" );
338         mimeTypesMap.addMimeTypes( "image/png png" );
339 
340         String mimeType = mimeTypesMap.getContentType( userFile );
341         String fileContent;
342         boolean isStream = false;
343 
344         if ( ( mimeType.indexOf( "image" ) >= 0 ) || ( mimeType.indexOf( "java-archive" ) >= 0 ) ||
345             ( mimeType.indexOf( "java-class" ) >= 0 ) || ( userFile.length() > 100000 ) )
346         {
347             fileContent = "";
348             isStream = true;
349         }
350         else
351         {
352             try
353             {
354                 fileContent = FileUtils.readFileToString( userFile );
355             }
356             catch ( IOException e )
357             {
358                 throw new ContinuumBuildAgentException( "Can't read file " + filename, e );
359             }
360         }
361 
362         projectFile.put( "downloadFileName", userFile.getName() );
363         projectFile.put( "downloadFileLength", Long.toString( userFile.length() ) );
364         projectFile.put( "downloadFile", downloadFile );
365         projectFile.put( "mimeType", mimeType );
366         projectFile.put( "fileContent", fileContent );
367         projectFile.put( "isStream", isStream );
368 
369         return projectFile;
370     }
371 
372     public Map<String, Object> getReleasePluginParameters( int projectId, String pomFilename )
373         throws ContinuumBuildAgentException
374     {
375         String workingDirectory = buildAgentConfigurationService.getWorkingDirectory( projectId ).getPath();
376 
377         try
378         {
379             log.debug( "Getting release plugin parameters of project {}", projectId );
380             return ReleaseUtil.getReleasePluginParameters( workingDirectory, pomFilename );
381         }
382         catch ( Exception e )
383         {
384             throw new ContinuumBuildAgentException( "Error getting release plugin parameters from pom file", e );
385         }
386     }
387 
388     public List<Map<String, String>> processProject( int projectId, String pomFilename, boolean autoVersionSubmodules )
389         throws ContinuumBuildAgentException
390     {
391         List<Map<String, String>> projects = new ArrayList<Map<String, String>>();
392 
393         String workingDirectory = buildAgentConfigurationService.getWorkingDirectory( projectId ).getPath();
394 
395         try
396         {
397             ReleaseUtil.processProject( workingDirectory, pomFilename, autoVersionSubmodules, projects );
398         }
399         catch ( Exception e )
400         {
401             throw new ContinuumBuildAgentException( "Unable to process project " + projectId, e );
402         }
403 
404         return projects;
405     }
406 
407     public String releasePrepare( Map project, Properties properties, Map releaseVersion, Map developmentVersion,
408                                   Map<String, String> environments, String username )
409         throws ContinuumBuildAgentException
410     {
411         try
412         {
413             log.debug( "Preparing release" );
414             return buildAgentReleaseManager.releasePrepare( project, properties, releaseVersion, developmentVersion,
415                                                             environments, username );
416         }
417         catch ( ContinuumReleaseException e )
418         {
419             throw new ContinuumBuildAgentException( "Unable to prepare release", e );
420         }
421     }
422 
423     public Map<String, Object> getReleaseResult( String releaseId )
424         throws ContinuumBuildAgentException
425     {
426         log.debug( "Getting release result of release {}", releaseId );
427         ReleaseResult result = buildAgentReleaseManager.getReleaseResult( releaseId );
428 
429         Map<String, Object> map = new HashMap<String, Object>();
430         map.put( ContinuumBuildAgentUtil.KEY_START_TIME, Long.toString( result.getStartTime() ) );
431         map.put( ContinuumBuildAgentUtil.KEY_END_TIME, Long.toString( result.getEndTime() ) );
432         map.put( ContinuumBuildAgentUtil.KEY_RELEASE_RESULT_CODE, result.getResultCode() );
433         map.put( ContinuumBuildAgentUtil.KEY_RELEASE_OUTPUT, result.getOutput() );
434 
435         return map;
436     }
437 
438     public Map<String, Object> getListener( String releaseId )
439         throws ContinuumBuildAgentException
440     {
441         return buildAgentReleaseManager.getListener( releaseId );
442     }
443 
444     public void removeListener( String releaseId )
445     {
446         buildAgentReleaseManager.removeListener( releaseId );
447     }
448 
449     public String getPreparedReleaseName( String releaseId )
450     {
451         return buildAgentReleaseManager.getPreparedReleaseName( releaseId );
452     }
453 
454     public void releasePerform( String releaseId, String goals, String arguments, boolean useReleaseProfile,
455                                 Map repository, String username )
456         throws ContinuumBuildAgentException
457     {
458         try
459         {
460             log.debug( "Performing release" );
461             buildAgentReleaseManager.releasePerform( releaseId, goals, arguments, useReleaseProfile, repository,
462                                                      username );
463         }
464         catch ( ContinuumReleaseException e )
465         {
466             throw new ContinuumBuildAgentException( "Unable to perform release " + releaseId, e );
467         }
468     }
469 
470     public String releasePerformFromScm( String goals, String arguments, boolean useReleaseProfile, Map repository,
471                                          String scmUrl, String scmUsername, String scmPassword, String scmTag,
472                                          String scmTagBase, Map<String, String> environments, String username )
473         throws ContinuumBuildAgentException
474     {
475         try
476         {
477             log.debug( "Performing release from scm" );
478             return buildAgentReleaseManager.releasePerformFromScm( goals, arguments, useReleaseProfile, repository,
479                                                                    scmUrl, scmUsername, scmPassword, scmTag, scmTagBase,
480                                                                    environments, username );
481         }
482         catch ( ContinuumReleaseException e )
483         {
484             throw new ContinuumBuildAgentException( "Unable to perform release from scm", e );
485         }
486     }
487 
488     public String releaseCleanup( String releaseId )
489         throws ContinuumBuildAgentException
490     {
491         log.debug( "Cleanup release {}", releaseId );
492         return buildAgentReleaseManager.releaseCleanup( releaseId );
493     }
494 
495     public void releaseRollback( String releaseId, int projectId )
496         throws ContinuumBuildAgentException
497     {
498         try
499         {
500             log.debug( "Release rollback release {} with project {}", releaseId, projectId );
501             buildAgentReleaseManager.releaseRollback( releaseId, projectId );
502         }
503         catch ( ContinuumReleaseException e )
504         {
505             throw new ContinuumBuildAgentException( e );
506         }
507     }
508 
509     public int getBuildSizeOfAgent()
510     {
511         int size = 0;
512 
513         try
514         {
515             log.debug( "Getting number of projects in any queue" );
516 
517             if ( buildAgentTaskQueueManager.getCurrentProjectInBuilding() != null )
518             {
519                 size++;
520             }
521 
522             PrepareBuildProjectsTask currentPrepareBuild = buildAgentTaskQueueManager.getCurrentProjectInPrepareBuild();
523 
524             if ( currentPrepareBuild != null )
525             {
526                 // need to get actual number of projects.
527                 size = size + currentPrepareBuild.getBuildContexts().size();
528             }
529 
530             size = size + buildAgentTaskQueueManager.getProjectsInBuildQueue().size();
531 
532             for ( PrepareBuildProjectsTask prepareBuildTask : buildAgentTaskQueueManager.getProjectsInPrepareBuildQueue() )
533             {
534                 if ( prepareBuildTask != null )
535                 {
536                     size = size + prepareBuildTask.getBuildContexts().size();
537                 }
538             }
539         }
540         catch ( TaskQueueManagerException e )
541         {
542             log.error( "Error occurred while getting build size of agent" );
543         }
544 
545         return size;
546     }
547 
548     public List<Map<String, Object>> getProjectsInPrepareBuildQueue()
549         throws ContinuumBuildAgentException
550     {
551         try
552         {
553             log.debug( "Getting projects in prepare build queue" );
554             List<Map<String, Object>> projects = new ArrayList<Map<String, Object>>();
555 
556             for ( PrepareBuildProjectsTask task : buildAgentTaskQueueManager.getProjectsInPrepareBuildQueue() )
557             {
558                 Map<String, Object> map = new HashMap<String, Object>();
559                 map.put( ContinuumBuildAgentUtil.KEY_PROJECT_GROUP_ID, new Integer( task.getProjectGroupId() ) );
560                 map.put( ContinuumBuildAgentUtil.KEY_SCM_ROOT_ID, new Integer( task.getScmRootId() ) );
561                 map.put( ContinuumBuildAgentUtil.KEY_SCM_ROOT_ADDRESS, task.getScmRootAddress() );
562                 map.put( ContinuumBuildAgentUtil.KEY_TRIGGER, task.getBuildTrigger().getTrigger() );
563                 map.put( ContinuumBuildAgentUtil.KEY_USERNAME, task.getBuildTrigger().getTriggeredBy() );
564 
565                 projects.add( map );
566             }
567 
568             return projects;
569         }
570         catch ( TaskQueueManagerException e )
571         {
572             log.error( "Error occurred while retrieving projects in prepare build queue", e );
573             throw new ContinuumBuildAgentException( "Error occurred while retrieving projects in prepare build queue",
574                                                     e );
575         }
576     }
577 
578     public List<Map<String, Object>> getProjectsAndBuildDefinitionsInPrepareBuildQueue()
579         throws ContinuumBuildAgentException
580     {
581         try
582         {
583             log.debug( "Getting projects in prepare build queue" );
584             List<Map<String, Object>> projects = new ArrayList<Map<String, Object>>();
585 
586             for ( PrepareBuildProjectsTask task : buildAgentTaskQueueManager.getProjectsInPrepareBuildQueue() )
587             {
588                 for ( BuildContext context : task.getBuildContexts() )
589                 {
590                     Map<String, Object> map = new HashMap<String, Object>();
591 
592                     map.put( ContinuumBuildAgentUtil.KEY_PROJECT_ID, context.getProjectId() );
593                     map.put( ContinuumBuildAgentUtil.KEY_BUILD_DEFINITION_ID, context.getBuildDefinitionId() );
594 
595                     projects.add( map );
596                 }
597             }
598 
599             return projects;
600         }
601         catch ( TaskQueueManagerException e )
602         {
603             log.error( "Error occurred while retrieving projects in prepare build queue", e );
604             throw new ContinuumBuildAgentException( "Error occurred while retrieving projects in prepare build queue",
605                                                     e );
606         }
607     }
608 
609     public List<Map<String, Object>> getProjectsInBuildQueue()
610         throws ContinuumBuildAgentException
611     {
612         try
613         {
614             log.debug( "Getting projects in build queue" );
615             List<Map<String, Object>> projects = new ArrayList<Map<String, Object>>();
616 
617             for ( BuildProjectTask task : buildAgentTaskQueueManager.getProjectsInBuildQueue() )
618             {
619                 Map<String, Object> map = new HashMap<String, Object>();
620                 map.put( ContinuumBuildAgentUtil.KEY_PROJECT_ID, new Integer( task.getProjectId() ) );
621                 map.put( ContinuumBuildAgentUtil.KEY_BUILD_DEFINITION_ID, new Integer( task.getBuildDefinitionId() ) );
622                 map.put( ContinuumBuildAgentUtil.KEY_TRIGGER, task.getBuildTrigger().getTrigger() );
623                 map.put( ContinuumBuildAgentUtil.KEY_USERNAME, task.getBuildTrigger().getTriggeredBy() );
624                 map.put( ContinuumBuildAgentUtil.KEY_PROJECT_GROUP_ID, new Integer( task.getProjectGroupId() ) );
625                 map.put( ContinuumBuildAgentUtil.KEY_BUILD_DEFINITION_LABEL, task.getBuildDefinitionLabel() );
626 
627                 projects.add( map );
628             }
629 
630             return projects;
631         }
632         catch ( TaskQueueManagerException e )
633         {
634             log.error( "Error occurred while retrieving projects in build queue", e );
635             throw new ContinuumBuildAgentException( "Error occurred while retrieving projects in build queue", e );
636         }
637     }
638 
639     public Map<String, Object> getProjectCurrentlyPreparingBuild()
640         throws ContinuumBuildAgentException
641     {
642         try
643         {
644             log.debug( "Get project currently preparing build" );
645             Map<String, Object> project = new HashMap<String, Object>();
646 
647             PrepareBuildProjectsTask task = buildAgentTaskQueueManager.getCurrentProjectInPrepareBuild();
648 
649             if ( task != null )
650             {
651                 project.put( ContinuumBuildAgentUtil.KEY_PROJECT_GROUP_ID, new Integer( task.getProjectGroupId() ) );
652                 project.put( ContinuumBuildAgentUtil.KEY_SCM_ROOT_ID, new Integer( task.getScmRootId() ) );
653                 project.put( ContinuumBuildAgentUtil.KEY_SCM_ROOT_ADDRESS, task.getScmRootAddress() );
654                 project.put( ContinuumBuildAgentUtil.KEY_TRIGGER, task.getBuildTrigger().getTrigger() );
655                 project.put( ContinuumBuildAgentUtil.KEY_USERNAME, task.getBuildTrigger().getTriggeredBy() );
656             }
657 
658             return project;
659         }
660         catch ( TaskQueueManagerException e )
661         {
662             log.error( "Error occurred while retrieving current project in prepare build", e );
663             throw new ContinuumBuildAgentException( "Error occurred while retrieving current project in prepare build",
664                                                     e );
665         }
666     }
667 
668     public List<Map<String, Object>> getProjectsAndBuildDefinitionsCurrentlyPreparingBuild()
669         throws ContinuumBuildAgentException
670     {
671         try
672         {
673             log.debug( "Getting projects currently preparing build" );
674             List<Map<String, Object>> projects = new ArrayList<Map<String, Object>>();
675 
676             PrepareBuildProjectsTask task = buildAgentTaskQueueManager.getCurrentProjectInPrepareBuild();
677 
678             if ( task != null )
679             {
680                 for ( BuildContext context : task.getBuildContexts() )
681                 {
682                     Map<String, Object> map = new HashMap<String, Object>();
683 
684                     map.put( ContinuumBuildAgentUtil.KEY_PROJECT_ID, context.getProjectId() );
685                     map.put( ContinuumBuildAgentUtil.KEY_BUILD_DEFINITION_ID, context.getBuildDefinitionId() );
686 
687                     projects.add( map );
688                 }
689             }
690 
691             return projects;
692         }
693         catch ( TaskQueueManagerException e )
694         {
695             log.error( "Error occurred while retrieving current projects in prepare build", e );
696             throw new ContinuumBuildAgentException( "Error occurred while retrieving current projects in prepare build",
697                                                     e );
698         }
699     }
700 
701     public Map<String, Object> getProjectCurrentlyBuilding()
702         throws ContinuumBuildAgentException
703     {
704         try
705         {
706             log.debug( "Getting currently building project" );
707             Map<String, Object> project = new HashMap<String, Object>();
708 
709             BuildProjectTask task = buildAgentTaskQueueManager.getCurrentProjectInBuilding();
710 
711             if ( task != null )
712             {
713                 project.put( ContinuumBuildAgentUtil.KEY_PROJECT_ID, new Integer( task.getProjectId() ) );
714                 project.put( ContinuumBuildAgentUtil.KEY_BUILD_DEFINITION_ID, new Integer(
715                     task.getBuildDefinitionId() ) );
716                 project.put( ContinuumBuildAgentUtil.KEY_TRIGGER, task.getBuildTrigger().getTrigger() );
717                 project.put( ContinuumBuildAgentUtil.KEY_USERNAME, task.getBuildTrigger().getTriggeredBy() );
718                 project.put( ContinuumBuildAgentUtil.KEY_PROJECT_GROUP_ID, new Integer( task.getProjectGroupId() ) );
719                 project.put( ContinuumBuildAgentUtil.KEY_BUILD_DEFINITION_LABEL, task.getBuildDefinitionLabel() );
720             }
721 
722             return project;
723         }
724         catch ( TaskQueueManagerException e )
725         {
726             log.error( "Error occurred while retrieving current project in building", e );
727             throw new ContinuumBuildAgentException( "Error occurred while retrieving current project in building", e );
728         }
729     }
730 
731     public boolean isProjectGroupInQueue( int projectGroupId )
732     {
733         try
734         {
735             log.debug( "Checking if project group is in any queue", projectGroupId );
736             for ( PrepareBuildProjectsTask task : buildAgentTaskQueueManager.getProjectsInPrepareBuildQueue() )
737             {
738                 if ( task.getProjectGroupId() == projectGroupId )
739                 {
740                     log.debug( "projectGroup {} is in prepare build queue", projectGroupId );
741                     return true;
742                 }
743             }
744 
745             PrepareBuildProjectsTask currentPrepareBuildTask =
746                 buildAgentTaskQueueManager.getCurrentProjectInPrepareBuild();
747 
748             if ( currentPrepareBuildTask != null && currentPrepareBuildTask.getProjectGroupId() == projectGroupId )
749             {
750                 log.debug( "projectGroup {} is currently preparing build", projectGroupId );
751                 return true;
752             }
753 
754             for ( BuildProjectTask task : buildAgentTaskQueueManager.getProjectsInBuildQueue() )
755             {
756                 if ( task.getProjectGroupId() == projectGroupId )
757                 {
758                     log.debug( "projectGroup {} is in build queue", projectGroupId );
759                     return true;
760                 }
761             }
762 
763             BuildProjectTask currentBuildTask = buildAgentTaskQueueManager.getCurrentProjectInBuilding();
764 
765             if ( currentBuildTask != null && currentBuildTask.getProjectGroupId() == projectGroupId )
766             {
767                 log.debug( "projectGroup {} is currently building", projectGroupId );
768                 return true;
769             }
770         }
771         catch ( TaskQueueManagerException e )
772         {
773             log.error( "Error while checking if project group " + projectGroupId + " is queued in agent", e );
774         }
775 
776         return false;
777     }
778 
779     public boolean isProjectScmRootInQueue( int projectScmRootId, List<Integer> projectIds )
780     {
781         try
782         {
783             log.debug( "Checking if projects {} is in any queue", projectIds );
784             PrepareBuildProjectsTask currentPrepareBuildTask =
785                 buildAgentTaskQueueManager.getCurrentProjectInPrepareBuild();
786 
787             if ( currentPrepareBuildTask != null && currentPrepareBuildTask.getScmRootId() == projectScmRootId )
788             {
789                 return true;
790             }
791 
792             BuildProjectTask currentBuildTask = buildAgentTaskQueueManager.getCurrentProjectInBuilding();
793 
794             if ( currentBuildTask != null )
795             {
796                 int projectId = currentBuildTask.getProjectId();
797 
798                 for ( Integer pid : projectIds )
799                 {
800                     if ( pid == projectId )
801                     {
802                         return true;
803                     }
804                 }
805             }
806 
807             for ( PrepareBuildProjectsTask task : buildAgentTaskQueueManager.getProjectsInPrepareBuildQueue() )
808             {
809                 if ( task.getScmRootId() == projectScmRootId )
810                 {
811                     return true;
812                 }
813             }
814 
815             for ( BuildProjectTask task : buildAgentTaskQueueManager.getProjectsInBuildQueue() )
816             {
817                 int projectId = task.getProjectId();
818 
819                 for ( Integer pid : projectIds )
820                 {
821                     if ( pid == projectId )
822                     {
823                         return true;
824                     }
825                 }
826             }
827         }
828         catch ( TaskQueueManagerException e )
829         {
830             log.error( "Error while checking if project scm root " + projectScmRootId + " is queued in agent", e );
831         }
832 
833         return false;
834     }
835 
836     public boolean isProjectGroupInPrepareBuildQueue( int projectGroupId )
837     {
838         try
839         {
840             log.debug( "Checking if project group {} is in prepare build queue", projectGroupId );
841             for ( PrepareBuildProjectsTask task : buildAgentTaskQueueManager.getProjectsInPrepareBuildQueue() )
842             {
843                 if ( task.getProjectGroupId() == projectGroupId )
844                 {
845                     return true;
846                 }
847             }
848         }
849         catch ( TaskQueueManagerException e )
850         {
851             log.error(
852                 "Error while checking if project group " + projectGroupId + " is in prepare build queue in agent", e );
853         }
854 
855         return false;
856     }
857 
858     public boolean isProjectInPrepareBuildQueue( int projectId, int buildDefinitionId )
859     {
860         try
861         {
862             log.debug( "Checking if projectId={}, buildDefinitionId={} is in prepare build queue", projectId,
863                        buildDefinitionId );
864             for ( PrepareBuildProjectsTask task : buildAgentTaskQueueManager.getProjectsInPrepareBuildQueue() )
865             {
866                 if ( task != null )
867                 {
868                     for ( BuildContext context : task.getBuildContexts() )
869                     {
870                         if ( context.getProjectId() == projectId &&
871                             ( buildDefinitionId == -1 || context.getBuildDefinitionId() == buildDefinitionId ) )
872                         {
873                             log.debug( "projectId={}, buildDefinitionId={} is in prepare build queue" );
874                             return true;
875                         }
876                     }
877                 }
878             }
879         }
880         catch ( TaskQueueManagerException e )
881         {
882             log.error( "Error while checking if projectId=" + projectId + ", buildDefinitionId=" + buildDefinitionId +
883                            " is in prepare build queue in agent", e );
884         }
885 
886         return false;
887     }
888 
889     public boolean isProjectGroupCurrentlyPreparingBuild( int projectGroupId )
890     {
891         try
892         {
893             log.debug( "Checking if project group {} currently preparing build", projectGroupId );
894             PrepareBuildProjectsTask currentPrepareBuildTask =
895                 buildAgentTaskQueueManager.getCurrentProjectInPrepareBuild();
896 
897             if ( currentPrepareBuildTask != null && currentPrepareBuildTask.getProjectGroupId() == projectGroupId )
898             {
899                 return true;
900             }
901         }
902         catch ( TaskQueueManagerException e )
903         {
904             log.error(
905                 "Error while checking if project group " + projectGroupId + " is currently preparing build in agent",
906                 e );
907         }
908 
909         return false;
910     }
911 
912     public boolean isProjectCurrentlyPreparingBuild( int projectId, int buildDefinitionId )
913     {
914         try
915         {
916             log.debug( "Checking if projectId={}, buildDefinitionId={} currently preparing build", projectId,
917                        buildDefinitionId );
918             PrepareBuildProjectsTask currentPrepareBuildTask =
919                 buildAgentTaskQueueManager.getCurrentProjectInPrepareBuild();
920 
921             if ( currentPrepareBuildTask != null )
922             {
923                 for ( BuildContext context : currentPrepareBuildTask.getBuildContexts() )
924                 {
925                     if ( context.getProjectId() == projectId &&
926                         ( buildDefinitionId == -1 || context.getBuildDefinitionId() == buildDefinitionId ) )
927                     {
928                         log.debug( "projectId={}, buildDefinitionId={} is currently preparing build" );
929                         return true;
930                     }
931                 }
932             }
933         }
934         catch ( TaskQueueManagerException e )
935         {
936             log.error( "Error while checking if projectId=" + projectId + ", buildDefinitionId=" + buildDefinitionId +
937                            " is currently preparing build in agent", e );
938         }
939 
940         return false;
941     }
942 
943     public boolean isProjectCurrentlyBuilding( int projectId, int buildDefinitionId )
944     {
945         try
946         {
947             log.debug( "Checking if projectId={}, buildDefinitionId={} is currently building", projectId,
948                        buildDefinitionId );
949             BuildProjectTask currentBuildTask = buildAgentTaskQueueManager.getCurrentProjectInBuilding();
950 
951             if ( currentBuildTask != null && currentBuildTask.getProjectId() == projectId &&
952                 ( buildDefinitionId == -1 || currentBuildTask.getBuildDefinitionId() == buildDefinitionId ) )
953             {
954                 log.debug( "projectId={}, buildDefinitionId={} is currently building" );
955                 return true;
956             }
957         }
958         catch ( TaskQueueManagerException e )
959         {
960             log.error(
961                 "Error occurred while checking if projectId=" + projectId + ", buildDefinitionId=" + buildDefinitionId +
962                     " is currently building in agent", e );
963         }
964 
965         return false;
966     }
967 
968     public boolean isProjectInBuildQueue( int projectId, int buildDefinitionId )
969     {
970         try
971         {
972             log.debug( "Checking if projectId={}, buildDefinitionId={} is in build queue", projectId,
973                        buildDefinitionId );
974             List<BuildProjectTask> buildTasks = buildAgentTaskQueueManager.getProjectsInBuildQueue();
975 
976             if ( buildTasks != null )
977             {
978                 for ( BuildProjectTask task : buildTasks )
979                 {
980                     if ( task.getProjectId() == projectId &&
981                         ( buildDefinitionId == -1 || task.getBuildDefinitionId() == buildDefinitionId ) )
982                     {
983                         log.debug( "projectId={}, buildDefinitionId={} is in build queue" );
984                         return true;
985                     }
986                 }
987             }
988         }
989         catch ( TaskQueueManagerException e )
990         {
991             log.error(
992                 "Error occurred while checking if projectId=" + projectId + ", buildDefinitionId=" + buildDefinitionId +
993                     " is in build queue of agent", e );
994         }
995 
996         return false;
997     }
998 
999     public boolean removeFromPrepareBuildQueue( int projectGroupId, int scmRootId )
1000         throws ContinuumBuildAgentException
1001     {
1002         try
1003         {
1004             log.info( "Removing project group {} from prepare build queue", projectGroupId );
1005             return buildAgentTaskQueueManager.removeFromPrepareBuildQueue( projectGroupId, scmRootId );
1006         }
1007         catch ( TaskQueueManagerException e )
1008         {
1009             log.error( "Error occurred while removing projects from prepare build queue", e );
1010             throw new ContinuumBuildAgentException( "Error occurred while removing projects from prepare build queue",
1011                                                     e );
1012         }
1013     }
1014 
1015     public void removeFromPrepareBuildQueue( List<String> hashCodes )
1016         throws ContinuumBuildAgentException
1017     {
1018         try
1019         {
1020             log.info( "Removing project groups {} from prepare build queue", hashCodes );
1021             buildAgentTaskQueueManager.removeFromPrepareBuildQueue( listToIntArray( hashCodes ) );
1022         }
1023         catch ( TaskQueueManagerException e )
1024         {
1025             log.error( "Error occurred while removing projects from prepare build queue", e );
1026             throw new ContinuumBuildAgentException( "Error occurred while removing projects from prepare build queue",
1027                                                     e );
1028         }
1029     }
1030 
1031     public boolean removeFromBuildQueue( int projectId, int buildDefinitionId )
1032         throws ContinuumBuildAgentException
1033     {
1034         try
1035         {
1036             log.info( "Removing project {} with buildDefinition {} from build queue", projectId, buildDefinitionId );
1037             return buildAgentTaskQueueManager.removeFromBuildQueue( projectId, buildDefinitionId );
1038         }
1039         catch ( TaskQueueManagerException e )
1040         {
1041             log.error( "Error occurred while removing project from build queue", e );
1042             throw new ContinuumBuildAgentException( "Error occurred while removing project from build queue ", e );
1043         }
1044     }
1045 
1046     public void removeFromBuildQueue( List<String> hashCodes )
1047         throws ContinuumBuildAgentException
1048     {
1049         try
1050         {
1051             log.info( "Removing projects {} from build queue", hashCodes );
1052             buildAgentTaskQueueManager.removeFromBuildQueue( listToIntArray( hashCodes ) );
1053         }
1054         catch ( TaskQueueManagerException e )
1055         {
1056             log.error( "Error occurred while removing projects from build queue", e );
1057             throw new ContinuumBuildAgentException( "Error occurred while removing project from build queue ", e );
1058         }
1059     }
1060 
1061     public boolean ping()
1062         throws ContinuumBuildAgentException
1063     {
1064         try
1065         {
1066             // check first if it can ping the master
1067             return buildAgentManager.pingMaster();
1068         }
1069         catch ( ContinuumException e )
1070         {
1071             throw new ContinuumBuildAgentException( e.getMessage() );
1072         }
1073     }
1074 
1075     public String getBuildAgentPlatform()
1076         throws ContinuumBuildAgentException
1077     {
1078         try
1079         {
1080             log.debug( "Getting build agent platform" );
1081             return System.getProperty( "os.name" );
1082         }
1083         catch ( Exception e )
1084         {
1085             log.error( "Error in when trying to get build agent's platform", e );
1086             throw new ContinuumBuildAgentException( "Error in when trying to get build agent's platform", e );
1087         }
1088     }
1089 
1090     public boolean isExecutingBuild()
1091     {
1092         return getBuildSizeOfAgent() > 0;
1093     }
1094 
1095     public boolean isExecutingRelease()
1096         throws ContinuumBuildAgentException
1097     {
1098         try
1099         {
1100             return buildAgentReleaseManager.getReleaseManager().isExecutingRelease();
1101         }
1102         catch ( Exception e )
1103         {
1104             throw new ContinuumBuildAgentException( e.getMessage(), e );
1105         }
1106     }
1107 
1108     public void executeDirectoryPurge( String directoryType, int daysOlder, int retentionCount, boolean deleteAll )
1109         throws ContinuumBuildAgentException
1110     {
1111         String logMsgFormat =
1112             "Directory purge [directoryType={0}, daysOlder={1}, retentionCount={2}, deleteAll={3}] not possible; {4}";
1113         if ( isExecutingBuild() )
1114         {
1115             log.info( MessageFormat.format( logMsgFormat, directoryType, daysOlder, retentionCount, deleteAll,
1116                                             "Build Agent busy" ) );
1117             return;
1118         }
1119 
1120         try
1121         {
1122             if ( isExecutingRelease() )
1123             {
1124                 log.info( MessageFormat.format( logMsgFormat, directoryType, daysOlder, retentionCount, deleteAll,
1125                                                 "Build Agent is executing a release." ) );
1126                 return;
1127             }
1128         }
1129         catch ( ContinuumBuildAgentException e )
1130         {
1131             if ( isExecutingRelease() )
1132             {
1133                 log.info( MessageFormat.format( logMsgFormat, directoryType, daysOlder, retentionCount, deleteAll,
1134                                                 "Unable to determine if Build Agent is executing a release." ) );
1135                 return;
1136             }
1137         }
1138 
1139         try
1140         {
1141             purgeManager.executeDirectoryPurge( directoryType, daysOlder, retentionCount, deleteAll );
1142         }
1143         catch ( Exception e )
1144         {
1145             throw new ContinuumBuildAgentException( e.getMessage(), e );
1146         }
1147     }
1148 
1149     private List<BuildContext> initializeBuildContext( List<Map<String, Object>> projectsBuildContext )
1150     {
1151         List<BuildContext> buildContext = new ArrayList<BuildContext>();
1152 
1153         for ( Map<String, Object> map : projectsBuildContext )
1154         {
1155             BuildContext context = new BuildContext();
1156             context.setProjectId( ContinuumBuildAgentUtil.getProjectId( map ) );
1157             context.setProjectVersion( ContinuumBuildAgentUtil.getProjectVersion( map ) );
1158             context.setBuildDefinitionId( ContinuumBuildAgentUtil.getBuildDefinitionId( map ) );
1159             context.setBuildFile( ContinuumBuildAgentUtil.getBuildFile( map ) );
1160             context.setExecutorId( ContinuumBuildAgentUtil.getExecutorId( map ) );
1161             context.setGoals( ContinuumBuildAgentUtil.getGoals( map ) );
1162             context.setArguments( ContinuumBuildAgentUtil.getArguments( map ) );
1163             context.setScmUrl( ContinuumBuildAgentUtil.getScmUrl( map ) );
1164             context.setScmUsername( ContinuumBuildAgentUtil.getScmUsername( map ) );
1165             context.setScmPassword( ContinuumBuildAgentUtil.getScmPassword( map ) );
1166             context.setBuildFresh( ContinuumBuildAgentUtil.isBuildFresh( map ) );
1167             context.setProjectGroupId( ContinuumBuildAgentUtil.getProjectGroupId( map ) );
1168             context.setProjectGroupName( ContinuumBuildAgentUtil.getProjectGroupName( map ) );
1169             context.setScmRootAddress( ContinuumBuildAgentUtil.getScmRootAddress( map ) );
1170             context.setScmRootId( ContinuumBuildAgentUtil.getScmRootId( map ) );
1171             context.setProjectName( ContinuumBuildAgentUtil.getProjectName( map ) );
1172             context.setProjectState( ContinuumBuildAgentUtil.getProjectState( map ) );
1173             context.setTrigger( ContinuumBuildAgentUtil.getTrigger( map ) );
1174             context.setUsername( ContinuumBuildAgentUtil.getUsername( map ) );
1175             context.setLocalRepository( ContinuumBuildAgentUtil.getLocalRepository( map ) );
1176             context.setBuildNumber( ContinuumBuildAgentUtil.getBuildNumber( map ) );
1177             context.setOldScmResult( getScmResult( ContinuumBuildAgentUtil.getOldScmChanges( map ) ) );
1178             context.setLatestUpdateDate( ContinuumBuildAgentUtil.getLatestUpdateDate( map ) );
1179             context.setBuildAgentUrl( ContinuumBuildAgentUtil.getBuildAgentUrl( map ) );
1180             context.setMaxExecutionTime( ContinuumBuildAgentUtil.getMaxExecutionTime( map ) );
1181             context.setBuildDefinitionLabel( ContinuumBuildAgentUtil.getBuildDefinitionLabel( map ) );
1182             context.setScmTag( ContinuumBuildAgentUtil.getScmTag( map ) );
1183 
1184             buildContext.add( context );
1185         }
1186 
1187         buildContextManager.addBuildContexts( buildContext );
1188 
1189         return buildContext;
1190     }
1191 
1192     private String getBuildOutputText( int projectId )
1193     {
1194         try
1195         {
1196             File buildOutputFile = buildAgentConfigurationService.getBuildOutputFile( projectId );
1197 
1198             if ( buildOutputFile.exists() )
1199             {
1200                 return StringEscapeUtils.escapeHtml( FileUtils.readFileToString( buildOutputFile ) );
1201             }
1202         }
1203         catch ( Exception e )
1204         {
1205             // do not throw exception, just log it
1206             log.error( "Error retrieving build output file", e );
1207         }
1208 
1209         return null;
1210     }
1211 
1212     private ScmResult getScmResult( List<Map<String, Object>> scmChanges )
1213     {
1214         ScmResult scmResult = null;
1215 
1216         if ( scmChanges != null && scmChanges.size() > 0 )
1217         {
1218             scmResult = new ScmResult();
1219 
1220             for ( Map<String, Object> map : scmChanges )
1221             {
1222                 ChangeSet changeSet = new ChangeSet();
1223                 changeSet.setAuthor( ContinuumBuildAgentUtil.getChangeSetAuthor( map ) );
1224                 changeSet.setComment( ContinuumBuildAgentUtil.getChangeSetComment( map ) );
1225                 changeSet.setDate( ContinuumBuildAgentUtil.getChangeSetDate( map ) );
1226                 setChangeFiles( changeSet, map );
1227                 scmResult.addChange( changeSet );
1228             }
1229         }
1230 
1231         return scmResult;
1232     }
1233 
1234     private void setChangeFiles( ChangeSet changeSet, Map<String, Object> context )
1235     {
1236         List<Map<String, Object>> files = ContinuumBuildAgentUtil.getChangeSetFiles( context );
1237 
1238         if ( files != null )
1239         {
1240             for ( Map<String, Object> map : files )
1241             {
1242                 ChangeFile changeFile = new ChangeFile();
1243                 changeFile.setName( ContinuumBuildAgentUtil.getChangeFileName( map ) );
1244                 changeFile.setRevision( ContinuumBuildAgentUtil.getChangeFileRevision( map ) );
1245                 changeFile.setStatus( ContinuumBuildAgentUtil.getChangeFileStatus( map ) );
1246 
1247                 changeSet.addFile( changeFile );
1248             }
1249         }
1250     }
1251 
1252     private PrepareBuildProjectsTask createPrepareBuildProjectsTask( List<BuildContext> buildContexts )
1253         throws ContinuumBuildAgentException
1254     {
1255         if ( buildContexts != null && buildContexts.size() > 0 )
1256         {
1257             BuildContext context = buildContexts.get( 0 );
1258             return new PrepareBuildProjectsTask( buildContexts, new BuildTrigger( context.getTrigger(),
1259                                                                                   context.getUsername() ),
1260                                                  context.getProjectGroupId(), context.getScmRootAddress(),
1261                                                  context.getScmRootId() );
1262         }
1263         else
1264         {
1265             log.info( "Nothing to build" );
1266             return null;
1267         }
1268     }
1269 
1270     private int[] listToIntArray( List<String> strings )
1271     {
1272         if ( strings == null || strings.isEmpty() )
1273         {
1274             return new int[0];
1275         }
1276         int[] array = new int[0];
1277         for ( String intString : strings )
1278         {
1279             array = ArrayUtils.add( array, Integer.parseInt( intString ) );
1280         }
1281         return array;
1282     }
1283 }