View Javadoc

1   package org.apache.maven.continuum.xmlrpc.server;
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 net.sf.dozer.util.mapping.DozerBeanMapperSingletonWrapper;
23  import net.sf.dozer.util.mapping.MapperIF;
24  import org.apache.commons.lang.StringEscapeUtils;
25  import org.apache.commons.lang.StringUtils;
26  import org.apache.continuum.buildagent.NoBuildAgentException;
27  import org.apache.continuum.buildagent.NoBuildAgentInGroupException;
28  import org.apache.continuum.builder.distributed.manager.DistributedBuildManager;
29  import org.apache.continuum.buildmanager.BuildManagerException;
30  import org.apache.continuum.buildmanager.BuildsManager;
31  import org.apache.continuum.configuration.BuildAgentConfigurationException;
32  import org.apache.continuum.configuration.ContinuumConfigurationException;
33  import org.apache.continuum.dao.SystemConfigurationDao;
34  import org.apache.continuum.purge.ContinuumPurgeManagerException;
35  import org.apache.continuum.purge.PurgeConfigurationServiceException;
36  import org.apache.continuum.repository.RepositoryServiceException;
37  import org.apache.continuum.utils.release.ReleaseUtil;
38  import org.apache.continuum.xmlrpc.release.ContinuumReleaseResult;
39  import org.apache.continuum.xmlrpc.repository.DirectoryPurgeConfiguration;
40  import org.apache.continuum.xmlrpc.repository.LocalRepository;
41  import org.apache.continuum.xmlrpc.repository.RepositoryPurgeConfiguration;
42  import org.apache.continuum.xmlrpc.utils.BuildTrigger;
43  import org.apache.maven.continuum.Continuum;
44  import org.apache.maven.continuum.ContinuumException;
45  import org.apache.maven.continuum.builddefinition.BuildDefinitionServiceException;
46  import org.apache.maven.continuum.configuration.ConfigurationException;
47  import org.apache.maven.continuum.configuration.ConfigurationService;
48  import org.apache.maven.continuum.configuration.ConfigurationStoringException;
49  import org.apache.maven.continuum.execution.ContinuumBuildExecutorConstants;
50  import org.apache.maven.continuum.installation.InstallationException;
51  import org.apache.maven.continuum.installation.InstallationService;
52  import org.apache.maven.continuum.project.ContinuumProjectState;
53  import org.apache.maven.continuum.project.builder.ContinuumProjectBuildingResult;
54  import org.apache.maven.continuum.security.ContinuumRoleConstants;
55  import org.apache.maven.continuum.store.ContinuumStoreException;
56  import org.apache.maven.continuum.xmlrpc.project.AddingResult;
57  import org.apache.maven.continuum.xmlrpc.project.BuildAgentConfiguration;
58  import org.apache.maven.continuum.xmlrpc.project.BuildAgentGroupConfiguration;
59  import org.apache.maven.continuum.xmlrpc.project.BuildDefinition;
60  import org.apache.maven.continuum.xmlrpc.project.BuildDefinitionTemplate;
61  import org.apache.maven.continuum.xmlrpc.project.BuildProjectTask;
62  import org.apache.maven.continuum.xmlrpc.project.BuildResult;
63  import org.apache.maven.continuum.xmlrpc.project.BuildResultSummary;
64  import org.apache.maven.continuum.xmlrpc.project.Project;
65  import org.apache.maven.continuum.xmlrpc.project.ProjectGroup;
66  import org.apache.maven.continuum.xmlrpc.project.ProjectGroupSummary;
67  import org.apache.maven.continuum.xmlrpc.project.ProjectNotifier;
68  import org.apache.maven.continuum.xmlrpc.project.ProjectScmRoot;
69  import org.apache.maven.continuum.xmlrpc.project.ProjectSummary;
70  import org.apache.maven.continuum.xmlrpc.project.ReleaseListenerSummary;
71  import org.apache.maven.continuum.xmlrpc.project.Schedule;
72  import org.apache.maven.continuum.xmlrpc.system.Installation;
73  import org.apache.maven.continuum.xmlrpc.system.Profile;
74  import org.apache.maven.continuum.xmlrpc.system.SystemConfiguration;
75  import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
76  import org.codehaus.plexus.redback.authorization.AuthorizationException;
77  import org.codehaus.plexus.redback.role.RoleManager;
78  import org.codehaus.plexus.redback.role.RoleManagerException;
79  import org.slf4j.Logger;
80  import org.slf4j.LoggerFactory;
81  
82  import java.io.File;
83  import java.lang.reflect.Field;
84  import java.util.ArrayList;
85  import java.util.Arrays;
86  import java.util.Collection;
87  import java.util.HashMap;
88  import java.util.List;
89  import java.util.Map;
90  import java.util.Properties;
91  import java.util.Set;
92  
93  /**
94   * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
95   * @version $Id: ContinuumServiceImpl.java 1420496 2012-12-12 00:17:52Z brett $
96   * @plexus.component role="org.apache.maven.continuum.xmlrpc.server.ContinuumXmlRpcComponent" role-hint="org.apache.maven.continuum.xmlrpc.ContinuumService"
97   */
98  public class ContinuumServiceImpl
99      extends AbstractContinuumSecureService
100 {
101     private static final String NAME_VALID_EXPRESSION = "[A-Za-z0-9_.\\s\\-():\\/,]*";
102 
103     private static final String DIRECTORY_VALID_EXPRESSION = "[A-Za-z0-9_/\\s:.\\\\-]*";
104 
105     private static final String URL_VALID_EXPRESSION = "[A-Za-z0-9_.@:/-]*";
106 
107     private static final String PROJECT_VERSION_VALID_EXPRESSION = "[a-zA-Z0-9.-]*";
108 
109     private static final String PROJECT_SCM_URL_VALID_EXPRESSION = "[a-zA-Z0-9_.:${}#~=@\\/|\\[\\]-]*";
110 
111     private static final String PROJECT_SCM_TAG_VALID_EXPRESSION = "[a-zA-Z0-9_.:@\\/|#~=\\[\\]-]*";
112 
113     private static final String PROJECT_ARTIFACT_ID_VALID_EXPRESSION = "[A-Za-z0-9\\-]*";
114 
115     private static final String PROJECT_EXECUTOR_OR_BUILDDEF_TYPE_VALID_EXPRESSION = "maven2|maven-1|ant|shell";
116 
117     private static final String SCHEDULE_CRON_VALID_EXPRESSION = "[A-Z0-9\\s*/,-?#]*";
118 
119     private static final String PROJECTGROUP_ID_VALID_EXPRESSION = "[a-zA-Z0-9_.\\s\\-]*";
120 
121     private static final String REPOSITORY_LAYOUT_VALID_EXPRESSION = "default|legacy";
122 
123     private static final String BUILD_DEFINITION_ARGUMENTS_VALID_EXPRESSION = "[A-Za-z0-9_./=,${}\":\\s\\\\-]*";
124 
125     private static final String BUILD_DEFINITION_GOALS_VALID_EXPRESSION = "[A-Za-z0-9_:\\s\\-]*";
126 
127     private static final String BUILD_DEFINITION_BUILD_FILE_VALID_EXPRESSION = "[A-Za-z0-9_.\\-/\\\\]*";
128 
129     private static final String INSTALLATION_VARNAME_VALID_EXPRESSION = "[A-Za-z][A-Za-z0-9_]*";
130 
131     private static final String INSTALLATION_VARVALUE_VALID_EXPRESSION = "(?:[~A-Za-z0-9_.:=${}\\\\/\\-+]|\\s|[()])*";
132 
133     private static final String INSTALLATION_TYPE_VALID_EXPRESSION = "jdk|maven2|maven1|ant|envvar";
134 
135     private static final String DIRECTORY_TYPE_VALID_EXPRESSION = "releases|buildOutput";
136 
137     private static final String NOTIFIER_TYPE_VALID_EXPRESSION = "irc|jabber|msn|mail|wagon";
138 
139     private static final String USERNAME_VALID_EXPRESSION = "[a-zA-Z_0-9\\-.@]*";
140 
141     private static final MapperIF mapper = DozerBeanMapperSingletonWrapper.getInstance();
142 
143     private final Logger logger = LoggerFactory.getLogger( ContinuumServiceImpl.class );
144 
145     /**
146      * @plexus.requirement
147      */
148     private Continuum continuum;
149 
150     /**
151      * @plexus.requirement
152      */
153     private SystemConfigurationDao systemConfigurationDao;
154 
155     /**
156      * @plexus.requirement role-hint="default"
157      */
158     private RoleManager roleManager;
159 
160     /**
161      * @plexus.requirement role-hint="parallel"
162      */
163     private BuildsManager parallelBuildsManager;
164 
165     /**
166      * @plexus.requirement
167      */
168     private DistributedBuildManager distributedBuildManager;
169 
170     public boolean ping()
171         throws ContinuumException
172     {
173         return true;
174     }
175 
176     // ----------------------------------------------------------------------
177     // Projects
178     // ----------------------------------------------------------------------
179 
180     public List<ProjectSummary> getProjects( int projectGroupId )
181         throws ContinuumException
182     {
183         checkViewProjectGroupAuthorization( getProjectGroupName( projectGroupId ) );
184 
185         List<ProjectSummary> projectsList = new ArrayList<ProjectSummary>();
186 
187         Collection<org.apache.maven.continuum.model.project.Project> projects = continuum.getProjectsInGroup(
188             projectGroupId );
189         if ( projects != null )
190         {
191             for ( org.apache.maven.continuum.model.project.Project project : projects )
192             {
193                 ProjectSummary ps = populateProjectSummary( project );
194                 projectsList.add( ps );
195             }
196         }
197         return projectsList;
198     }
199 
200     public ProjectSummary getProjectSummary( int projectId )
201         throws ContinuumException
202     {
203         org.apache.maven.continuum.model.project.Project project = continuum.getProject( projectId );
204 
205         checkViewProjectGroupAuthorization( project.getProjectGroup().getName() );
206 
207         return populateProjectSummary( project );
208     }
209 
210     public Project getProjectWithAllDetails( int projectId )
211         throws ContinuumException
212     {
213         org.apache.maven.continuum.model.project.Project project = continuum.getProjectWithAllDetails( projectId );
214 
215         checkViewProjectGroupAuthorization( project.getProjectGroup().getName() );
216 
217         return populateProject( project );
218     }
219 
220     public int removeProject( int projectId )
221         throws ContinuumException
222     {
223         ProjectSummary ps = getProjectSummary( projectId );
224 
225         checkRemoveProjectFromGroupAuthorization( ps.getProjectGroup().getName() );
226 
227         continuum.removeProject( projectId );
228 
229         return 0;
230     }
231 
232     public ProjectSummary updateProject( ProjectSummary project )
233         throws ContinuumException
234     {
235         if ( StringUtils.isNotBlank( project.getName() ) && !project.getName().matches( NAME_VALID_EXPRESSION ) )
236         //!GenericValidator.matchRegexp( project.getName(), NAME_VALID_EXPRESSION ) )
237         {
238             throw new ContinuumException( "Project Name contains invalid characters" );
239         }
240 
241         if ( StringUtils.isNotBlank( project.getScmTag() ) && !project.getScmTag().matches(
242             PROJECT_SCM_TAG_VALID_EXPRESSION ) )
243         {
244             throw new ContinuumException( "Project Scm Tag contains invalid characters" );
245         }
246 
247         if ( StringUtils.isNotBlank( project.getScmUrl() ) && !project.getScmUrl().matches(
248             PROJECT_SCM_URL_VALID_EXPRESSION ) )
249         {
250             throw new ContinuumException( "Project Scm Url contains invalid characters" );
251         }
252 
253         if ( StringUtils.isNotBlank( project.getVersion() ) && !project.getVersion().matches(
254             PROJECT_VERSION_VALID_EXPRESSION ) )
255         {
256             throw new ContinuumException( "Project Version contains invalid characters" );
257         }
258 
259         ProjectSummary ps = getProjectSummary( project.getId() );
260 
261         checkRemoveProjectFromGroupAuthorization( ps.getProjectGroup().getName() );
262 
263         org.apache.maven.continuum.model.project.Project p = continuum.getProject( project.getId() );
264 
265         p.setName( project.getName() );
266         p.setVersion( project.getVersion() );
267         p.setScmUrl( project.getScmUrl() );
268         p.setScmUseCache( project.isScmUseCache() );
269         p.setScmUsername( project.getScmUsername() );
270         p.setScmPassword( project.getScmPassword() );
271         p.setScmTag( project.getScmTag() );
272 
273         continuum.updateProject( p );
274 
275         return getProjectSummary( project.getId() );
276     }
277 
278     // ----------------------------------------------------------------------
279     // Projects Groups
280     // ----------------------------------------------------------------------
281 
282     public List<ProjectGroupSummary> getAllProjectGroups()
283         throws ContinuumException
284     {
285         Collection<org.apache.maven.continuum.model.project.ProjectGroup> pgList = continuum.getAllProjectGroups();
286         List<ProjectGroupSummary> result = new ArrayList<ProjectGroupSummary>();
287         for ( org.apache.maven.continuum.model.project.ProjectGroup projectGroup : pgList )
288         {
289             try
290             {
291                 if ( isAuthorized( ContinuumRoleConstants.CONTINUUM_VIEW_GROUP_OPERATION, projectGroup.getName() ) )
292                 {
293                     result.add( populateProjectGroupSummary( projectGroup ) );
294                 }
295             }
296             catch ( AuthorizationException e )
297             {
298                 throw new ContinuumException( "error authorizing request." );
299             }
300         }
301         return result;
302     }
303 
304     public ProjectGroup getProjectGroup( int projectGroupId )
305         throws ContinuumException
306     {
307         ProjectGroup result = null;
308         org.apache.maven.continuum.model.project.ProjectGroup projectGroup = continuum.getProjectGroup(
309             projectGroupId );
310         try
311         {
312             if ( isAuthorized( ContinuumRoleConstants.CONTINUUM_VIEW_GROUP_OPERATION, projectGroup.getName() ) )
313             {
314                 result = populateProjectGroupWithAllDetails( projectGroup );
315             }
316         }
317         catch ( AuthorizationException e )
318         {
319             throw new ContinuumException( "error authorizing request." );
320         }
321         return result;
322     }
323 
324     public List<ProjectGroup> getAllProjectGroupsWithAllDetails()
325         throws ContinuumException
326     {
327         Collection<org.apache.maven.continuum.model.project.ProjectGroup> pgList =
328             continuum.getAllProjectGroupsWithBuildDetails();
329         List<ProjectGroup> result = new ArrayList<ProjectGroup>();
330         for ( org.apache.maven.continuum.model.project.ProjectGroup projectGroup : pgList )
331         {
332             try
333             {
334                 if ( isAuthorized( ContinuumRoleConstants.CONTINUUM_VIEW_GROUP_OPERATION, projectGroup.getName() ) )
335                 {
336                     result.add( populateProjectGroupWithAllDetails( projectGroup ) );
337                 }
338             }
339             catch ( AuthorizationException e )
340             {
341                 throw new ContinuumException( "error authorizing request." );
342             }
343         }
344         return result;
345     }
346 
347     public List<ProjectGroup> getAllProjectGroupsWithProjects()
348         throws ContinuumException
349     {
350         return getAllProjectGroupsWithAllDetails();
351     }
352 
353     protected String getProjectGroupName( int projectGroupId )
354         throws ContinuumException
355     {
356         ProjectGroupSummary pgs = getPGSummary( projectGroupId );
357         return pgs.getName();
358     }
359 
360     private ProjectGroupSummary getPGSummary( int projectGroupId )
361         throws ContinuumException
362     {
363         org.apache.maven.continuum.model.project.ProjectGroup projectGroup = continuum.getProjectGroup(
364             projectGroupId );
365 
366         checkViewProjectGroupAuthorization( projectGroup.getName() );
367         return populateProjectGroupSummary( projectGroup );
368     }
369 
370     public ProjectGroupSummary getProjectGroupSummary( int projectGroupId )
371         throws ContinuumException
372     {
373         checkViewProjectGroupAuthorization( getProjectGroupName( projectGroupId ) );
374 
375         org.apache.maven.continuum.model.project.ProjectGroup projectGroup = continuum.getProjectGroup(
376             projectGroupId );
377         return populateProjectGroupSummary( projectGroup );
378     }
379 
380     public ProjectGroup getProjectGroupWithProjects( int projectGroupId )
381         throws ContinuumException
382     {
383         checkViewProjectGroupAuthorization( getProjectGroupName( projectGroupId ) );
384 
385         org.apache.maven.continuum.model.project.ProjectGroup projectGroup = continuum.getProjectGroupWithProjects(
386             projectGroupId );
387         return populateProjectGroupWithAllDetails( projectGroup );
388     }
389 
390     public int removeProjectGroup( int projectGroupId )
391         throws ContinuumException
392     {
393         checkRemoveProjectGroupAuthorization( getProjectGroupName( projectGroupId ) );
394 
395         continuum.removeProjectGroup( projectGroupId );
396         return 0;
397     }
398 
399     public ProjectGroupSummary updateProjectGroup( ProjectGroupSummary projectGroup )
400         throws ContinuumException
401     {
402         if ( projectGroup == null )
403         {
404             return null;
405         }
406 
407         checkModifyProjectGroupAuthorization( getProjectGroupName( projectGroup.getId() ) );
408 
409         if ( StringUtils.isEmpty( projectGroup.getName() ) )
410         {
411             throw new ContinuumException( "project group name is required" );
412         }
413         else if ( StringUtils.isEmpty( projectGroup.getName().trim() ) )
414         {
415             throw new ContinuumException( "project group name can't be spaces" );
416         }
417 
418         if ( !projectGroup.getName().matches( NAME_VALID_EXPRESSION ) )
419         {
420             throw new ContinuumException( "ProjectGroup Name contains invalid characters" );
421         }
422 
423         org.apache.maven.continuum.model.project.ProjectGroup pg = continuum.getProjectGroupWithProjects(
424             projectGroup.getId() );
425 
426         // need to administer roles since they are based off of this
427         // todo convert everything like to work off of string keys
428         if ( !projectGroup.getName().equals( pg.getName() ) )
429         {
430             try
431             {
432                 roleManager.updateRole( "project-administrator", pg.getName(), projectGroup.getName() );
433                 roleManager.updateRole( "project-developer", pg.getName(), projectGroup.getName() );
434                 roleManager.updateRole( "project-user", pg.getName(), projectGroup.getName() );
435 
436                 pg.setName( projectGroup.getName() );
437             }
438             catch ( RoleManagerException e )
439             {
440                 throw new ContinuumException( "unable to rename the project group", e );
441             }
442         }
443 
444         pg.setDescription( StringEscapeUtils.escapeXml( projectGroup.getDescription() ) );
445 
446         org.apache.continuum.model.repository.LocalRepository repo =
447             new org.apache.continuum.model.repository.LocalRepository();
448         pg.setLocalRepository( populateLocalRepository( projectGroup.getLocalRepository(), repo ) );
449 
450         continuum.updateProjectGroup( pg );
451         return getProjectGroupSummary( projectGroup.getId() );
452     }
453 
454     public ProjectGroupSummary addProjectGroup( String groupName, String groupId, String description )
455         throws Exception
456     {
457         if ( StringUtils.isNotBlank( groupId ) && !groupId.matches( PROJECTGROUP_ID_VALID_EXPRESSION ) )
458         {
459             throw new ContinuumException( "ProjectGroup Id contains invalid characters" );
460         }
461 
462         if ( StringUtils.isNotBlank( groupName ) && !groupName.matches( NAME_VALID_EXPRESSION ) )
463         {
464             throw new ContinuumException( "ProjectGroup Name contains invalid characters" );
465         }
466 
467         org.apache.maven.continuum.model.project.ProjectGroup pg =
468             new org.apache.maven.continuum.model.project.ProjectGroup();
469         pg.setName( groupName );
470         pg.setGroupId( groupId );
471         pg.setDescription( StringEscapeUtils.escapeXml( description ) );
472         continuum.addProjectGroup( pg );
473         return populateProjectGroupSummary( continuum.getProjectGroupByGroupId( groupId ) );
474     }
475 
476     public ProjectNotifier getNotifier( int projectid, int notifierId )
477         throws ContinuumException
478     {
479         return populateProjectNotifier( continuum.getNotifier( projectid, notifierId ) );
480     }
481 
482     public ProjectNotifier updateNotifier( int projectid, ProjectNotifier newNotifier )
483         throws ContinuumException
484     {
485         if ( StringUtils.isNotBlank( newNotifier.getType() ) && !newNotifier.getType().matches(
486             NOTIFIER_TYPE_VALID_EXPRESSION ) )
487         {
488             throw new ContinuumException( "Notifier Type can only be 'irc, jabber, msn, mail or wagon" );
489         }
490 
491         org.apache.maven.continuum.model.project.ProjectNotifier notifier = continuum.getNotifier( projectid,
492                                                                                                    newNotifier.getId() );
493         notifier.setConfiguration( newNotifier.getConfiguration() );
494         notifier.setFrom( newNotifier.getFrom() );
495         notifier.setRecipientType( newNotifier.getRecipientType() );
496         notifier.setType( newNotifier.getType() );
497         notifier.setEnabled( newNotifier.isEnabled() );
498         notifier.setSendOnError( newNotifier.isSendOnError() );
499         notifier.setSendOnFailure( newNotifier.isSendOnFailure() );
500         notifier.setSendOnSuccess( newNotifier.isSendOnSuccess() );
501         notifier.setSendOnWarning( newNotifier.isSendOnWarning() );
502         return populateProjectNotifier( continuum.updateNotifier( projectid, notifier ) );
503     }
504 
505     public ProjectNotifier addNotifier( int projectid, ProjectNotifier newNotifier )
506         throws ContinuumException
507     {
508         if ( StringUtils.isNotBlank( newNotifier.getType() ) && !newNotifier.getType().matches(
509             NOTIFIER_TYPE_VALID_EXPRESSION ) )
510         {
511             throw new ContinuumException( "Notifier Type can only be 'irc, jabber, msn, mail or wagon'" );
512         }
513 
514         org.apache.maven.continuum.model.project.ProjectNotifier notifier =
515             new org.apache.maven.continuum.model.project.ProjectNotifier();
516         notifier.setConfiguration( newNotifier.getConfiguration() );
517         notifier.setFrom( newNotifier.getFrom() );
518         notifier.setRecipientType( newNotifier.getRecipientType() );
519         notifier.setType( newNotifier.getType() );
520         notifier.setEnabled( newNotifier.isEnabled() );
521         notifier.setSendOnError( newNotifier.isSendOnError() );
522         notifier.setSendOnFailure( newNotifier.isSendOnFailure() );
523         notifier.setSendOnSuccess( newNotifier.isSendOnSuccess() );
524         notifier.setSendOnWarning( newNotifier.isSendOnWarning() );
525         return populateProjectNotifier( continuum.addNotifier( projectid, notifier ) );
526     }
527 
528     public int removeNotifier( int projectid, int notifierId )
529         throws ContinuumException
530     {
531         continuum.removeNotifier( projectid, notifierId );
532         return 0;
533     }
534 
535     public ProjectNotifier getGroupNotifier( int projectgroupid, int notifierId )
536         throws ContinuumException
537     {
538         return populateProjectNotifier( continuum.getGroupNotifier( projectgroupid, notifierId ) );
539     }
540 
541     public ProjectNotifier updateGroupNotifier( int projectgroupid, ProjectNotifier newNotifier )
542         throws ContinuumException
543     {
544         if ( StringUtils.isNotBlank( newNotifier.getType() ) && !newNotifier.getType().matches(
545             NOTIFIER_TYPE_VALID_EXPRESSION ) )
546         {
547             throw new ContinuumException( "Notifier Type can only be 'irc, jabber, msn, mail, or wagon" );
548         }
549 
550         org.apache.maven.continuum.model.project.ProjectNotifier notifier = continuum.getGroupNotifier( projectgroupid,
551                                                                                                         newNotifier.getId() );
552         notifier.setConfiguration( newNotifier.getConfiguration() );
553         notifier.setFrom( newNotifier.getFrom() );
554         notifier.setRecipientType( newNotifier.getRecipientType() );
555         notifier.setType( newNotifier.getType() );
556         notifier.setEnabled( newNotifier.isEnabled() );
557         notifier.setSendOnError( newNotifier.isSendOnError() );
558         notifier.setSendOnFailure( newNotifier.isSendOnFailure() );
559         notifier.setSendOnSuccess( newNotifier.isSendOnSuccess() );
560         notifier.setSendOnWarning( newNotifier.isSendOnWarning() );
561         return populateProjectNotifier( continuum.updateGroupNotifier( projectgroupid, notifier ) );
562     }
563 
564     public ProjectNotifier addGroupNotifier( int projectgroupid, ProjectNotifier newNotifier )
565         throws ContinuumException
566     {
567         org.apache.maven.continuum.model.project.ProjectNotifier notifier =
568             new org.apache.maven.continuum.model.project.ProjectNotifier();
569 
570         if ( StringUtils.isNotBlank( newNotifier.getType() ) && !newNotifier.getType().matches(
571             NOTIFIER_TYPE_VALID_EXPRESSION ) )
572         {
573             throw new ContinuumException( "Notifier Type can only be 'irc, jabber, msn, mail or wagon" );
574         }
575 
576         notifier.setConfiguration( newNotifier.getConfiguration() );
577         notifier.setFrom( newNotifier.getFrom() );
578         notifier.setRecipientType( newNotifier.getRecipientType() );
579         notifier.setType( newNotifier.getType() );
580         notifier.setEnabled( newNotifier.isEnabled() );
581         notifier.setSendOnError( newNotifier.isSendOnError() );
582         notifier.setSendOnFailure( newNotifier.isSendOnFailure() );
583         notifier.setSendOnSuccess( newNotifier.isSendOnSuccess() );
584         notifier.setSendOnWarning( newNotifier.isSendOnWarning() );
585         return populateProjectNotifier( continuum.addGroupNotifier( projectgroupid, notifier ) );
586     }
587 
588     public int removeGroupNotifier( int projectgroupid, int notifierId )
589         throws ContinuumException
590     {
591         continuum.removeGroupNotifier( projectgroupid, notifierId );
592         return 0;
593     }
594 
595     // ----------------------------------------------------------------------
596     // Build Definitions
597     // ----------------------------------------------------------------------
598 
599     public List<BuildDefinition> getBuildDefinitionsForProject( int projectId )
600         throws ContinuumException
601     {
602         ProjectSummary ps = getProjectSummary( projectId );
603 
604         checkViewProjectGroupAuthorization( ps.getProjectGroup().getName() );
605 
606         List<org.apache.maven.continuum.model.project.BuildDefinition> bds = continuum.getBuildDefinitionsForProject(
607             projectId );
608 
609         List<BuildDefinition> result = new ArrayList<BuildDefinition>();
610         for ( org.apache.maven.continuum.model.project.BuildDefinition bd : bds )
611         {
612             result.add( populateBuildDefinition( bd ) );
613         }
614         return result;
615     }
616 
617     public List<BuildDefinition> getBuildDefinitionsForProjectGroup( int projectGroupId )
618         throws ContinuumException
619     {
620         checkViewProjectGroupAuthorization( getProjectGroupName( projectGroupId ) );
621 
622         List<org.apache.maven.continuum.model.project.BuildDefinition> bds =
623             continuum.getBuildDefinitionsForProjectGroup( projectGroupId );
624 
625         List<BuildDefinition> result = new ArrayList<BuildDefinition>();
626         for ( org.apache.maven.continuum.model.project.BuildDefinition bd : bds )
627         {
628             result.add( populateBuildDefinition( bd ) );
629         }
630         return result;
631     }
632 
633     public BuildDefinition getBuildDefinition( int buildDefinitionId )
634         throws Exception
635     {
636         org.apache.maven.continuum.model.project.BuildDefinition bd = continuum.getBuildDefinition( buildDefinitionId );
637 
638         return populateBuildDefinition( bd );
639     }
640 
641     public int removeBuildDefinitionFromProjectGroup( int projectGroupId, int buildDefinitionId )
642         throws ContinuumException
643     {
644         checkRemoveGroupBuildDefinitionAuthorization( getProjectGroupName( projectGroupId ) );
645 
646         continuum.removeBuildDefinitionFromProjectGroup( projectGroupId, buildDefinitionId );
647         return 0;
648     }
649 
650     public BuildDefinition updateBuildDefinitionForProject( int projectId, BuildDefinition buildDef )
651         throws ContinuumException
652     {
653         ProjectSummary ps = getProjectSummary( projectId );
654 
655         checkModifyProjectBuildDefinitionAuthorization( ps.getProjectGroup().getName() );
656         org.apache.maven.continuum.model.project.BuildDefinition newbd = continuum.getBuildDefinition(
657             buildDef.getId() );
658         org.apache.maven.continuum.model.project.BuildDefinition bd = populateBuildDefinition( buildDef, newbd );
659         bd = continuum.updateBuildDefinitionForProject( projectId, bd );
660         return populateBuildDefinition( bd );
661     }
662 
663     public BuildDefinition updateBuildDefinitionForProjectGroup( int projectGroupId, BuildDefinition buildDef )
664         throws ContinuumException
665     {
666         checkModifyGroupBuildDefinitionAuthorization( getProjectGroupName( projectGroupId ) );
667         org.apache.maven.continuum.model.project.BuildDefinition newbd = continuum.getBuildDefinition(
668             buildDef.getId() );
669         org.apache.maven.continuum.model.project.BuildDefinition bd = populateBuildDefinition( buildDef, newbd );
670         bd = continuum.updateBuildDefinitionForProjectGroup( projectGroupId, bd );
671         return populateBuildDefinition( bd );
672     }
673 
674     public BuildDefinition addBuildDefinitionToProject( int projectId, BuildDefinition buildDef )
675         throws ContinuumException
676     {
677         checkAddProjectBuildDefinitionAuthorization( getProjectSummary( projectId ).getProjectGroup().getName() );
678 
679         if ( buildDef.getSchedule() == null )
680         {
681             throw new ContinuumException( "The schedule can't be null." );
682         }
683         org.apache.maven.continuum.model.project.BuildDefinition newbd =
684             new org.apache.maven.continuum.model.project.BuildDefinition();
685         org.apache.maven.continuum.model.project.BuildDefinition bd = populateBuildDefinition( buildDef, newbd );
686         bd = continuum.addBuildDefinitionToProject( projectId, bd );
687         return populateBuildDefinition( bd );
688     }
689 
690     public BuildDefinition addBuildDefinitionToProjectGroup( int projectGroupId, BuildDefinition buildDef )
691         throws ContinuumException
692     {
693         checkAddGroupBuildDefinitionAuthorization( getPGSummary( projectGroupId ).getName() );
694 
695         if ( buildDef.getSchedule() == null )
696         {
697             throw new ContinuumException( "The schedule can't be null." );
698         }
699         org.apache.maven.continuum.model.project.BuildDefinition newbd =
700             new org.apache.maven.continuum.model.project.BuildDefinition();
701         org.apache.maven.continuum.model.project.BuildDefinition bd = populateBuildDefinition( buildDef, newbd );
702         bd = continuum.addBuildDefinitionToProjectGroup( projectGroupId, bd );
703         return populateBuildDefinition( bd );
704     }
705 
706     public List<BuildDefinitionTemplate> getBuildDefinitionTemplates()
707         throws Exception
708     {
709         checkManageBuildDefinitionTemplatesAuthorization();
710         List<org.apache.maven.continuum.model.project.BuildDefinitionTemplate> bdts =
711             continuum.getBuildDefinitionService().getAllBuildDefinitionTemplate();
712 
713         List<BuildDefinitionTemplate> result = new ArrayList<BuildDefinitionTemplate>();
714         for ( org.apache.maven.continuum.model.project.BuildDefinitionTemplate bdt : bdts )
715         {
716             result.add( populateBuildDefinitionTemplate( bdt ) );
717         }
718         return result;
719     }
720 
721     // ----------------------------------------------------------------------
722     // Building
723     // ----------------------------------------------------------------------
724 
725     // TODO: delete this since it does exactly the same as buildProject( int projectId )
726     public int addProjectToBuildQueue( int projectId )
727         throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
728     {
729         ProjectSummary ps = getProjectSummary( projectId );
730         checkBuildProjectInGroupAuthorization( ps.getProjectGroup().getName() );
731 
732         continuum.buildProject( projectId, new org.apache.continuum.utils.build.BuildTrigger(
733             ContinuumProjectState.TRIGGER_SCHEDULED, "" ) );
734         return 0;
735     }
736 
737     // TODO: delete this since it does exactly the same as buildProject( int projectId, int buildDefinitionId );
738     public int addProjectToBuildQueue( int projectId, int buildDefinitionId )
739         throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
740     {
741         ProjectSummary ps = getProjectSummary( projectId );
742         checkBuildProjectInGroupAuthorization( ps.getProjectGroup().getName() );
743 
744         continuum.buildProject( projectId, buildDefinitionId, new org.apache.continuum.utils.build.BuildTrigger(
745             ContinuumProjectState.TRIGGER_SCHEDULED, "" ) );
746         return 0;
747     }
748 
749     public int buildProject( int projectId )
750         throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
751     {
752         ProjectSummary ps = getProjectSummary( projectId );
753         checkBuildProjectInGroupAuthorization( ps.getProjectGroup().getName() );
754 
755         continuum.buildProject( projectId, new org.apache.continuum.utils.build.BuildTrigger(
756             ContinuumProjectState.TRIGGER_SCHEDULED, "" ) );
757         return 0;
758     }
759 
760     public int buildProject( int projectId, int buildDefinitionId )
761         throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
762     {
763         ProjectSummary ps = getProjectSummary( projectId );
764         checkBuildProjectInGroupAuthorization( ps.getProjectGroup().getName() );
765 
766         buildProjectWithBuildDefinition( projectId, buildDefinitionId,
767                                          new org.apache.continuum.utils.build.BuildTrigger(
768                                              ContinuumProjectState.TRIGGER_SCHEDULED, "" ) );
769         return 0;
770     }
771 
772     public int buildProject( int projectId, BuildTrigger xmlrpcBuildTrigger )
773         throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
774     {
775         ProjectSummary ps = getProjectSummary( projectId );
776         checkBuildProjectInGroupAuthorization( ps.getProjectGroup().getName() );
777 
778         org.apache.continuum.utils.build.BuildTrigger buildTrigger = populateBuildTrigger( xmlrpcBuildTrigger );
779 
780         continuum.buildProject( projectId, buildTrigger );
781         return 0;
782     }
783 
784     public int buildProject( int projectId, int buildDefinitionId, BuildTrigger xmlrpcBuildTrigger )
785         throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
786     {
787         ProjectSummary projectSummary = getProjectSummary( projectId );
788         checkBuildProjectInGroupAuthorization( projectSummary.getProjectGroup().getName() );
789 
790         org.apache.continuum.utils.build.BuildTrigger buildTrigger = populateBuildTrigger( xmlrpcBuildTrigger );
791         buildProjectWithBuildDefinition( projectId, buildDefinitionId, buildTrigger );
792 
793         return 0;
794     }
795 
796     public int buildGroup( int projectGroupId )
797         throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
798     {
799         ProjectGroupSummary pg = getProjectGroupSummary( projectGroupId );
800         checkBuildProjectInGroupAuthorization( pg.getName() );
801 
802         continuum.buildProjectGroup( projectGroupId, new org.apache.continuum.utils.build.BuildTrigger(
803             ContinuumProjectState.TRIGGER_SCHEDULED, "" ) );
804 
805         return 0;
806     }
807 
808     public int buildGroup( int projectGroupId, int buildDefinitionId )
809         throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
810     {
811         ProjectGroupSummary pg = getProjectGroupSummary( projectGroupId );
812         checkBuildProjectInGroupAuthorization( pg.getName() );
813 
814         continuum.buildProjectGroupWithBuildDefinition( projectGroupId, buildDefinitionId,
815                                                         new org.apache.continuum.utils.build.BuildTrigger(
816                                                             ContinuumProjectState.TRIGGER_SCHEDULED, "" ) );
817 
818         return 0;
819     }
820 
821     // ----------------------------------------------------------------------
822     // SCM roots
823     // ----------------------------------------------------------------------
824 
825     public List<ProjectScmRoot> getProjectScmRootByProjectGroup( int projectGroupId )
826         throws ContinuumException
827     {
828         checkViewProjectGroupAuthorization( getProjectGroupName( projectGroupId ) );
829 
830         List<org.apache.continuum.model.project.ProjectScmRoot> projectScmRoots =
831             continuum.getProjectScmRootByProjectGroup( projectGroupId );
832 
833         List<ProjectScmRoot> result = new ArrayList<ProjectScmRoot>( projectScmRoots.size() );
834         for ( org.apache.continuum.model.project.ProjectScmRoot projectScmRoot : projectScmRoots )
835         {
836             result.add( populateProjectScmRoot( projectScmRoot ) );
837         }
838 
839         return result;
840     }
841 
842     public ProjectScmRoot getProjectScmRootByProject( int projectId )
843         throws ContinuumException
844     {
845         org.apache.continuum.model.project.ProjectScmRoot projectScmRoot = continuum.getProjectScmRootByProject(
846             projectId );
847 
848         checkViewProjectGroupAuthorization( projectScmRoot.getProjectGroup().getName() );
849 
850         return populateProjectScmRoot( projectScmRoot );
851     }
852 
853     // ----------------------------------------------------------------------
854     // Build Results
855     // ----------------------------------------------------------------------
856 
857     public BuildResult getLatestBuildResult( int projectId )
858         throws ContinuumException
859     {
860         ProjectSummary ps = getProjectSummary( projectId );
861         checkViewProjectGroupAuthorization( ps.getProjectGroup().getName() );
862 
863         org.apache.maven.continuum.model.project.BuildResult buildResult = continuum.getLatestBuildResultForProject(
864             projectId );
865 
866         if ( buildResult != null )
867         {
868             return getBuildResult( projectId, buildResult.getId() );
869         }
870 
871         return null;
872     }
873 
874     public BuildResult getBuildResult( int projectId, int buildId )
875         throws ContinuumException
876     {
877         ProjectSummary ps = getProjectSummary( projectId );
878         checkViewProjectGroupAuthorization( ps.getProjectGroup().getName() );
879 
880         return populateBuildResult( continuum.getBuildResult( buildId ) );
881     }
882 
883     public List<BuildResultSummary> getBuildResultsForProject( int projectId )
884         throws ContinuumException
885     {
886         ProjectSummary ps = getProjectSummary( projectId );
887         checkViewProjectGroupAuthorization( ps.getProjectGroup().getName() );
888 
889         List<BuildResultSummary> result = new ArrayList<BuildResultSummary>();
890         Collection<org.apache.maven.continuum.model.project.BuildResult> buildResults =
891             continuum.getBuildResultsForProject( projectId );
892         if ( buildResults != null )
893         {
894             for ( org.apache.maven.continuum.model.project.BuildResult buildResult : buildResults )
895             {
896                 BuildResultSummary br = populateBuildResultSummary( buildResult );
897                 result.add( br );
898             }
899         }
900 
901         return result;
902     }
903 
904     public int removeBuildResult( BuildResult br )
905         throws ContinuumException
906     {
907         checkModifyProjectGroupAuthorization( getProjectSummary(
908             br.getProject().getId() ).getProjectGroup().getName() );
909         continuum.removeBuildResult( br.getId() );
910         return 0;
911     }
912 
913     public String getBuildOutput( int projectId, int buildId )
914         throws ContinuumException
915     {
916         ProjectSummary ps = getProjectSummary( projectId );
917         checkViewProjectGroupAuthorization( ps.getProjectGroup().getName() );
918 
919         return continuum.getBuildOutput( projectId, buildId );
920     }
921 
922     // ----------------------------------------------------------------------
923     // Maven 2.x projects
924     // ----------------------------------------------------------------------
925 
926     public AddingResult addMavenTwoProject( String url )
927         throws ContinuumException
928     {
929         checkAddProjectGroupAuthorization();
930 
931         ContinuumProjectBuildingResult result = continuum.addMavenTwoProject( url );
932         return populateAddingResult( result );
933     }
934 
935     public AddingResult addMavenTwoProject( String url, int projectGroupId )
936         throws ContinuumException
937     {
938         checkAddProjectToGroupAuthorization( getProjectGroupName( projectGroupId ) );
939 
940         ContinuumProjectBuildingResult result = continuum.addMavenTwoProject( url, projectGroupId );
941         return populateAddingResult( result );
942     }
943 
944     public AddingResult addMavenTwoProject( String url, int projectGroupId, boolean checkoutInSingleDirectory )
945         throws ContinuumException
946     {
947         checkAddProjectToGroupAuthorization( getProjectGroupName( projectGroupId ) );
948 
949         ContinuumProjectBuildingResult result;
950         try
951         {
952             result = continuum.addMavenTwoProject( url, projectGroupId, true, // checkProtocol
953                                                    false, // useCredentialsCache
954                                                    true, // recursiveProjects
955                                                    continuum.getBuildDefinitionService().getDefaultMavenTwoBuildDefinitionTemplate().getId(),
956                                                    checkoutInSingleDirectory );
957         }
958         catch ( BuildDefinitionServiceException e )
959         {
960             throw new ContinuumException( e.getMessage(), e );
961         }
962 
963         return populateAddingResult( result );
964     }
965 
966     public AddingResult addMavenTwoProjectAsSingleProject( String url, int projectGroupId )
967         throws Exception
968     {
969         checkAddProjectToGroupAuthorization( getProjectGroupName( projectGroupId ) );
970 
971         ContinuumProjectBuildingResult result;
972         try
973         {
974             result = continuum.addMavenTwoProject( url, projectGroupId, true, // checkProtocol
975                                                    false, // useCredentialsCache
976                                                    false, // recursiveProjects
977                                                    continuum.getBuildDefinitionService().getDefaultMavenTwoBuildDefinitionTemplate().getId(),
978                                                    true ); // a multi-module project added as a single project is always
979             // checked out
980             // in a single directory, regardless the value set for
981             // checkoutInSingleDirectory
982             // variable
983         }
984         catch ( BuildDefinitionServiceException e )
985         {
986             throw new ContinuumException( e.getMessage(), e );
987         }
988 
989         return populateAddingResult( result );
990     }
991 
992     public AddingResult addMavenTwoProject( String url, int projectGroupId, boolean checkProtocol,
993                                             boolean useCredentialsCache, boolean recursiveProjects,
994                                             boolean checkoutInSingleDirectory )
995         throws Exception
996     {
997         checkAddProjectToGroupAuthorization( getProjectGroupName( projectGroupId ) );
998 
999         ContinuumProjectBuildingResult result;
1000         try
1001         {
1002             result = continuum.addMavenTwoProject( url, projectGroupId, checkProtocol, useCredentialsCache,
1003                                                    recursiveProjects,
1004                                                    continuum.getBuildDefinitionService().getDefaultMavenTwoBuildDefinitionTemplate().getId(),
1005                                                    checkoutInSingleDirectory );
1006         }
1007         catch ( BuildDefinitionServiceException e )
1008         {
1009             throw new ContinuumException( e.getMessage(), e );
1010         }
1011 
1012         return populateAddingResult( result );
1013     }
1014 
1015     // ----------------------------------------------------------------------
1016     // Maven 1.x projects
1017     // ----------------------------------------------------------------------
1018 
1019     public AddingResult addMavenOneProject( String url, int projectGroupId )
1020         throws ContinuumException
1021     {
1022         checkAddProjectToGroupAuthorization( getProjectGroupName( projectGroupId ) );
1023 
1024         ContinuumProjectBuildingResult result = continuum.addMavenOneProject( url, projectGroupId );
1025         return populateAddingResult( result );
1026     }
1027 
1028     // ----------------------------------------------------------------------
1029     // Maven ANT projects
1030     // ----------------------------------------------------------------------
1031 
1032     public ProjectSummary addAntProject( ProjectSummary project, int projectGroupId )
1033         throws ContinuumException
1034     {
1035         checkAddProjectGroupAuthorization();
1036         org.apache.maven.continuum.model.project.Project newProject =
1037             new org.apache.maven.continuum.model.project.Project();
1038         int projectId = continuum.addProject( populateProject( project, newProject ),
1039                                               ContinuumBuildExecutorConstants.ANT_BUILD_EXECUTOR, projectGroupId );
1040         return getProjectSummary( projectId );
1041     }
1042 
1043     // ----------------------------------------------------------------------
1044     // Maven Shell projects
1045     // ----------------------------------------------------------------------
1046 
1047     public ProjectSummary addShellProject( ProjectSummary project, int projectGroupId )
1048         throws ContinuumException
1049     {
1050         checkAddProjectGroupAuthorization();
1051         org.apache.maven.continuum.model.project.Project newProject =
1052             new org.apache.maven.continuum.model.project.Project();
1053         int projectId = continuum.addProject( populateProject( project, newProject ),
1054                                               ContinuumBuildExecutorConstants.SHELL_BUILD_EXECUTOR, projectGroupId );
1055         return getProjectSummary( projectId );
1056     }
1057 
1058     // ----------------------------------------------------------------------
1059     // Schedules
1060     // ----------------------------------------------------------------------
1061 
1062     public List<Schedule> getSchedules()
1063         throws ContinuumException
1064     {
1065         checkManageSchedulesAuthorization();
1066         Collection schedules = continuum.getSchedules();
1067 
1068         List<Schedule> s = new ArrayList<Schedule>();
1069         for ( Object schedule : schedules )
1070         {
1071             s.add( populateSchedule( (org.apache.maven.continuum.model.project.Schedule) schedule ) );
1072         }
1073 
1074         return s;
1075     }
1076 
1077     public Schedule getSchedule( int scheduleId )
1078         throws ContinuumException
1079     {
1080         checkManageSchedulesAuthorization();
1081         return populateSchedule( continuum.getSchedule( scheduleId ) );
1082     }
1083 
1084     public Schedule updateSchedule( Schedule schedule )
1085         throws ContinuumException
1086     {
1087         checkManageSchedulesAuthorization();
1088         org.apache.maven.continuum.model.project.Schedule s = continuum.getSchedule( schedule.getId() );
1089         org.apache.maven.continuum.model.project.Schedule newSchedule = populateSchedule( schedule, s );
1090         org.apache.maven.continuum.model.project.Schedule storedSchedule = continuum.getSchedule( schedule.getId() );
1091         storedSchedule.setActive( newSchedule.isActive() );
1092         storedSchedule.setName( newSchedule.getName() );
1093         storedSchedule.setDescription( StringEscapeUtils.escapeXml( newSchedule.getDescription() ) );
1094         storedSchedule.setDelay( newSchedule.getDelay() );
1095         storedSchedule.setCronExpression( newSchedule.getCronExpression() );
1096         storedSchedule.setMaxJobExecutionTime( newSchedule.getMaxJobExecutionTime() );
1097         continuum.updateSchedule( storedSchedule );
1098 
1099         return populateSchedule( continuum.getScheduleByName( schedule.getName() ) );
1100     }
1101 
1102     public Schedule addSchedule( Schedule schedule )
1103         throws ContinuumException
1104     {
1105         checkManageSchedulesAuthorization();
1106         org.apache.maven.continuum.model.project.Schedule s = new org.apache.maven.continuum.model.project.Schedule();
1107         continuum.addSchedule( populateSchedule( schedule, s ) );
1108 
1109         return populateSchedule( continuum.getScheduleByName( schedule.getName() ) );
1110     }
1111 
1112     // ----------------------------------------------------------------------
1113     // Profiles
1114     // ----------------------------------------------------------------------
1115 
1116     public List<Profile> getProfiles()
1117         throws ContinuumException
1118     {
1119         checkManageProfilesAuthorization();
1120         Collection profiles = continuum.getProfileService().getAllProfiles();
1121 
1122         List<Profile> p = new ArrayList<Profile>();
1123         for ( Object profile : profiles )
1124         {
1125             p.add( populateProfile( (org.apache.maven.continuum.model.system.Profile) profile ) );
1126         }
1127 
1128         return p;
1129     }
1130 
1131     public Profile getProfile( int profileId )
1132         throws ContinuumException
1133     {
1134         checkManageProfilesAuthorization();
1135         return populateProfile( continuum.getProfileService().getProfile( profileId ) );
1136     }
1137 
1138     public Profile getProfileWithName( String profileName )
1139         throws ContinuumException
1140     {
1141         checkManageProfilesAuthorization();
1142         org.apache.maven.continuum.model.system.Profile profile = continuum.getProfileService().getProfileWithName(
1143             profileName );
1144         return profile != null ? populateProfile( profile ) : null;
1145     }
1146 
1147     public Profile addProfile( Profile profile )
1148         throws ContinuumException
1149     {
1150         org.apache.maven.continuum.model.system.Profile newProfile =
1151             new org.apache.maven.continuum.model.system.Profile();
1152 
1153         return populateProfile( continuum.getProfileService().addProfile( populateProfile( profile, newProfile ) ) );
1154     }
1155 
1156     public int updateProfile( Profile profile )
1157         throws ContinuumException
1158     {
1159         org.apache.maven.continuum.model.system.Profile newProfile = continuum.getProfileService().getProfile(
1160             profile.getId() );
1161 
1162         continuum.getProfileService().updateProfile( populateProfile( profile, newProfile ) );
1163         return 0;
1164     }
1165 
1166     public int deleteProfile( int profileId )
1167         throws ContinuumException
1168     {
1169 
1170         continuum.getProfileService().deleteProfile( profileId );
1171         return 0;
1172     }
1173 
1174     // ----------------------------------------------------------------------
1175     // Installations
1176     // ----------------------------------------------------------------------
1177 
1178     public List<Installation> getInstallations()
1179         throws ContinuumException
1180     {
1181         checkManageInstallationsAuthorization();
1182         try
1183         {
1184             List<org.apache.maven.continuum.model.system.Installation> installs =
1185                 continuum.getInstallationService().getAllInstallations();
1186 
1187             List<Installation> i = new ArrayList<Installation>();
1188             for ( Object install : installs )
1189             {
1190                 i.add( populateInstallation( (org.apache.maven.continuum.model.system.Installation) install ) );
1191             }
1192             return i;
1193         }
1194         catch ( InstallationException e )
1195         {
1196             throw new ContinuumException( "Can't load installations", e );
1197         }
1198     }
1199 
1200     public List<Installation> getBuildAgentInstallations( String url )
1201         throws ContinuumException
1202     {
1203         try
1204         {
1205             List<org.apache.maven.continuum.model.system.Installation> buildAgentInstallations =
1206                 distributedBuildManager.getAvailableInstallations( url );
1207 
1208             List<Installation> convertedBuildAgentInstallations = new ArrayList<Installation>();
1209             for ( Object buildAgentInstallation : buildAgentInstallations )
1210             {
1211                 convertedBuildAgentInstallations.add( populateInstallation(
1212                     (org.apache.maven.continuum.model.system.Installation) buildAgentInstallation ) );
1213             }
1214             return convertedBuildAgentInstallations;
1215         }
1216         catch ( Exception e )
1217         {
1218             throw new ContinuumException( "Can't load installations", e );
1219         }
1220     }
1221 
1222     public Installation getInstallation( int installationId )
1223         throws ContinuumException
1224     {
1225         checkManageInstallationsAuthorization();
1226         try
1227         {
1228             org.apache.maven.continuum.model.system.Installation install =
1229                 continuum.getInstallationService().getInstallation( installationId );
1230             return populateInstallation( install );
1231         }
1232         catch ( InstallationException e )
1233         {
1234             throw new ContinuumException( "Can't load installations", e );
1235         }
1236     }
1237 
1238     public Installation getInstallation( String installationName )
1239         throws ContinuumException
1240     {
1241         checkManageInstallationsAuthorization();
1242         try
1243         {
1244             org.apache.maven.continuum.model.system.Installation install =
1245                 continuum.getInstallationService().getInstallation( installationName );
1246             return install != null ? populateInstallation( install ) : null;
1247         }
1248         catch ( InstallationException e )
1249         {
1250             throw new ContinuumException( "Can't load installations", e );
1251         }
1252     }
1253 
1254     public Installation addInstallation( Installation installation )
1255         throws ContinuumException
1256     {
1257         try
1258         {
1259             org.apache.maven.continuum.model.system.Installation newInstallation =
1260                 new org.apache.maven.continuum.model.system.Installation();
1261             return populateInstallation( continuum.getInstallationService().add( populateInstallation( installation,
1262                                                                                                        newInstallation ) ) );
1263         }
1264         catch ( InstallationException e )
1265         {
1266             throw new ContinuumException( "Can't delete installations", e );
1267         }
1268     }
1269 
1270     public int updateInstallation( Installation installation )
1271         throws ContinuumException
1272     {
1273         try
1274         {
1275             final org.apache.maven.continuum.model.system.Installation newInst =
1276                 continuum.getInstallationService().getInstallation( installation.getInstallationId() );
1277             continuum.getInstallationService().update( populateInstallation( installation, newInst ) );
1278             return 0;
1279         }
1280         catch ( InstallationException e )
1281         {
1282             throw new ContinuumException( "Can't delete installations", e );
1283         }
1284     }
1285 
1286     public int deleteInstallation( int installationId )
1287         throws ContinuumException
1288     {
1289         try
1290         {
1291             org.apache.maven.continuum.model.system.Installation installationTODelete =
1292                 continuum.getInstallationService().getInstallation( installationId );
1293             continuum.getInstallationService().delete( installationTODelete );
1294             return 0;
1295         }
1296         catch ( InstallationException e )
1297         {
1298             throw new ContinuumException( "Can't delete installations", e );
1299         }
1300     }
1301 
1302     // ----------------------------------------------------------------------
1303     // SystemConfigurationDao
1304     // ----------------------------------------------------------------------
1305 
1306     public SystemConfiguration getSystemConfiguration()
1307         throws ContinuumException
1308     {
1309         checkManageConfigurationAuthorization();
1310         try
1311         {
1312             org.apache.maven.continuum.model.system.SystemConfiguration sysConf =
1313                 systemConfigurationDao.getSystemConfiguration();
1314             return populateSystemConfiguration( sysConf );
1315         }
1316         catch ( ContinuumStoreException e )
1317         {
1318             throw new ContinuumException( "Can't get SystemConfigurationDao.", e );
1319         }
1320     }
1321 
1322     // ----------------------------------------------------------------------
1323     // Queue
1324     // ----------------------------------------------------------------------
1325     public boolean isProjectInPrepareBuildQueue( int projectId )
1326         throws ContinuumException
1327     {
1328         return isProjectInPrepareBuildQueue( projectId, -1 );
1329     }
1330 
1331     public boolean isProjectInPrepareBuildQueue( int projectId, int buildDefinitionId )
1332         throws ContinuumException
1333     {
1334         try
1335         {
1336             if ( continuum.getConfiguration().isDistributedBuildEnabled() )
1337             {
1338                 return distributedBuildManager.isProjectInAnyPrepareBuildQueue( projectId, buildDefinitionId );
1339             }
1340             else
1341             {
1342                 return parallelBuildsManager.isInPrepareBuildQueue( projectId );
1343             }
1344         }
1345         catch ( BuildManagerException e )
1346         {
1347             throw new ContinuumException( e.getMessage(), e );
1348         }
1349     }
1350 
1351     public boolean isProjectInBuildingQueue( int projectId )
1352         throws ContinuumException
1353     {
1354         return isProjectInBuildingQueue( projectId, -1 );
1355     }
1356 
1357     public boolean isProjectInBuildingQueue( int projectId, int buildDefinitionId )
1358         throws ContinuumException
1359     {
1360         try
1361         {
1362             if ( continuum.getConfiguration().isDistributedBuildEnabled() )
1363             {
1364                 return distributedBuildManager.isProjectInAnyBuildQueue( projectId, buildDefinitionId );
1365             }
1366             else
1367             {
1368                 return parallelBuildsManager.isInAnyBuildQueue( projectId );
1369             }
1370         }
1371         catch ( BuildManagerException e )
1372         {
1373             throw new ContinuumException( e.getMessage(), e );
1374         }
1375     }
1376 
1377     public boolean isProjectCurrentlyPreparingBuild( int projectId )
1378         throws ContinuumException
1379     {
1380         return isProjectCurrentlyPreparingBuild( projectId, -1 );
1381     }
1382 
1383     public boolean isProjectCurrentlyPreparingBuild( int projectId, int buildDefinitionId )
1384         throws ContinuumException
1385     {
1386         try
1387         {
1388             if ( continuum.getConfiguration().isDistributedBuildEnabled() )
1389             {
1390                 return distributedBuildManager.isProjectCurrentlyPreparingBuild( projectId, buildDefinitionId );
1391             }
1392             else
1393             {
1394                 return parallelBuildsManager.isProjectCurrentlyPreparingBuild( projectId );
1395             }
1396         }
1397         catch ( BuildManagerException e )
1398         {
1399             throw new ContinuumException( e.getMessage(), e );
1400         }
1401     }
1402 
1403     public boolean isProjectCurrentlyBuilding( int projectId )
1404         throws ContinuumException
1405     {
1406         return isProjectCurrentlyBuilding( projectId, -1 );
1407     }
1408 
1409     public boolean isProjectCurrentlyBuilding( int projectId, int buildDefinitionId )
1410         throws ContinuumException
1411     {
1412         try
1413         {
1414             if ( continuum.getConfiguration().isDistributedBuildEnabled() )
1415             {
1416                 return distributedBuildManager.isProjectCurrentlyBuilding( projectId, buildDefinitionId );
1417             }
1418             else
1419             {
1420                 return parallelBuildsManager.isProjectInAnyCurrentBuild( projectId );
1421             }
1422         }
1423         catch ( BuildManagerException e )
1424         {
1425             throw new ContinuumException( e.getMessage(), e );
1426         }
1427     }
1428 
1429     public List<BuildProjectTask> getProjectsInBuildQueue()
1430         throws ContinuumException
1431     {
1432         try
1433         {
1434             Map<String, List<org.apache.continuum.taskqueue.BuildProjectTask>> buildTasks;
1435 
1436             if ( continuum.getConfiguration().isDistributedBuildEnabled() )
1437             {
1438                 buildTasks = distributedBuildManager.getProjectsInBuildQueue();
1439             }
1440             else
1441             {
1442                 buildTasks = parallelBuildsManager.getProjectsInBuildQueues();
1443             }
1444 
1445             Set<String> keys = buildTasks.keySet();
1446             List<org.apache.continuum.taskqueue.BuildProjectTask> convertedTasks =
1447                 new ArrayList<org.apache.continuum.taskqueue.BuildProjectTask>();
1448 
1449             for ( String key : keys )
1450             {
1451                 List<org.apache.continuum.taskqueue.BuildProjectTask> tasks = buildTasks.get( key );
1452                 for ( org.apache.continuum.taskqueue.BuildProjectTask task : tasks )
1453                 {
1454                     convertedTasks.add( task );
1455                 }
1456             }
1457 
1458             return populateBuildProjectTaskList( convertedTasks );
1459         }
1460         catch ( BuildManagerException e )
1461         {
1462             throw new ContinuumException( e.getMessage(), e );
1463         }
1464     }
1465 
1466     public int removeProjectsFromBuildingQueue( int[] projectsId )
1467         throws ContinuumException
1468     {
1469         checkManageQueuesAuthorization();
1470 
1471         parallelBuildsManager.removeProjectsFromBuildQueue( projectsId );
1472 
1473         return 0;
1474     }
1475 
1476     public boolean cancelCurrentBuild()
1477         throws ContinuumException
1478     {
1479         checkManageQueuesAuthorization();
1480         try
1481         {
1482             return parallelBuildsManager.cancelAllBuilds();
1483         }
1484         catch ( BuildManagerException e )
1485         {
1486             throw new ContinuumException( e.getMessage(), e );
1487         }
1488     }
1489 
1490     public boolean cancelBuild( int projectId, int buildDefinitionId )
1491         throws ContinuumException
1492     {
1493         checkManageQueuesAuthorization();
1494         try
1495         {
1496             if ( continuum.getConfiguration().isDistributedBuildEnabled() )
1497             {
1498                 DistributedBuildManager dbm = continuum.getDistributedBuildManager();
1499 
1500                 String buildAgentUrl = dbm.getBuildAgentUrl( projectId, buildDefinitionId );
1501 
1502                 if ( dbm.isProjectInAnyPrepareBuildQueue( projectId, buildDefinitionId ) )
1503                 {
1504                     if ( buildAgentUrl != null )
1505                     {
1506                         org.apache.continuum.model.project.ProjectScmRoot scmRoot =
1507                             continuum.getProjectScmRootByProject( projectId );
1508                         dbm.removeFromPrepareBuildQueue( buildAgentUrl, scmRoot.getProjectGroup().getId(),
1509                                                          scmRoot.getId() );
1510                     }
1511                 }
1512                 // wait if already preparing
1513                 else if ( dbm.isProjectCurrentlyPreparingBuild( projectId, buildDefinitionId ) )
1514                 {
1515                     while ( dbm.isProjectCurrentlyPreparingBuild( projectId, buildDefinitionId ) )
1516                     {
1517                         try
1518                         {
1519                             Thread.sleep( 1000 );
1520                         }
1521                         catch ( InterruptedException e )
1522                         {
1523                             // do nothing
1524                         }
1525                     }
1526                 }
1527 
1528                 if ( dbm.isProjectInAnyBuildQueue( projectId, buildDefinitionId ) )
1529                 {
1530                     dbm.removeFromBuildQueue( buildAgentUrl, projectId, buildDefinitionId );
1531                 }
1532                 else if ( dbm.isProjectCurrentlyBuilding( projectId, buildDefinitionId ) )
1533                 {
1534                     if ( buildAgentUrl != null )
1535                     {
1536                         dbm.cancelDistributedBuild( buildAgentUrl );
1537                     }
1538                 }
1539 
1540                 return true;
1541             }
1542             else
1543             {
1544                 // if currently preparing build or being checked out, wait until done
1545                 if ( parallelBuildsManager.isProjectCurrentlyPreparingBuild( projectId ) ||
1546                     parallelBuildsManager.isProjectCurrentlyBeingCheckedOut( projectId ) )
1547                 {
1548                     while ( parallelBuildsManager.isProjectCurrentlyPreparingBuild( projectId ) ||
1549                         parallelBuildsManager.isProjectCurrentlyBeingCheckedOut( projectId ) )
1550                     {
1551                         try
1552                         {
1553                             Thread.sleep( 1000 );
1554                         }
1555                         catch ( InterruptedException e )
1556                         {
1557                             // do nothing
1558                         }
1559                     }
1560                 }
1561 
1562                 if ( parallelBuildsManager.isInPrepareBuildQueue( projectId ) )
1563                 {
1564                     org.apache.continuum.model.project.ProjectScmRoot scmRoot = continuum.getProjectScmRootByProject(
1565                         projectId );
1566                     parallelBuildsManager.removeProjectFromPrepareBuildQueue( scmRoot.getProjectGroup().getId(),
1567                                                                               scmRoot.getId() );
1568                 }
1569                 else if ( parallelBuildsManager.isInAnyCheckoutQueue( projectId ) )
1570                 {
1571                     parallelBuildsManager.removeProjectFromCheckoutQueue( projectId );
1572                 }
1573                 else if ( parallelBuildsManager.isInAnyBuildQueue( projectId ) )
1574                 {
1575                     parallelBuildsManager.removeProjectFromBuildQueue( projectId );
1576                 }
1577                 else if ( parallelBuildsManager.isProjectInAnyCurrentBuild( projectId ) )
1578                 {
1579                     return parallelBuildsManager.cancelBuild( projectId );
1580                 }
1581 
1582                 return true;
1583             }
1584         }
1585         catch ( BuildManagerException e )
1586         {
1587             throw new ContinuumException( e.getMessage(), e );
1588         }
1589     }
1590 
1591     // ----------------------------------------------------------------------
1592     // Release Results
1593     // ----------------------------------------------------------------------
1594 
1595     public ContinuumReleaseResult getReleaseResult( int releaseId )
1596         throws ContinuumException
1597     {
1598         org.apache.continuum.model.release.ContinuumReleaseResult releaseResult = continuum.getContinuumReleaseResult(
1599             releaseId );
1600         checkViewProjectGroupAuthorization( getProjectGroupName( releaseResult.getProjectGroup().getId() ) );
1601         return populateReleaseResult( releaseResult );
1602     }
1603 
1604     public List<ContinuumReleaseResult> getReleaseResultsForProjectGroup( int projectGroupId )
1605         throws ContinuumException
1606     {
1607         checkViewProjectGroupAuthorization( getProjectGroupName( projectGroupId ) );
1608         Collection releaseResults = continuum.getContinuumReleaseResultsByProjectGroup( projectGroupId );
1609 
1610         List<ContinuumReleaseResult> r = new ArrayList<ContinuumReleaseResult>();
1611         for ( Object releaseResult : releaseResults )
1612         {
1613             r.add( populateReleaseResult( (org.apache.continuum.model.release.ContinuumReleaseResult) releaseResult ) );
1614         }
1615         return r;
1616     }
1617 
1618     public int removeReleaseResult( ContinuumReleaseResult releaseResult )
1619         throws ContinuumException
1620     {
1621         checkModifyProjectGroupAuthorization( getProjectGroupName( releaseResult.getProjectGroup().getId() ) );
1622         continuum.removeContinuumReleaseResult( releaseResult.getId() );
1623         return 0;
1624     }
1625 
1626     public String getReleaseOutput( int releaseId )
1627         throws ContinuumException
1628     {
1629         org.apache.continuum.model.release.ContinuumReleaseResult releaseResult = continuum.getContinuumReleaseResult(
1630             releaseId );
1631         checkViewProjectGroupAuthorization( getProjectGroupName( releaseResult.getProjectGroup().getId() ) );
1632 
1633         return continuum.getReleaseOutput( releaseId );
1634     }
1635 
1636     // ----------------------------------------------------------------------
1637     // Purge Configuration
1638     // ----------------------------------------------------------------------
1639 
1640     public RepositoryPurgeConfiguration addRepositoryPurgeConfiguration( RepositoryPurgeConfiguration repoPurge )
1641         throws ContinuumException
1642     {
1643         checkManagePurgingAuthorization();
1644 
1645         try
1646         {
1647             org.apache.continuum.model.repository.RepositoryPurgeConfiguration newPurge =
1648                 new org.apache.continuum.model.repository.RepositoryPurgeConfiguration();
1649             return populateRepositoryPurgeConfiguration(
1650                 continuum.getPurgeConfigurationService().addRepositoryPurgeConfiguration(
1651                     populateRepositoryPurgeConfiguration( repoPurge, newPurge ) ) );
1652         }
1653         catch ( RepositoryServiceException e )
1654         {
1655             throw new ContinuumException( "Error while converting repository purge configuration", e );
1656         }
1657         catch ( PurgeConfigurationServiceException e )
1658         {
1659             throw new ContinuumException( "Can't add repositoryPurgeConfiguration", e );
1660         }
1661     }
1662 
1663     public int updateRepositoryPurgeConfiguration( RepositoryPurgeConfiguration repoPurge )
1664         throws ContinuumException
1665     {
1666         checkManagePurgingAuthorization();
1667 
1668         try
1669         {
1670             org.apache.continuum.model.repository.RepositoryPurgeConfiguration purge =
1671                 new org.apache.continuum.model.repository.RepositoryPurgeConfiguration();
1672             continuum.getPurgeConfigurationService().updateRepositoryPurgeConfiguration(
1673                 populateRepositoryPurgeConfiguration( repoPurge, purge ) );
1674             return 0;
1675         }
1676         catch ( RepositoryServiceException e )
1677         {
1678             throw new ContinuumException( "Error while converting repository purge configuration", e );
1679         }
1680         catch ( PurgeConfigurationServiceException e )
1681         {
1682             throw new ContinuumException( "Cant' update repository PurgeException", e );
1683         }
1684     }
1685 
1686     public int removeRepositoryPurgeConfiguration( int repoPurgeId )
1687         throws ContinuumException
1688     {
1689         checkManagePurgingAuthorization();
1690 
1691         try
1692         {
1693             org.apache.continuum.model.repository.RepositoryPurgeConfiguration repoPurge =
1694                 continuum.getPurgeConfigurationService().getRepositoryPurgeConfiguration( repoPurgeId );
1695             continuum.getPurgeConfigurationService().removeRepositoryPurgeConfiguration( repoPurge );
1696             return 0;
1697         }
1698         catch ( PurgeConfigurationServiceException e )
1699         {
1700             throw new ContinuumException( "Can't delete repository purge configuration", e );
1701         }
1702     }
1703 
1704     public RepositoryPurgeConfiguration getRepositoryPurgeConfiguration( int repoPurgeId )
1705         throws ContinuumException
1706     {
1707         checkManagePurgingAuthorization();
1708 
1709         try
1710         {
1711             org.apache.continuum.model.repository.RepositoryPurgeConfiguration repoPurgeConfig =
1712                 continuum.getPurgeConfigurationService().getRepositoryPurgeConfiguration( repoPurgeId );
1713             return populateRepositoryPurgeConfiguration( repoPurgeConfig );
1714         }
1715         catch ( PurgeConfigurationServiceException e )
1716         {
1717             throw new ContinuumException( "Error while retrieving repository purge configuration", e );
1718         }
1719     }
1720 
1721     public List<RepositoryPurgeConfiguration> getAllRepositoryPurgeConfigurations()
1722         throws ContinuumException
1723     {
1724         checkManagePurgingAuthorization();
1725         Collection repoPurgeConfigs = continuum.getPurgeConfigurationService().getAllRepositoryPurgeConfigurations();
1726 
1727         List<RepositoryPurgeConfiguration> r = new ArrayList<RepositoryPurgeConfiguration>();
1728         for ( Object repoPurgeConfig : repoPurgeConfigs )
1729         {
1730             r.add( populateRepositoryPurgeConfiguration(
1731                 (org.apache.continuum.model.repository.RepositoryPurgeConfiguration) repoPurgeConfig ) );
1732         }
1733         return r;
1734     }
1735 
1736     public DirectoryPurgeConfiguration addDirectoryPurgeConfiguration( DirectoryPurgeConfiguration dirPurge )
1737         throws ContinuumException
1738     {
1739         checkManagePurgingAuthorization();
1740 
1741         try
1742         {
1743             org.apache.continuum.model.repository.DirectoryPurgeConfiguration newPurge =
1744                 new org.apache.continuum.model.repository.DirectoryPurgeConfiguration();
1745             return populateDirectoryPurgeConfiguration(
1746                 continuum.getPurgeConfigurationService().addDirectoryPurgeConfiguration(
1747                     populateDirectoryPurgeConfiguration( dirPurge, newPurge ) ) );
1748         }
1749         catch ( RepositoryServiceException e )
1750         {
1751             throw new ContinuumException( "Error while converting directory purge configuration", e );
1752         }
1753         catch ( PurgeConfigurationServiceException e )
1754         {
1755             throw new ContinuumException( "Can't add directory purge configuration", e );
1756         }
1757     }
1758 
1759     public int updateDirectoryPurgeConfiguration( DirectoryPurgeConfiguration dirPurge )
1760         throws ContinuumException
1761     {
1762         checkManagePurgingAuthorization();
1763 
1764         try
1765         {
1766             org.apache.continuum.model.repository.DirectoryPurgeConfiguration purge =
1767                 new org.apache.continuum.model.repository.DirectoryPurgeConfiguration();
1768             continuum.getPurgeConfigurationService().updateDirectoryPurgeConfiguration(
1769                 populateDirectoryPurgeConfiguration( dirPurge, purge ) );
1770             return 0;
1771         }
1772         catch ( RepositoryServiceException e )
1773         {
1774             throw new ContinuumException( "Error while converting directory purge configuration", e );
1775         }
1776         catch ( PurgeConfigurationServiceException e )
1777         {
1778             throw new ContinuumException( "Can't add directory purge configuration", e );
1779         }
1780     }
1781 
1782     public int removeDirectoryPurgeConfiguration( int dirPurgeId )
1783         throws ContinuumException
1784     {
1785         checkManagePurgingAuthorization();
1786 
1787         try
1788         {
1789             org.apache.continuum.model.repository.DirectoryPurgeConfiguration dirPurge =
1790                 continuum.getPurgeConfigurationService().getDirectoryPurgeConfiguration( dirPurgeId );
1791             continuum.getPurgeConfigurationService().removeDirectoryPurgeConfiguration( dirPurge );
1792             return 0;
1793         }
1794         catch ( PurgeConfigurationServiceException e )
1795         {
1796             throw new ContinuumException( "Can't delete directory purge configuration", e );
1797         }
1798     }
1799 
1800     public DirectoryPurgeConfiguration getDirectoryPurgeConfiguration( int dirPurgeId )
1801         throws ContinuumException
1802     {
1803         checkManagePurgingAuthorization();
1804 
1805         try
1806         {
1807             org.apache.continuum.model.repository.DirectoryPurgeConfiguration dirPurgeConfig =
1808                 continuum.getPurgeConfigurationService().getDirectoryPurgeConfiguration( dirPurgeId );
1809             return populateDirectoryPurgeConfiguration( dirPurgeConfig );
1810         }
1811         catch ( PurgeConfigurationServiceException e )
1812         {
1813             throw new ContinuumException( "Error while retrieving directory purge configuration", e );
1814         }
1815     }
1816 
1817     public List<DirectoryPurgeConfiguration> getAllDirectoryPurgeConfigurations()
1818         throws ContinuumException
1819     {
1820         checkManagePurgingAuthorization();
1821         Collection dirPurgeConfigs = continuum.getPurgeConfigurationService().getAllDirectoryPurgeConfigurations();
1822 
1823         List<DirectoryPurgeConfiguration> d = new ArrayList<DirectoryPurgeConfiguration>();
1824         for ( Object dirPurgeConfig : dirPurgeConfigs )
1825         {
1826             d.add( populateDirectoryPurgeConfiguration(
1827                 (org.apache.continuum.model.repository.DirectoryPurgeConfiguration) dirPurgeConfig ) );
1828         }
1829         return d;
1830     }
1831 
1832     public int purgeLocalRepository( int repoPurgeId )
1833         throws ContinuumException
1834     {
1835         checkManagePurgingAuthorization();
1836 
1837         try
1838         {
1839             org.apache.continuum.model.repository.RepositoryPurgeConfiguration repoPurgeConfig =
1840                 continuum.getPurgeConfigurationService().getRepositoryPurgeConfiguration( repoPurgeId );
1841             continuum.getPurgeManager().purgeRepository( repoPurgeConfig );
1842 
1843             return 0;
1844         }
1845         catch ( PurgeConfigurationServiceException e )
1846         {
1847             throw new ContinuumException( "Error while retrieving repository purge configuration", e );
1848         }
1849         catch ( ContinuumPurgeManagerException e )
1850         {
1851             throw new ContinuumException( "Error while purging local repository", e );
1852         }
1853     }
1854 
1855     public int purgeDirectory( int dirPurgeId )
1856         throws ContinuumException
1857     {
1858         checkManagePurgingAuthorization();
1859 
1860         try
1861         {
1862             org.apache.continuum.model.repository.DirectoryPurgeConfiguration dirPurgeConfig =
1863                 continuum.getPurgeConfigurationService().getDirectoryPurgeConfiguration( dirPurgeId );
1864             continuum.getPurgeManager().purgeDirectory( dirPurgeConfig );
1865 
1866             return 0;
1867         }
1868         catch ( PurgeConfigurationServiceException e )
1869         {
1870             throw new ContinuumException( "Error while retrieving directory purge configuration", e );
1871         }
1872         catch ( ContinuumPurgeManagerException e )
1873         {
1874             throw new ContinuumException( "Error while purging directory", e );
1875         }
1876     }
1877 
1878     // ----------------------------------------------------------------------
1879     // Local Repository
1880     // ----------------------------------------------------------------------
1881 
1882     public LocalRepository addLocalRepository( LocalRepository repository )
1883         throws ContinuumException
1884     {
1885         checkManageRepositoriesAuthorization();
1886 
1887         try
1888         {
1889             org.apache.continuum.model.repository.LocalRepository newRepository =
1890                 new org.apache.continuum.model.repository.LocalRepository();
1891             return populateLocalRepository( continuum.getRepositoryService().addLocalRepository(
1892                 populateLocalRepository( repository, newRepository ) ) );
1893         }
1894         catch ( RepositoryServiceException e )
1895         {
1896             throw new ContinuumException( "Unable to add repository", e );
1897         }
1898     }
1899 
1900     public int updateLocalRepository( LocalRepository repository )
1901         throws ContinuumException
1902     {
1903         checkManageRepositoriesAuthorization();
1904 
1905         try
1906         {
1907             final org.apache.continuum.model.repository.LocalRepository newRepo =
1908                 continuum.getRepositoryService().getLocalRepository( repository.getId() );
1909             continuum.getRepositoryService().updateLocalRepository( populateLocalRepository( repository, newRepo ) );
1910             return 0;
1911         }
1912         catch ( RepositoryServiceException e )
1913         {
1914             throw new ContinuumException( "Can't update repository", e );
1915         }
1916     }
1917 
1918     public int removeLocalRepository( int repositoryId )
1919         throws ContinuumException
1920     {
1921         checkManageRepositoriesAuthorization();
1922 
1923         try
1924         {
1925             continuum.getRepositoryService().removeLocalRepository( repositoryId );
1926             return 0;
1927         }
1928         catch ( RepositoryServiceException e )
1929         {
1930             throw new ContinuumException( "Can't delete repository", e );
1931         }
1932     }
1933 
1934     public LocalRepository getLocalRepository( int repositoryId )
1935         throws ContinuumException
1936     {
1937         checkManageRepositoriesAuthorization();
1938 
1939         try
1940         {
1941             return populateLocalRepository( continuum.getRepositoryService().getLocalRepository( repositoryId ) );
1942         }
1943         catch ( RepositoryServiceException e )
1944         {
1945             throw new ContinuumException( "Error while retrieving repository.", e );
1946         }
1947     }
1948 
1949     public List<LocalRepository> getAllLocalRepositories()
1950         throws ContinuumException
1951     {
1952         checkManageRepositoriesAuthorization();
1953         Collection repos = continuum.getRepositoryService().getAllLocalRepositories();
1954 
1955         List<LocalRepository> r = new ArrayList<LocalRepository>();
1956         for ( Object repo : repos )
1957         {
1958             r.add( populateLocalRepository( (org.apache.continuum.model.repository.LocalRepository) repo ) );
1959         }
1960         return r;
1961     }
1962 
1963     // ----------------------------------------------------------------------
1964     // Build agent
1965     // ----------------------------------------------------------------------
1966 
1967     public BuildAgentConfiguration addBuildAgent( BuildAgentConfiguration buildAgentConfiguration )
1968         throws ConfigurationException, ConfigurationStoringException, ContinuumConfigurationException
1969     {
1970         ConfigurationService configurationService = continuum.getConfiguration();
1971 
1972         if ( buildAgentConfiguration == null )
1973         {
1974             return null;
1975         }
1976         try
1977         {
1978             configurationService.addBuildAgent( populateBuildAgent( buildAgentConfiguration ) );
1979             configurationService.store();
1980             return populateBuildAgent( configurationService.getBuildAgent( buildAgentConfiguration.getUrl() ) );
1981         }
1982         catch ( ContinuumException e )
1983         {
1984             throw new ConfigurationException( "Error in adding buildAgent", e );
1985         }
1986     }
1987 
1988     public BuildAgentConfiguration getBuildAgent( String url )
1989     {
1990         ConfigurationService configurationService = continuum.getConfiguration();
1991         org.apache.continuum.configuration.BuildAgentConfiguration buildAgent = configurationService.getBuildAgent(
1992             url );
1993         return buildAgent != null ? populateBuildAgent( buildAgent ) : null;
1994     }
1995 
1996     /**
1997      * {@inheritDoc}
1998      *
1999      * @throws ContinuumException distributed build is not enabled or error during retrieval of build agent url
2000      * @see DistributedBuildManager#getBuildAgentUrl(int, int)
2001      */
2002     public String getBuildAgentUrl( int projectId, int buildDefinitionId )
2003         throws ContinuumException
2004     {
2005         if ( !continuum.getConfiguration().isDistributedBuildEnabled() )
2006         {
2007             throw new ContinuumException( "Method available only in distributed build mode." );
2008         }
2009 
2010         return distributedBuildManager.getBuildAgentUrl( projectId, buildDefinitionId );
2011     }
2012 
2013     public BuildAgentConfiguration updateBuildAgent( BuildAgentConfiguration buildAgentConfiguration )
2014         throws ConfigurationStoringException, ContinuumConfigurationException
2015     {
2016         try
2017         {
2018             ConfigurationService configurationService = continuum.getConfiguration();
2019             org.apache.continuum.configuration.BuildAgentConfiguration buildAgent = configurationService.getBuildAgent(
2020                 buildAgentConfiguration.getUrl() );
2021             BuildAgentConfiguration buildAgentConfigurationToUpdate = buildAgent != null ? populateBuildAgent(
2022                 buildAgent ) : null;
2023 
2024             if ( buildAgentConfigurationToUpdate != null )
2025             {
2026                 buildAgentConfigurationToUpdate.setDescription( StringEscapeUtils.escapeXml(
2027                     buildAgentConfiguration.getDescription() ) );
2028                 buildAgentConfigurationToUpdate.setEnabled( buildAgentConfiguration.isEnabled() );
2029                 configurationService.updateBuildAgent( populateBuildAgent( buildAgentConfigurationToUpdate ) );
2030                 configurationService.store();
2031                 return populateBuildAgent( configurationService.getBuildAgent( buildAgentConfiguration.getUrl() ) );
2032             }
2033             else
2034             {
2035                 return null;
2036             }
2037         }
2038         catch ( ContinuumException e )
2039         {
2040             throw new ContinuumConfigurationException( "Error in adding buildAgent", e );
2041         }
2042     }
2043 
2044     public boolean removeBuildAgent( String url )
2045         throws BuildAgentConfigurationException, ConfigurationStoringException, ContinuumConfigurationException,
2046         ContinuumException
2047     {
2048         ConfigurationService configurationService = continuum.getConfiguration();
2049 
2050         boolean SUCCESS;
2051         org.apache.continuum.configuration.BuildAgentConfiguration buildAgent = configurationService.getBuildAgent(
2052             url );
2053         BuildAgentConfiguration buildAgentConfiguration = buildAgent != null ? populateBuildAgent( buildAgent ) : null;
2054         if ( buildAgentConfiguration != null )
2055         {
2056             if ( continuum.getDistributedBuildManager().isBuildAgentBusy( buildAgentConfiguration.getUrl() ) )
2057             {
2058                 throw new BuildAgentConfigurationException(
2059                     "Cannot delete build agent because it's busy at the moment" );
2060             }
2061 
2062             if ( configurationService.getBuildAgentGroups() != null )
2063             {
2064                 for ( org.apache.continuum.configuration.BuildAgentGroupConfiguration buildAgentGroup : configurationService.getBuildAgentGroups() )
2065                 {
2066                     if ( configurationService.containsBuildAgentUrl( buildAgentConfiguration.getUrl(),
2067                                                                      buildAgentGroup ) )
2068                     {
2069                         throw new BuildAgentConfigurationException(
2070                             "Cannot delete build agent because it's in use at the moment" );
2071                     }
2072                 }
2073             }
2074 
2075             try
2076             {
2077                 continuum.getDistributedBuildManager().removeDistributedBuildQueueOfAgent(
2078                     buildAgentConfiguration.getUrl() );
2079                 configurationService.removeBuildAgent( populateBuildAgent( buildAgentConfiguration ) );
2080                 configurationService.store();
2081                 SUCCESS = true;
2082             }
2083             catch ( ContinuumException e )
2084             {
2085                 throw new ContinuumException( "Error when removing build agent in build queue", e );
2086             }
2087 
2088         }
2089         else
2090         {
2091             throw new BuildAgentConfigurationException( "Build agent does not exist." );
2092         }
2093 
2094         return SUCCESS;
2095     }
2096 
2097     public List<BuildAgentConfiguration> getAllBuildAgents()
2098     {
2099         ConfigurationService configurationService = continuum.getConfiguration();
2100 
2101         List<org.apache.continuum.configuration.BuildAgentConfiguration> buildAgents =
2102             configurationService.getBuildAgents();
2103         List<BuildAgentConfiguration> buildAgentConfigurations = new ArrayList<BuildAgentConfiguration>();
2104 
2105         if ( buildAgents != null )
2106         {
2107             for ( org.apache.continuum.configuration.BuildAgentConfiguration buildAgent : buildAgents )
2108             {
2109                 buildAgentConfigurations.add( populateBuildAgent( buildAgent ) );
2110             }
2111         }
2112         return buildAgentConfigurations;
2113     }
2114 
2115     public List<BuildAgentConfiguration> getBuildAgentsWithInstallations()
2116         throws Exception
2117     {
2118         ConfigurationService configurationService = continuum.getConfiguration();
2119 
2120         List<org.apache.continuum.configuration.BuildAgentConfiguration> buildAgents =
2121             configurationService.getBuildAgents();
2122         List<BuildAgentConfiguration> buildAgentConfigurations = new ArrayList<BuildAgentConfiguration>();
2123 
2124         if ( buildAgents != null )
2125         {
2126             for ( org.apache.continuum.configuration.BuildAgentConfiguration buildAgent : buildAgents )
2127             {
2128                 if ( buildAgent.isEnabled() )
2129                 {
2130                     BuildAgentConfiguration agent = populateBuildAgent( buildAgent );
2131                     agent.setInstallations( getBuildAgentInstallations( buildAgent.getUrl() ) );
2132                     buildAgentConfigurations.add( agent );
2133                 }
2134             }
2135         }
2136         return buildAgentConfigurations;
2137     }
2138 
2139     // ----------------------------------------------------------------------
2140     // Build agent group
2141     // ----------------------------------------------------------------------
2142 
2143     public BuildAgentGroupConfiguration addBuildAgentGroup( BuildAgentGroupConfiguration buildAgentGroup )
2144         throws ConfigurationException, ConfigurationStoringException, ContinuumConfigurationException
2145     {
2146         ConfigurationService configurationService = continuum.getConfiguration();
2147 
2148         if ( buildAgentGroup == null )
2149         {
2150             return null;
2151         }
2152         try
2153         {
2154             configurationService.addBuildAgentGroup( populateBuildAgentGroup( buildAgentGroup ) );
2155             configurationService.store();
2156             return populateBuildAgentGroup( configurationService.getBuildAgentGroup( buildAgentGroup.getName() ) );
2157         }
2158         catch ( ContinuumException e )
2159         {
2160             throw new ConfigurationException( "Error in adding buildAgentGroup", e );
2161         }
2162     }
2163 
2164     public BuildAgentGroupConfiguration getBuildAgentGroup( String name )
2165     {
2166         ConfigurationService configurationService = continuum.getConfiguration();
2167         org.apache.continuum.configuration.BuildAgentGroupConfiguration buildAgentGroup =
2168             configurationService.getBuildAgentGroup( name );
2169         return buildAgentGroup != null ? populateBuildAgentGroup( buildAgentGroup ) : null;
2170     }
2171 
2172     public BuildAgentGroupConfiguration updateBuildAgentGroup( BuildAgentGroupConfiguration buildAgentGroup )
2173         throws ConfigurationException, ConfigurationStoringException, ContinuumConfigurationException
2174     {
2175         try
2176         {
2177             ConfigurationService configurationService = continuum.getConfiguration();
2178             org.apache.continuum.configuration.BuildAgentGroupConfiguration buildAgentGroupConfiguration =
2179                 configurationService.getBuildAgentGroup( buildAgentGroup.getName() );
2180 
2181             if ( buildAgentGroupConfiguration != null )
2182             {
2183                 buildAgentGroupConfiguration.setName( StringEscapeUtils.escapeXml( buildAgentGroup.getName() ) );
2184                 if ( buildAgentGroup.getBuildAgents() != null )
2185                 {
2186                     buildAgentGroupConfiguration.getBuildAgents().clear();
2187                     for ( BuildAgentConfiguration buildAgent : buildAgentGroup.getBuildAgents() )
2188                     {
2189                         buildAgentGroupConfiguration.getBuildAgents().add( populateBuildAgent( buildAgent ) );
2190                     }
2191                 }
2192                 else
2193                 {
2194                     buildAgentGroupConfiguration.setBuildAgents( null );
2195                 }
2196                 configurationService.updateBuildAgentGroup( buildAgentGroupConfiguration );
2197                 configurationService.store();
2198                 return populateBuildAgentGroup( configurationService.getBuildAgentGroup( buildAgentGroup.getName() ) );
2199             }
2200             else
2201             {
2202                 return null;
2203             }
2204         }
2205         catch ( ContinuumException e )
2206         {
2207             throw new ContinuumConfigurationException(
2208                 "Error in updating build agent group " + buildAgentGroup.getName(), e );
2209         }
2210     }
2211 
2212     public int removeBuildAgentGroup( String name )
2213         throws ConfigurationException
2214     {
2215         ConfigurationService configurationService = continuum.getConfiguration();
2216         org.apache.continuum.configuration.BuildAgentGroupConfiguration buildAgentGroupConfiguration =
2217             configurationService.getBuildAgentGroup( name );
2218         if ( buildAgentGroupConfiguration != null )
2219         {
2220             configurationService.removeBuildAgentGroup( buildAgentGroupConfiguration );
2221         }
2222 
2223         return 0;
2224     }
2225 
2226     // ----------------------------------------------------------------------
2227     // Converters
2228     // ----------------------------------------------------------------------
2229 
2230     private List<BuildProjectTask> populateBuildProjectTaskList(
2231         List<org.apache.continuum.taskqueue.BuildProjectTask> buildProjectTasks )
2232     {
2233         List<BuildProjectTask> responses = new ArrayList<BuildProjectTask>();
2234         for ( org.apache.continuum.taskqueue.BuildProjectTask buildProjectTask : buildProjectTasks )
2235         {
2236 
2237             responses.add( (BuildProjectTask) mapper.map( buildProjectTask, BuildProjectTask.class ) );
2238         }
2239         return responses;
2240     }
2241 
2242     private ProjectSummary populateProjectSummary( org.apache.maven.continuum.model.project.Project project )
2243     {
2244         return (ProjectSummary) mapper.map( project, ProjectSummary.class );
2245     }
2246 
2247     private Project populateProject( org.apache.maven.continuum.model.project.Project project )
2248     {
2249         return (Project) mapper.map( project, Project.class );
2250     }
2251 
2252     private ProjectScmRoot populateProjectScmRoot( org.apache.continuum.model.project.ProjectScmRoot projectScmRoot )
2253     {
2254         return (ProjectScmRoot) mapper.map( projectScmRoot, ProjectScmRoot.class );
2255     }
2256 
2257     private org.apache.maven.continuum.model.project.Project populateProject( ProjectSummary projectSummary,
2258                                                                               org.apache.maven.continuum.model.project.Project project )
2259         throws ContinuumException
2260     {
2261         if ( projectSummary == null )
2262         {
2263             return null;
2264         }
2265 
2266         // validate
2267         if ( StringUtils.isNotBlank( projectSummary.getArtifactId() ) && !projectSummary.getArtifactId().matches(
2268             PROJECT_ARTIFACT_ID_VALID_EXPRESSION ) )
2269         {
2270             throw new ContinuumException( "Project Artifact Id contains invalid characters" );
2271         }
2272 
2273         if ( StringUtils.isNotBlank( projectSummary.getExecutorId() ) && !projectSummary.getExecutorId().matches(
2274             PROJECT_EXECUTOR_OR_BUILDDEF_TYPE_VALID_EXPRESSION ) )
2275         {
2276             throw new ContinuumException( "Project Executor Id can only be 'maven2, maven-1, ant or shell'" );
2277         }
2278 
2279         if ( StringUtils.isNotBlank( projectSummary.getGroupId() ) && !projectSummary.getGroupId().matches(
2280             PROJECTGROUP_ID_VALID_EXPRESSION ) )
2281         {
2282             throw new ContinuumException( "Project Group Id contains invalid characters" );
2283         }
2284 
2285         if ( StringUtils.isNotBlank( projectSummary.getName() ) && !projectSummary.getName().matches(
2286             NAME_VALID_EXPRESSION ) )
2287         {
2288             throw new ContinuumException( "Project Name contains invalid characters" );
2289         }
2290 
2291         if ( StringUtils.isNotBlank( projectSummary.getScmTag() ) && !projectSummary.getScmTag().matches(
2292             PROJECT_SCM_TAG_VALID_EXPRESSION ) )
2293         {
2294             throw new ContinuumException( "Project Scm Tag contains invalid characters" );
2295         }
2296 
2297         if ( StringUtils.isNotBlank( projectSummary.getScmUrl() ) && !projectSummary.getScmUrl().matches(
2298             PROJECT_SCM_URL_VALID_EXPRESSION ) )
2299         {
2300             throw new ContinuumException( "Project Scm Url contains invalid characters" );
2301         }
2302 
2303         if ( StringUtils.isNotBlank( projectSummary.getUrl() ) && !projectSummary.getUrl().matches(
2304             URL_VALID_EXPRESSION ) )
2305         {
2306             throw new ContinuumException( "Project Url contains invalid characters" );
2307         }
2308 
2309         if ( StringUtils.isNotBlank( projectSummary.getVersion() ) && !projectSummary.getVersion().matches(
2310             PROJECT_VERSION_VALID_EXPRESSION ) )
2311         {
2312             throw new ContinuumException( "Project Version contains invalid characters" );
2313         }
2314 
2315         if ( StringUtils.isNotBlank( projectSummary.getWorkingDirectory() ) &&
2316             !projectSummary.getWorkingDirectory().matches( DIRECTORY_VALID_EXPRESSION ) )
2317         {
2318             throw new ContinuumException( "Project Working Directory contains invalid characters" );
2319         }
2320 
2321         project.setArtifactId( projectSummary.getArtifactId() );
2322         project.setBuildNumber( projectSummary.getBuildNumber() );
2323         project.setDescription( StringEscapeUtils.escapeXml( projectSummary.getDescription() ) );
2324         project.setExecutorId( projectSummary.getExecutorId() );
2325         project.setGroupId( projectSummary.getGroupId() );
2326         project.setId( projectSummary.getId() );
2327         project.setLatestBuildId( projectSummary.getLatestBuildId() );
2328         project.setName( projectSummary.getName() );
2329         if ( projectSummary.getProjectGroup() != null )
2330         {
2331             org.apache.maven.continuum.model.project.ProjectGroup g = continuum.getProjectGroup(
2332                 projectSummary.getProjectGroup().getId() );
2333             project.setProjectGroup( populateProjectGroupSummary( projectSummary.getProjectGroup(), g ) );
2334         }
2335         else
2336         {
2337             project.setProjectGroup( null );
2338         }
2339         project.setScmTag( projectSummary.getScmTag() );
2340         project.setScmUrl( projectSummary.getScmUrl() );
2341         project.setScmUseCache( projectSummary.isScmUseCache() );
2342         project.setScmUsername( projectSummary.getScmUsername() );
2343         project.setState( projectSummary.getState() );
2344         project.setUrl( projectSummary.getUrl() );
2345         project.setVersion( projectSummary.getVersion() );
2346         project.setWorkingDirectory( projectSummary.getWorkingDirectory() );
2347         return project;
2348     }
2349 
2350     private ProjectNotifier populateProjectNotifier( org.apache.maven.continuum.model.project.ProjectNotifier notifier )
2351     {
2352         return (ProjectNotifier) mapper.map( notifier, ProjectNotifier.class );
2353     }
2354 
2355     private ProjectGroupSummary populateProjectGroupSummary(
2356         org.apache.maven.continuum.model.project.ProjectGroup group )
2357     {
2358         return (ProjectGroupSummary) mapper.map( group, ProjectGroupSummary.class );
2359     }
2360 
2361     private org.apache.maven.continuum.model.project.ProjectGroup populateProjectGroupSummary(
2362         ProjectGroupSummary group, org.apache.maven.continuum.model.project.ProjectGroup g )
2363         throws ContinuumException
2364     {
2365         if ( group == null )
2366         {
2367             return null;
2368         }
2369 
2370         if ( StringUtils.isNotBlank( group.getGroupId() ) && !group.getGroupId().matches(
2371             PROJECTGROUP_ID_VALID_EXPRESSION ) )
2372         {
2373             throw new ContinuumException( "ProjectGroup Id contains invalid characters" );
2374         }
2375 
2376         if ( StringUtils.isNotBlank( group.getName() ) && !group.getName().matches( NAME_VALID_EXPRESSION ) )
2377         {
2378             throw new ContinuumException( "ProjectGroup Name contains invalid characters" );
2379         }
2380 
2381         g.setDescription( StringEscapeUtils.escapeXml( group.getDescription() ) );
2382         g.setGroupId( group.getGroupId() );
2383         g.setId( group.getId() );
2384         g.setName( group.getName() );
2385         org.apache.continuum.model.repository.LocalRepository repo =
2386             new org.apache.continuum.model.repository.LocalRepository();
2387         g.setLocalRepository( populateLocalRepository( group.getLocalRepository(), repo ) );
2388         return g;
2389     }
2390 
2391     private ProjectGroup populateProjectGroupWithAllDetails(
2392         org.apache.maven.continuum.model.project.ProjectGroup group )
2393     {
2394         return (ProjectGroup) mapper.map( group, ProjectGroup.class );
2395     }
2396 
2397     private BuildResultSummary populateBuildResultSummary(
2398         org.apache.maven.continuum.model.project.BuildResult buildResult )
2399     {
2400         return (BuildResultSummary) mapper.map( buildResult, BuildResultSummary.class );
2401     }
2402 
2403     private BuildResult populateBuildResult( org.apache.maven.continuum.model.project.BuildResult buildResult )
2404         throws ContinuumException
2405     {
2406         return (BuildResult) mapper.map( buildResult, BuildResult.class );
2407     }
2408 
2409     private AddingResult populateAddingResult( ContinuumProjectBuildingResult result )
2410     {
2411         if ( result == null )
2412         {
2413             return null;
2414         }
2415         AddingResult res = new AddingResult();
2416 
2417         if ( result.hasErrors() )
2418         {
2419             if ( StringUtils.isNotBlank( result.getErrorsAsString() ) )
2420             {
2421                 res.addError( result.getErrorsAsString() );
2422             }
2423             else
2424             {
2425                 for ( String error : result.getErrors() )
2426                 {
2427                     res.addError( AddingResultUtil.getErrorMessage( error ) );
2428                 }
2429             }
2430         }
2431 
2432         if ( result.getProjects() != null )
2433         {
2434             for ( org.apache.maven.continuum.model.project.Project project : result.getProjects() )
2435             {
2436                 res.addProject( populateProjectSummary( project ) );
2437             }
2438         }
2439 
2440         if ( result.getProjectGroups() != null )
2441         {
2442             for ( org.apache.maven.continuum.model.project.ProjectGroup projectGroup : result.getProjectGroups() )
2443             {
2444                 res.addProjectGroup( populateProjectGroupSummary( projectGroup ) );
2445             }
2446         }
2447 
2448         return res;
2449     }
2450 
2451     private BuildDefinition populateBuildDefinition( org.apache.maven.continuum.model.project.BuildDefinition buildDef )
2452     {
2453         return (BuildDefinition) mapper.map( buildDef, BuildDefinition.class );
2454     }
2455 
2456     protected org.apache.maven.continuum.model.project.BuildDefinition populateBuildDefinition(
2457         BuildDefinition buildDef, org.apache.maven.continuum.model.project.BuildDefinition bd )
2458         throws ContinuumException
2459     {
2460         if ( buildDef == null )
2461         {
2462             return null;
2463         }
2464 
2465         if ( StringUtils.isNotBlank( buildDef.getArguments() ) && !buildDef.getArguments().matches(
2466             BUILD_DEFINITION_ARGUMENTS_VALID_EXPRESSION ) )
2467         {
2468             throw new ContinuumException( "Build Definition Arguments contain invalid characters" );
2469         }
2470 
2471         if ( StringUtils.isNotBlank( buildDef.getBuildFile() ) && !buildDef.getBuildFile().matches(
2472             BUILD_DEFINITION_BUILD_FILE_VALID_EXPRESSION ) )
2473         {
2474             throw new ContinuumException( "Build Definition Build File contains invalid characters" );
2475         }
2476 
2477         if ( StringUtils.isNotBlank( buildDef.getGoals() ) && !buildDef.getGoals().matches(
2478             BUILD_DEFINITION_GOALS_VALID_EXPRESSION ) )
2479         {
2480             throw new ContinuumException( "Build Definition Goals contain invalid characters" );
2481         }
2482 
2483         if ( StringUtils.isNotBlank( buildDef.getType() ) && !buildDef.getType().matches(
2484             PROJECT_EXECUTOR_OR_BUILDDEF_TYPE_VALID_EXPRESSION ) )
2485         {
2486             throw new ContinuumException( "Build Definition Type can only be 'maven2, maven-1, ant, or shell'" );
2487         }
2488 
2489         bd.setArguments( buildDef.getArguments() );
2490         bd.setBuildFile( buildDef.getBuildFile() );
2491         bd.setType( buildDef.getType() );
2492         bd.setBuildFresh( buildDef.isBuildFresh() );
2493         bd.setAlwaysBuild( buildDef.isAlwaysBuild() );
2494         bd.setDefaultForProject( buildDef.isDefaultForProject() );
2495         bd.setGoals( buildDef.getGoals() );
2496         bd.setId( buildDef.getId() );
2497         if ( buildDef.getProfile() != null )
2498         {
2499             bd.setProfile( populateProfile( buildDef.getProfile(), continuum.getProfileService().getProfile(
2500                 buildDef.getProfile().getId() ) ) );
2501         }
2502         else
2503         {
2504             bd.setProfile( null );
2505         }
2506         if ( buildDef.getSchedule() != null )
2507         {
2508             bd.setSchedule( populateSchedule( buildDef.getSchedule(), continuum.getSchedule(
2509                 buildDef.getSchedule().getId() ) ) );
2510         }
2511         else
2512         {
2513             bd.setSchedule( null );
2514         }
2515 
2516         if ( StringUtils.isNotEmpty( buildDef.getDescription() ) )
2517         {
2518             bd.setDescription( StringEscapeUtils.escapeXml( buildDef.getDescription() ) );
2519         }
2520 
2521         return bd;
2522     }
2523 
2524     protected void buildProjectWithBuildDefinition( int projectId, int buildDefinitionId,
2525                                                     org.apache.continuum.utils.build.BuildTrigger buildTrigger )
2526         throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
2527     {
2528         continuum.buildProjectWithBuildDefinition( projectId, buildDefinitionId, buildTrigger );
2529     }
2530 
2531     private BuildDefinitionTemplate populateBuildDefinitionTemplate(
2532         org.apache.maven.continuum.model.project.BuildDefinitionTemplate bdt )
2533     {
2534         return (BuildDefinitionTemplate) mapper.map( bdt, BuildDefinitionTemplate.class );
2535     }
2536 
2537     private org.apache.maven.continuum.model.project.Schedule populateSchedule( Schedule schedule,
2538                                                                                 org.apache.maven.continuum.model.project.Schedule s )
2539         throws ContinuumException
2540     {
2541         if ( schedule == null )
2542         {
2543             return null;
2544         }
2545 
2546         if ( StringUtils.isNotBlank( schedule.getCronExpression() ) && !schedule.getCronExpression().matches(
2547             SCHEDULE_CRON_VALID_EXPRESSION ) )
2548         {
2549             throw new ContinuumException( "Schedule Cron Expression contains invalid characters" );
2550         }
2551 
2552         if ( StringUtils.isNotBlank( schedule.getName() ) && !schedule.getName().matches( NAME_VALID_EXPRESSION ) )
2553         {
2554             throw new ContinuumException( "Schedule Name contains invalid characters" );
2555         }
2556 
2557         s.setActive( schedule.isActive() );
2558         s.setCronExpression( schedule.getCronExpression() );
2559         s.setDelay( schedule.getDelay() );
2560         s.setDescription( StringEscapeUtils.escapeXml( schedule.getDescription() ) );
2561         s.setId( schedule.getId() );
2562         s.setMaxJobExecutionTime( schedule.getMaxJobExecutionTime() );
2563         s.setName( schedule.getName() );
2564         return s;
2565     }
2566 
2567     private Schedule populateSchedule( org.apache.maven.continuum.model.project.Schedule schedule )
2568     {
2569         return (Schedule) mapper.map( schedule, Schedule.class );
2570     }
2571 
2572     private org.apache.maven.continuum.model.system.Profile populateProfile( Profile profile,
2573                                                                              org.apache.maven.continuum.model.system.Profile newProfile )
2574         throws ContinuumException
2575     {
2576         if ( profile == null )
2577         {
2578             return null;
2579         }
2580 
2581         if ( StringUtils.isNotBlank( profile.getName() ) && !profile.getName().matches( NAME_VALID_EXPRESSION ) )
2582         {
2583             throw new ContinuumException( "Build Environment Name contains invalid characters" );
2584         }
2585 
2586         try
2587         {
2588             newProfile.setActive( profile.isActive() );
2589             newProfile.setBuildWithoutChanges( profile.isBuildWithoutChanges() );
2590             newProfile.setDescription( StringEscapeUtils.escapeXml( profile.getDescription() ) );
2591             newProfile.setName( profile.getName() );
2592             newProfile.setScmMode( profile.getScmMode() );
2593             newProfile.setBuildAgentGroup( profile.getBuildAgentGroup() );
2594             if ( profile.getBuilder() != null )
2595             {
2596                 final org.apache.maven.continuum.model.system.Installation newBuilder =
2597                     continuum.getInstallationService().getInstallation( profile.getBuilder().getInstallationId() );
2598                 newProfile.setBuilder( populateInstallation( profile.getBuilder(), newBuilder ) );
2599 
2600             }
2601             else
2602             {
2603                 newProfile.setBuilder( null );
2604             }
2605             if ( profile.getJdk() != null )
2606             {
2607                 final org.apache.maven.continuum.model.system.Installation newJdk =
2608                     continuum.getInstallationService().getInstallation( profile.getJdk().getInstallationId() );
2609                 newProfile.setJdk( populateInstallation( profile.getJdk(), newJdk ) );
2610 
2611             }
2612             else
2613             {
2614                 newProfile.setJdk( null );
2615             }
2616             newProfile.getEnvironmentVariables().clear();
2617             if ( profile.getEnvironmentVariables() != null )
2618             {
2619                 for ( final Installation varEnv : profile.getEnvironmentVariables() )
2620                 {
2621                     final org.apache.maven.continuum.model.system.Installation newInst =
2622                         continuum.getInstallationService().getInstallation( varEnv.getInstallationId() );
2623                     newProfile.getEnvironmentVariables().add( populateInstallation( varEnv, newInst ) );
2624 
2625                 }
2626             }
2627             return newProfile;
2628         }
2629         catch ( InstallationException e )
2630         {
2631             throw new ContinuumException( "Can't load installations", e );
2632         }
2633     }
2634 
2635     private Profile populateProfile( org.apache.maven.continuum.model.system.Profile profile )
2636     {
2637         return (Profile) mapper.map( profile, Profile.class );
2638     }
2639 
2640     private org.apache.maven.continuum.model.system.Installation populateInstallation( Installation install,
2641                                                                                        org.apache.maven.continuum.model.system.Installation inst )
2642         throws ContinuumException
2643     {
2644         if ( install == null )
2645         {
2646             return null;
2647         }
2648 
2649         if ( StringUtils.isNotBlank( install.getName() ) && !install.getName().matches( NAME_VALID_EXPRESSION ) )
2650         {
2651             throw new ContinuumException( "Installation Name contains invalid characters" );
2652         }
2653 
2654         if ( StringUtils.isNotBlank( install.getType() ) && !install.getType().matches(
2655             INSTALLATION_TYPE_VALID_EXPRESSION ) )
2656         {
2657             throw new ContinuumException( "Installation Type contains invalid characters" );
2658         }
2659 
2660         if ( StringUtils.isNotBlank( install.getVarName() ) && !install.getVarName().matches(
2661             INSTALLATION_VARNAME_VALID_EXPRESSION ) )
2662         {
2663             throw new ContinuumException( "Installation VarName contains invalid characters" );
2664         }
2665 
2666         if ( StringUtils.isNotBlank( install.getVarValue() ) && !install.getVarValue().matches(
2667             INSTALLATION_VARVALUE_VALID_EXPRESSION ) )
2668         {
2669             throw new ContinuumException( "Installation VarValue contains invalid characters" );
2670         }
2671 
2672         inst.setName( install.getName() );
2673         inst.setType( install.getType() );
2674         inst.setVarName( install.getVarName() );
2675         inst.setVarValue( install.getVarValue() );
2676         return inst;
2677     }
2678 
2679     private Installation populateInstallation( org.apache.maven.continuum.model.system.Installation install )
2680     {
2681         return (Installation) mapper.map( install, Installation.class );
2682     }
2683 
2684     private SystemConfiguration populateSystemConfiguration(
2685         org.apache.maven.continuum.model.system.SystemConfiguration sysConf )
2686     {
2687         return (SystemConfiguration) mapper.map( sysConf, SystemConfiguration.class );
2688     }
2689 
2690     private ContinuumReleaseResult populateReleaseResult(
2691         org.apache.continuum.model.release.ContinuumReleaseResult releaseResult )
2692     {
2693         return (ContinuumReleaseResult) mapper.map( releaseResult, ContinuumReleaseResult.class );
2694     }
2695 
2696     private RepositoryPurgeConfiguration populateRepositoryPurgeConfiguration(
2697         org.apache.continuum.model.repository.RepositoryPurgeConfiguration repoPurgeConfig )
2698     {
2699         return (RepositoryPurgeConfiguration) mapper.map( repoPurgeConfig, RepositoryPurgeConfiguration.class );
2700     }
2701 
2702     private org.apache.continuum.model.repository.RepositoryPurgeConfiguration populateRepositoryPurgeConfiguration(
2703         RepositoryPurgeConfiguration repoPurgeConfig,
2704         org.apache.continuum.model.repository.RepositoryPurgeConfiguration repoPurge )
2705         throws RepositoryServiceException, ContinuumException
2706     {
2707         if ( repoPurgeConfig == null )
2708         {
2709             return null;
2710         }
2711 
2712         repoPurge.setDaysOlder( repoPurgeConfig.getDaysOlder() );
2713         repoPurge.setDefaultPurge( repoPurgeConfig.isDefaultPurge() );
2714         repoPurge.setDeleteAll( repoPurgeConfig.isDeleteAll() );
2715         repoPurge.setDeleteReleasedSnapshots( repoPurgeConfig.isDeleteReleasedSnapshots() );
2716         repoPurge.setDescription( StringEscapeUtils.escapeXml( repoPurgeConfig.getDescription() ) );
2717         repoPurge.setEnabled( repoPurgeConfig.isEnabled() );
2718         repoPurge.setRetentionCount( repoPurgeConfig.getRetentionCount() );
2719         if ( repoPurgeConfig.getRepository() != null )
2720         {
2721             repoPurge.setRepository( populateLocalRepository( repoPurgeConfig.getRepository(),
2722                                                               continuum.getRepositoryService().getLocalRepository(
2723                                                                   repoPurgeConfig.getRepository().getId() ) ) );
2724         }
2725         else
2726         {
2727             repoPurge.setRepository( null );
2728         }
2729         if ( repoPurgeConfig.getSchedule() != null )
2730         {
2731             repoPurge.setSchedule( populateSchedule( repoPurgeConfig.getSchedule(), continuum.getSchedule(
2732                 repoPurgeConfig.getSchedule().getId() ) ) );
2733         }
2734         else
2735         {
2736             repoPurge.setSchedule( null );
2737         }
2738 
2739         return repoPurge;
2740     }
2741 
2742     private DirectoryPurgeConfiguration populateDirectoryPurgeConfiguration(
2743         org.apache.continuum.model.repository.DirectoryPurgeConfiguration dirPurgeConfig )
2744     {
2745         return (DirectoryPurgeConfiguration) mapper.map( dirPurgeConfig, DirectoryPurgeConfiguration.class );
2746     }
2747 
2748     private org.apache.continuum.model.repository.DirectoryPurgeConfiguration populateDirectoryPurgeConfiguration(
2749         DirectoryPurgeConfiguration dirPurgeConfig,
2750         org.apache.continuum.model.repository.DirectoryPurgeConfiguration dirPurge )
2751         throws RepositoryServiceException, ContinuumException
2752     {
2753         if ( dirPurgeConfig == null )
2754         {
2755             return null;
2756         }
2757 
2758         if ( StringUtils.isNotBlank( dirPurgeConfig.getDirectoryType() ) && !dirPurgeConfig.getDirectoryType().matches(
2759             DIRECTORY_TYPE_VALID_EXPRESSION ) )
2760         {
2761             throw new ContinuumException( "Directory Purge Configuration Type can only be 'releases or buildOutput'" );
2762         }
2763 
2764         if ( StringUtils.isNotBlank( dirPurgeConfig.getLocation() ) && !dirPurgeConfig.getLocation().matches(
2765             DIRECTORY_VALID_EXPRESSION ) )
2766         {
2767             throw new ContinuumException( "Directory Purge Configuration Location contains invalid characters" );
2768         }
2769 
2770         dirPurge.setDaysOlder( dirPurgeConfig.getDaysOlder() );
2771         dirPurge.setDefaultPurge( dirPurgeConfig.isDefaultPurge() );
2772         dirPurge.setDeleteAll( dirPurgeConfig.isDeleteAll() );
2773         dirPurge.setDescription( StringEscapeUtils.escapeXml( dirPurgeConfig.getDescription() ) );
2774         dirPurge.setDirectoryType( dirPurgeConfig.getDirectoryType() );
2775         dirPurge.setEnabled( dirPurgeConfig.isEnabled() );
2776 
2777         String path = "";
2778 
2779         if ( dirPurge.getDirectoryType().equals( "releases" ) )
2780         {
2781             path = continuum.getConfiguration().getWorkingDirectory().getAbsolutePath();
2782         }
2783         else if ( dirPurge.getDirectoryType().equals( "buildOutput" ) )
2784         {
2785             path = continuum.getConfiguration().getBuildOutputDirectory().getAbsolutePath();
2786         }
2787 
2788         dirPurge.setLocation( path );
2789         dirPurge.setRetentionCount( dirPurgeConfig.getRetentionCount() );
2790         if ( dirPurgeConfig.getSchedule() != null )
2791         {
2792             dirPurge.setSchedule( populateSchedule( dirPurgeConfig.getSchedule(), continuum.getSchedule(
2793                 dirPurgeConfig.getSchedule().getId() ) ) );
2794         }
2795         else
2796         {
2797             dirPurge.setSchedule( null );
2798         }
2799 
2800         return dirPurge;
2801     }
2802 
2803     private LocalRepository populateLocalRepository(
2804         org.apache.continuum.model.repository.LocalRepository localRepository )
2805     {
2806         return (LocalRepository) mapper.map( localRepository, LocalRepository.class );
2807     }
2808 
2809     private org.apache.continuum.model.repository.LocalRepository populateLocalRepository( LocalRepository repository,
2810                                                                                            org.apache.continuum.model.repository.LocalRepository repo )
2811         throws ContinuumException
2812     {
2813         if ( repository == null )
2814         {
2815             return null;
2816         }
2817 
2818         if ( StringUtils.isNotBlank( repository.getLayout() ) && !repository.getLayout().matches(
2819             REPOSITORY_LAYOUT_VALID_EXPRESSION ) )
2820         {
2821             throw new ContinuumException( "Repository Layout can only be 'default or legacy'" );
2822         }
2823 
2824         if ( StringUtils.isNotBlank( repository.getLocation() ) && !repository.getLocation().matches(
2825             DIRECTORY_VALID_EXPRESSION ) )
2826         {
2827             throw new ContinuumException( "Repository Location contains invalid characters" );
2828         }
2829 
2830         if ( StringUtils.isNotBlank( repository.getName() ) && !repository.getName().matches( NAME_VALID_EXPRESSION ) )
2831         {
2832             throw new ContinuumException( "Repository Name contains invalid characters" );
2833         }
2834 
2835         repo.setLayout( repository.getLayout() );
2836         repo.setLocation( repository.getLocation() );
2837         repo.setName( repository.getName() );
2838         return repo;
2839     }
2840 
2841     private org.apache.continuum.utils.build.BuildTrigger populateBuildTrigger( BuildTrigger buildTrigger )
2842         throws ContinuumException
2843     {
2844         if ( buildTrigger == null )
2845         {
2846             return null;
2847         }
2848 
2849         if ( StringUtils.isNotBlank( buildTrigger.getTriggeredBy() ) && !buildTrigger.getTriggeredBy().matches(
2850             USERNAME_VALID_EXPRESSION ) )
2851         {
2852             throw new ContinuumException( "BuildTrigger Triggered By contains invalid characters" );
2853         }
2854 
2855         return new org.apache.continuum.utils.build.BuildTrigger( buildTrigger.getTrigger(),
2856                                                                   buildTrigger.getTriggeredBy() );
2857     }
2858 
2859     private org.apache.continuum.configuration.BuildAgentConfiguration populateBuildAgent(
2860         BuildAgentConfiguration buildAgent )
2861         throws ContinuumException
2862     {
2863         if ( buildAgent == null )
2864         {
2865             return null;
2866         }
2867 
2868         if ( StringUtils.isNotBlank( buildAgent.getUrl() ) && !buildAgent.getUrl().matches( URL_VALID_EXPRESSION ) )
2869         {
2870             throw new ContinuumException( "Build Agent URL contains invalid characters" );
2871         }
2872 
2873         org.apache.continuum.configuration.BuildAgentConfiguration buildAgentConfiguration =
2874             new org.apache.continuum.configuration.BuildAgentConfiguration();
2875         buildAgentConfiguration.setUrl( buildAgent.getUrl() );
2876         buildAgentConfiguration.setDescription( StringEscapeUtils.escapeXml( buildAgent.getDescription() ) );
2877         buildAgentConfiguration.setEnabled( buildAgent.isEnabled() );
2878         return buildAgentConfiguration;
2879     }
2880 
2881     private BuildAgentConfiguration populateBuildAgent(
2882         org.apache.continuum.configuration.BuildAgentConfiguration buildAgent )
2883     {
2884         BuildAgentConfiguration buildAgentConfiguration = (BuildAgentConfiguration) mapper.map( buildAgent,
2885                                                                                                 BuildAgentConfiguration.class );
2886         try
2887         {
2888             buildAgentConfiguration.setPlatform( distributedBuildManager.getBuildAgentPlatform(
2889                 buildAgentConfiguration.getUrl() ) );
2890             return buildAgentConfiguration;
2891         }
2892         catch ( ContinuumException e )
2893         {
2894             logger.warn( "Unable to connect to build agent " + buildAgentConfiguration.getUrl() + ".", e );
2895             buildAgentConfiguration.setPlatform( "" );
2896             return buildAgentConfiguration;
2897         }
2898     }
2899 
2900     private org.apache.continuum.configuration.BuildAgentGroupConfiguration populateBuildAgentGroup(
2901         BuildAgentGroupConfiguration buildAgentGroup )
2902         throws ContinuumException
2903     {
2904         if ( buildAgentGroup == null )
2905         {
2906             return null;
2907         }
2908 
2909         org.apache.continuum.configuration.BuildAgentGroupConfiguration buildAgentGroupConfiguration =
2910             new org.apache.continuum.configuration.BuildAgentGroupConfiguration();
2911 
2912         if ( StringUtils.isBlank( buildAgentGroup.getName() ) )
2913         {
2914             throw new ContinuumException( "Build agent group name is required" );
2915         }
2916 
2917         buildAgentGroupConfiguration.setName( StringEscapeUtils.escapeXml( buildAgentGroup.getName() ) );
2918 
2919         buildAgentGroupConfiguration.getBuildAgents().clear();
2920         if ( buildAgentGroup.getBuildAgents() != null )
2921         {
2922             for ( BuildAgentConfiguration buildAgent : buildAgentGroup.getBuildAgents() )
2923             {
2924                 buildAgentGroupConfiguration.getBuildAgents().add( populateBuildAgent( buildAgent ) );
2925             }
2926         }
2927         return buildAgentGroupConfiguration;
2928     }
2929 
2930     private BuildAgentGroupConfiguration populateBuildAgentGroup(
2931         org.apache.continuum.configuration.BuildAgentGroupConfiguration buildAgentGroup )
2932     {
2933         return (BuildAgentGroupConfiguration) mapper.map( buildAgentGroup, BuildAgentGroupConfiguration.class );
2934     }
2935 
2936     private Map<String, Object> serializeObject( Object o, final String... ignore )
2937     {
2938         if ( o != null )
2939         {
2940             return serializeObject( o, o.getClass(), ignore );
2941         }
2942         else
2943         {
2944             return null;
2945         }
2946     }
2947 
2948     private Map<String, Object> serializeObject( Object o, Class clasz, final String... ignore )
2949     {
2950 
2951         final List<String> ignoreList = ignore == null ? new ArrayList<String>() : Arrays.asList( ignore );
2952         if ( o != null )
2953         {
2954             final Map<String, Object> retValue = new HashMap<String, Object>();
2955             if ( !Object.class.equals( clasz.getSuperclass() ) )
2956             {
2957                 retValue.putAll( serializeObject( o, clasz.getSuperclass(), ignore ) );
2958             }
2959 
2960             final Field[] fields = clasz.getDeclaredFields();
2961 
2962             retValue.put( "__class", clasz.getName() );
2963             for ( final Field field : fields )
2964             {
2965 
2966                 if ( !ignoreList.contains( field.getName() ) )
2967                 {
2968                     field.setAccessible( true );
2969                     try
2970                     {
2971                         final Object tmpFO = field.get( o );
2972                         final Object tmpNO = mapObject( tmpFO );
2973 
2974                         retValue.put( field.getName(), tmpNO );
2975                     }
2976                     catch ( IllegalAccessException e )
2977                     {
2978                         e.printStackTrace();
2979                     }
2980                 }
2981             }
2982             return retValue;
2983         }
2984         else
2985         {
2986             return null;
2987         }
2988     }
2989 
2990     private Object mapObject( Object tmpFO )
2991     {
2992         final Object retValue;
2993         if ( tmpFO instanceof String )
2994         {
2995             Object tmpNO = serializeObject( (String) tmpFO );
2996             if ( tmpNO == null )
2997             {
2998                 tmpNO = "";
2999             }
3000             retValue = tmpNO;
3001         }
3002         else if ( tmpFO instanceof Float )
3003         {
3004             Object tmpNO = serializeObject( (Float) tmpFO );
3005             if ( tmpNO == null )
3006             {
3007                 tmpNO = "";
3008             }
3009             retValue = tmpNO;
3010         }
3011         else if ( tmpFO instanceof Boolean )
3012         {
3013             Object tmpNO = serializeObject( (Boolean) tmpFO );
3014             if ( tmpNO == null )
3015             {
3016                 tmpNO = "";
3017             }
3018             retValue = tmpNO;
3019         }
3020         else if ( tmpFO instanceof Integer )
3021         {
3022             Object tmpNO = serializeObject( (Integer) tmpFO );
3023             if ( tmpNO == null )
3024             {
3025                 tmpNO = "";
3026             }
3027             retValue = tmpNO;
3028         }
3029         else if ( tmpFO instanceof Long )
3030         {
3031             Object tmpNO = serializeObject( (Long) tmpFO );
3032             if ( tmpNO == null )
3033             {
3034                 tmpNO = "";
3035             }
3036             retValue = tmpNO;
3037         }
3038         else if ( tmpFO instanceof Character )
3039         {
3040             Object tmpNO = serializeObject( (Character) tmpFO );
3041             if ( tmpNO == null )
3042             {
3043                 tmpNO = "";
3044             }
3045             retValue = tmpNO;
3046         }
3047         else if ( tmpFO instanceof Byte )
3048         {
3049             Object tmpNO = serializeObject( (Byte) tmpFO );
3050             if ( tmpNO == null )
3051             {
3052                 tmpNO = "";
3053             }
3054             retValue = tmpNO;
3055         }
3056         else if ( tmpFO instanceof Double )
3057         {
3058             Object tmpNO = serializeObject( (Double) tmpFO );
3059             if ( tmpNO == null )
3060             {
3061                 tmpNO = "";
3062             }
3063             retValue = tmpNO;
3064         }
3065         else if ( tmpFO instanceof List )
3066         {
3067             Object tmpNO = serializeObject( (List) tmpFO );
3068             if ( tmpNO == null )
3069             {
3070                 tmpNO = "";
3071             }
3072             retValue = tmpNO;
3073         }
3074         else if ( tmpFO instanceof Map )
3075         {
3076             Object tmpNO = serializeObject( (Map) tmpFO );
3077             if ( tmpNO == null )
3078             {
3079                 tmpNO = "";
3080             }
3081             retValue = tmpNO;
3082         }
3083         else
3084         {
3085             Object tmpNO = serializeObject( tmpFO );
3086             if ( tmpNO == null )
3087             {
3088                 tmpNO = "";
3089             }
3090             retValue = tmpNO;
3091         }
3092         return retValue;
3093     }
3094 
3095     private Map<String, Object> serializeObject( Map<Object, Object> map )
3096     {
3097         final Map<String, Object> retValue = new HashMap<String, Object>();
3098 
3099         for ( Object key : map.keySet() )
3100         {
3101             final Object tmpKey = mapObject( key );
3102 
3103             if ( tmpKey != null )
3104             {
3105                 retValue.put( tmpKey.toString(), mapObject( map.get( key ) ) );
3106             }
3107         }
3108         return retValue;
3109     }
3110 
3111     private List<Object> serializeObject( List list )
3112     {
3113         final List<Object> retValue = new ArrayList<Object>();
3114 
3115         for ( Object o : list )
3116         {
3117             final Object tmpO = mapObject( o );
3118             if ( tmpO == null )
3119             {
3120                 retValue.add( "" );
3121             }
3122             else
3123             {
3124                 retValue.add( tmpO );
3125             }
3126         }
3127         return retValue;
3128     }
3129 
3130     private String serializeObject( String o )
3131     {
3132         return o;
3133     }
3134 
3135     private String serializeObject( Byte o )
3136     {
3137         return ( o == null ? null : o.toString() );
3138     }
3139 
3140     private String serializeObject( Character o )
3141     {
3142         return ( o == null ? null : o.toString() );
3143     }
3144 
3145     private Double serializeObject( Long o )
3146     {
3147         return ( o == null ? null : o.doubleValue() );
3148     }
3149 
3150     private Double serializeObject( Float o )
3151     {
3152         return ( o == null ? null : o.doubleValue() );
3153     }
3154 
3155     private Double serializeObject( Double o )
3156     {
3157         return o;
3158     }
3159 
3160     private Integer serializeObject( Integer o )
3161     {
3162         return o;
3163     }
3164 
3165     private Boolean serializeObject( Boolean o )
3166     {
3167         return o;
3168     }
3169 
3170     private Object unserializeObject( Map<String, Object> o )
3171     {
3172         Object retValue = null;
3173         if ( o != null )
3174         {
3175             final String className = (String) o.remove( "__class" );
3176 
3177             if ( className != null )
3178             {
3179                 try
3180                 {
3181                     final Class clasz = Class.forName( className );
3182                     final Object tmpO = clasz.newInstance();
3183                     for ( final String key : o.keySet() )
3184                     {
3185                         final Field field = clasz.getDeclaredField( key );
3186                         field.setAccessible( true );
3187                         final Object tmpFO = o.get( key );
3188 
3189                         field.set( tmpO, unMapObject( tmpFO ) );
3190                     }
3191                     retValue = tmpO;
3192                 }
3193                 catch ( Exception e )
3194                 {
3195                     e.printStackTrace();
3196                     retValue = null;
3197                 }
3198             }
3199             else
3200             {
3201                 // Not an object, it's a normal Map
3202                 Map<String, Object> tmpValue = new HashMap<String, Object>();
3203 
3204                 for ( String key : o.keySet() )
3205                 {
3206                     tmpValue.put( key, unMapObject( o.get( key ) ) );
3207                 }
3208                 retValue = tmpValue;
3209             }
3210         }
3211         return retValue;
3212     }
3213 
3214     private Object unMapObject( Object tmpFO )
3215     {
3216         final Object retValue;
3217         if ( tmpFO instanceof String )
3218         {
3219             retValue = unserializeObject( (String) tmpFO );
3220         }
3221         else if ( tmpFO instanceof Float )
3222         {
3223             retValue = unserializeObject( (Float) tmpFO );
3224         }
3225         else if ( tmpFO instanceof Boolean )
3226         {
3227             retValue = unserializeObject( (Boolean) tmpFO );
3228         }
3229         else if ( tmpFO instanceof Integer )
3230         {
3231             retValue = unserializeObject( (Integer) tmpFO );
3232         }
3233         else if ( tmpFO instanceof Long )
3234         {
3235             retValue = unserializeObject( (Long) tmpFO );
3236         }
3237         else if ( tmpFO instanceof Character )
3238         {
3239             retValue = unserializeObject( (Character) tmpFO );
3240         }
3241         else if ( tmpFO instanceof Byte )
3242         {
3243             retValue = unserializeObject( (Byte) tmpFO );
3244         }
3245         else if ( tmpFO instanceof Double )
3246         {
3247             retValue = unserializeObject( (Double) tmpFO );
3248         }
3249         else if ( tmpFO instanceof List )
3250         {
3251             retValue = unserializeObject( (List) tmpFO );
3252         }
3253         else if ( tmpFO instanceof Map )
3254         {
3255             retValue = unserializeObject( (Map) tmpFO );
3256         }
3257         else if ( tmpFO instanceof Object[] )
3258         {
3259             retValue = unserializeObject( (Object[]) tmpFO );
3260         }
3261         else
3262         {
3263             retValue = unserializeObject( tmpFO );
3264         }
3265         return retValue;
3266     }
3267 
3268     private List<Object> unserializeObject( List list )
3269     {
3270         final List<Object> retValue = new ArrayList<Object>();
3271 
3272         for ( Object o : list )
3273         {
3274             retValue.add( unMapObject( o ) );
3275         }
3276         return retValue;
3277     }
3278 
3279     private Object unserializeObject( Object o )
3280     {
3281         return o;
3282     }
3283 
3284     private Object unserializeObject( Object[] list )
3285     {
3286         final List<Object> retValue = new ArrayList<Object>();
3287 
3288         for ( Object o : list )
3289         {
3290             retValue.add( unMapObject( o ) );
3291         }
3292         return retValue;
3293     }
3294 
3295     private String unserializeObject( String o )
3296     {
3297         return o;
3298     }
3299 
3300     private Byte unserializeObject( Byte o )
3301     {
3302         return o;
3303     }
3304 
3305     private Character unserializeObject( Character o )
3306     {
3307         return o;
3308     }
3309 
3310     private Long unserializeObject( Long o )
3311     {
3312         return o;
3313     }
3314 
3315     private Float unserializeObject( Float o )
3316     {
3317         return o;
3318     }
3319 
3320     private Double unserializeObject( Double o )
3321     {
3322         return o;
3323     }
3324 
3325     private Integer unserializeObject( Integer o )
3326     {
3327         return o;
3328     }
3329 
3330     private Boolean unserializeObject( Boolean o )
3331     {
3332         return o;
3333     }
3334 
3335     public Map<String, Object> addAntProjectRPC( Map<String, Object> project, int projectGroupId )
3336         throws Exception
3337     {
3338         return serializeObject( this.addAntProject( (ProjectSummary) unserializeObject( project ), projectGroupId ) );
3339     }
3340 
3341     public Map<String, Object> addBuildDefinitionToProjectGroupRPC( int projectGroupId, Map<String, Object> buildDef )
3342         throws Exception
3343     {
3344         return serializeObject( this.addBuildDefinitionToProjectGroup( projectGroupId,
3345                                                                        (BuildDefinition) unserializeObject( buildDef ) ) );
3346     }
3347 
3348     public Map<String, Object> addBuildDefinitionToProjectRPC( int projectId, Map<String, Object> buildDef )
3349         throws Exception
3350     {
3351         return serializeObject( this.addBuildDefinitionToProject( projectId, (BuildDefinition) unserializeObject(
3352             buildDef ) ) );
3353     }
3354 
3355     public Map<String, Object> addMavenOneProjectRPC( String url, int projectGroupId )
3356         throws Exception
3357     {
3358         return serializeObject( this.addMavenOneProject( url, projectGroupId ) );
3359     }
3360 
3361     public Map<String, Object> addMavenTwoProjectRPC( String url )
3362         throws Exception
3363     {
3364         return serializeObject( this.addMavenTwoProject( url ) );
3365     }
3366 
3367     public Map<String, Object> addMavenTwoProjectRPC( String url, int projectGroupId )
3368         throws Exception
3369     {
3370         return serializeObject( this.addMavenTwoProject( url, projectGroupId ) );
3371     }
3372 
3373     public Map<String, Object> addMavenTwoProjectRPC( String url, int projectGroupId,
3374                                                       boolean checkoutInSingleDirectory )
3375         throws Exception
3376     {
3377         return serializeObject( this.addMavenTwoProject( url, projectGroupId, checkoutInSingleDirectory ) );
3378     }
3379 
3380     public Map<String, Object> addMavenTwoProjectAsSingleProjectRPC( String url, int projectGroupId )
3381         throws Exception
3382     {
3383         return serializeObject( this.addMavenTwoProjectAsSingleProject( url, projectGroupId ) );
3384     }
3385 
3386     public Map<String, Object> addMavenTwoProjectRPC( String url, int projectGroupId, boolean checkProtocol,
3387                                                       boolean useCredentialsCache, boolean recursiveProjects,
3388                                                       boolean checkoutInSingleDirectory )
3389         throws Exception
3390     {
3391         return serializeObject( this.addMavenTwoProject( url, projectGroupId, checkProtocol, useCredentialsCache,
3392                                                          recursiveProjects, checkoutInSingleDirectory ) );
3393     }
3394 
3395     public Map<String, Object> addProjectGroupRPC( String groupName, String groupId, String description )
3396         throws Exception
3397     {
3398         return serializeObject( this.addProjectGroup( groupName, groupId, description ) );
3399     }
3400 
3401     public Map<String, Object> addScheduleRPC( Map<String, Object> schedule )
3402         throws Exception
3403     {
3404         return serializeObject( this.addSchedule( (Schedule) unserializeObject( schedule ) ) );
3405     }
3406 
3407     public Map<String, Object> addShellProjectRPC( Map<String, Object> project, int projectGroupId )
3408         throws Exception
3409     {
3410         return serializeObject( this.addShellProject( (ProjectSummary) unserializeObject( project ), projectGroupId ) );
3411     }
3412 
3413     public List<Object> getAllProjectGroupsRPC()
3414         throws Exception
3415     {
3416         return serializeObject( this.getAllProjectGroups() );
3417     }
3418 
3419     public List<Object> getAllProjectGroupsWithAllDetailsRPC()
3420         throws Exception
3421     {
3422         return serializeObject( this.getAllProjectGroupsWithAllDetails() );
3423     }
3424 
3425     public List<Object> getBuildDefinitionTemplatesRPC()
3426         throws Exception
3427     {
3428         return serializeObject( this.getBuildDefinitionTemplates() );
3429     }
3430 
3431     public List<Object> getBuildDefinitionsForProjectGroupRPC( int projectGroupId )
3432         throws Exception
3433     {
3434         return serializeObject( this.getBuildDefinitionsForProjectGroup( projectGroupId ) );
3435     }
3436 
3437     public List<Object> getBuildDefinitionsForProjectRPC( int projectId )
3438         throws Exception
3439     {
3440         return serializeObject( this.getBuildDefinitionsForProject( projectId ) );
3441     }
3442 
3443     public Map<String, Object> getBuildDefinitionRPC( int buildDefinitionId )
3444         throws Exception
3445     {
3446         return serializeObject( this.getBuildDefinition( buildDefinitionId ) );
3447     }
3448 
3449     public Map<String, Object> getBuildResultRPC( int projectId, int buildId )
3450         throws Exception
3451     {
3452         return serializeObject( this.getBuildResult( projectId, buildId ) );
3453     }
3454 
3455     public List<Object> getBuildResultsForProjectRPC( int projectId )
3456         throws Exception
3457     {
3458         return serializeObject( this.getBuildResultsForProject( projectId ) );
3459     }
3460 
3461     public Map<String, Object> getInstallationRPC( int installationId )
3462         throws Exception
3463     {
3464         return serializeObject( this.getInstallation( installationId ) );
3465     }
3466 
3467     public Map<String, Object> getInstallationRPC( String installationName )
3468         throws Exception
3469     {
3470         return serializeObject( this.getInstallation( installationName ) );
3471     }
3472 
3473     public List<Object> getInstallationsRPC()
3474         throws Exception
3475     {
3476         return serializeObject( this.getInstallations() );
3477     }
3478 
3479     public List<Object> getBuildAgentInstallationsRPC( String url )
3480         throws Exception
3481     {
3482         return serializeObject( this.getBuildAgentInstallations( url ) );
3483     }
3484 
3485     public Map<String, Object> getLatestBuildResultRPC( int projectId )
3486         throws Exception
3487     {
3488         return serializeObject( this.getLatestBuildResult( projectId ) );
3489     }
3490 
3491     public Map<String, Object> getProfileRPC( int profileId )
3492         throws Exception
3493     {
3494         return serializeObject( this.getProfile( profileId ) );
3495     }
3496 
3497     public Map<String, Object> getProfileWithNameRPC( String profileName )
3498         throws Exception
3499     {
3500         return serializeObject( this.getProfileWithName( profileName ) );
3501     }
3502 
3503     public List<Object> getProfilesRPC()
3504         throws Exception
3505     {
3506         return serializeObject( this.getProfiles() );
3507     }
3508 
3509     public Map<String, Object> getProjectGroupSummaryRPC( int projectGroupId )
3510         throws Exception
3511     {
3512         return serializeObject( this.getProjectGroupSummary( projectGroupId ) );
3513     }
3514 
3515     public Map<String, Object> getProjectGroupWithProjectsRPC( int projectGroupId )
3516         throws Exception
3517     {
3518         return serializeObject( this.getProjectGroupWithProjects( projectGroupId ) );
3519     }
3520 
3521     public Map<String, Object> updateProjectGroupRPC( Map<String, Object> projectGroup )
3522         throws Exception
3523     {
3524         return serializeObject( this.updateProjectGroup( (ProjectGroupSummary) unserializeObject( projectGroup ) ) );
3525     }
3526 
3527     public Map<String, Object> getProjectSummaryRPC( int projectId )
3528         throws Exception
3529     {
3530         return serializeObject( this.getProjectSummary( projectId ) );
3531     }
3532 
3533     public Map<String, Object> getProjectWithAllDetailsRPC( int projectId )
3534         throws Exception
3535     {
3536         return serializeObject( this.getProjectWithAllDetails( projectId ) );
3537     }
3538 
3539     public List<Object> getProjectsRPC( int projectGroupId )
3540         throws Exception
3541     {
3542         return serializeObject( this.getProjects( projectGroupId ) );
3543     }
3544 
3545     public Map<String, Object> getScheduleRPC( int scheduleId )
3546         throws Exception
3547     {
3548         return serializeObject( this.getSchedule( scheduleId ) );
3549     }
3550 
3551     public List<Object> getSchedulesRPC()
3552         throws Exception
3553     {
3554         return serializeObject( this.getSchedules() );
3555     }
3556 
3557     public Map<String, Object> getSystemConfigurationRPC()
3558         throws Exception
3559     {
3560         return serializeObject( this.getSystemConfiguration() );
3561     }
3562 
3563     public int removeBuildResultRPC( Map<String, Object> br )
3564         throws Exception
3565     {
3566         return serializeObject( this.removeBuildResult( (BuildResult) unserializeObject( br ) ) );
3567     }
3568 
3569     public Map<String, Object> updateBuildDefinitionForProjectGroupRPC( int projectGroupId,
3570                                                                         Map<String, Object> buildDef )
3571         throws Exception
3572     {
3573         return serializeObject( this.updateBuildDefinitionForProjectGroup( projectGroupId,
3574                                                                            (BuildDefinition) unserializeObject(
3575                                                                                buildDef ) ) );
3576     }
3577 
3578     public Map<String, Object> updateBuildDefinitionForProjectRPC( int projectId, Map<String, Object> buildDef )
3579         throws Exception
3580     {
3581         return serializeObject( this.updateBuildDefinitionForProject( projectId, (BuildDefinition) unserializeObject(
3582             buildDef ) ) );
3583     }
3584 
3585     public Map<String, Object> updateProjectRPC( Map<String, Object> project )
3586         throws Exception
3587     {
3588         return serializeObject( this.updateProject( (ProjectSummary) unserializeObject( project ) ) );
3589     }
3590 
3591     public Map<String, Object> updateScheduleRPC( Map<String, Object> schedule )
3592         throws Exception
3593     {
3594         return serializeObject( this.updateSchedule( (Schedule) unserializeObject( schedule ) ) );
3595     }
3596 
3597     public Map<String, Object> getProjectGroupRPC( int projectGroupId )
3598         throws Exception
3599     {
3600         return serializeObject( this.getProjectGroup( projectGroupId ), "projects" );
3601     }
3602 
3603     public Map<String, Object> getGroupNotifierRPC( int projectgroupid, int notifierId )
3604         throws Exception
3605     {
3606         return serializeObject( this.getGroupNotifier( projectgroupid, notifierId ) );
3607     }
3608 
3609     public Map<String, Object> getNotifierRPC( int projectid, int notifierId )
3610         throws Exception
3611     {
3612         return serializeObject( this.getNotifier( projectid, notifierId ) );
3613     }
3614 
3615     public Map<String, Object> updateGroupNotifierRPC( int projectgroupid, Map<String, Object> newNotifier )
3616         throws Exception
3617     {
3618         return serializeObject( this.updateGroupNotifier( projectgroupid, (ProjectNotifier) unserializeObject(
3619             newNotifier ) ) );
3620     }
3621 
3622     public Map<String, Object> updateNotifierRPC( int projectid, Map<String, Object> newNotifier )
3623         throws Exception
3624     {
3625         return serializeObject( this.updateNotifier( projectid, (ProjectNotifier) unserializeObject( newNotifier ) ) );
3626     }
3627 
3628     public Map<String, Object> addGroupNotifierRPC( int projectgroupid, Map<String, Object> newNotifier )
3629         throws Exception
3630     {
3631         return serializeObject( this.addGroupNotifier( projectgroupid, (ProjectNotifier) unserializeObject(
3632             newNotifier ) ) );
3633     }
3634 
3635     public Map<String, Object> addNotifierRPC( int projectid, Map<String, Object> newNotifier )
3636         throws Exception
3637     {
3638         return serializeObject( this.addNotifier( projectid, (ProjectNotifier) unserializeObject( newNotifier ) ) );
3639     }
3640 
3641     public Map<String, Object> addInstallationRPC( Map<String, Object> installation )
3642         throws Exception
3643     {
3644         return serializeObject( this.addInstallation( (Installation) unserializeObject( installation ) ) );
3645     }
3646 
3647     public Map<String, Object> addProfileRPC( Map<String, Object> profile )
3648         throws Exception
3649     {
3650         return serializeObject( this.addProfile( (Profile) unserializeObject( profile ) ) );
3651     }
3652 
3653     public int updateInstallationRPC( Map<String, Object> installation )
3654         throws Exception
3655     {
3656         return this.updateInstallation( (Installation) unserializeObject( installation ) );
3657     }
3658 
3659     public int updateProfileRPC( Map<String, Object> profile )
3660         throws Exception
3661     {
3662         return this.updateProfile( (Profile) unserializeObject( profile ) );
3663     }
3664 
3665     public Map<String, Object> getReleaseResultRPC( int releaseId )
3666         throws Exception
3667     {
3668         return serializeObject( this.getReleaseResult( releaseId ) );
3669     }
3670 
3671     public List<Object> getReleaseResultsForProjectGroupRPC( int projectGroupId )
3672         throws Exception
3673     {
3674         return serializeObject( this.getReleaseResultsForProjectGroup( projectGroupId ) );
3675     }
3676 
3677     public int removeReleaseResultRPC( Map<String, Object> rr )
3678         throws Exception
3679     {
3680         return serializeObject( this.removeReleaseResult( (ContinuumReleaseResult) unserializeObject( rr ) ) );
3681     }
3682 
3683     public Map<String, Object> addRepositoryPurgeConfigurationRPC( Map<String, Object> repoPurge )
3684         throws Exception
3685     {
3686         return serializeObject( this.addRepositoryPurgeConfiguration( (RepositoryPurgeConfiguration) unserializeObject(
3687             repoPurge ) ) );
3688     }
3689 
3690     public int updateRepositoryPurgeConfigurationRPC( Map<String, Object> repoPurge )
3691         throws Exception
3692     {
3693         return serializeObject( this.updateRepositoryPurgeConfiguration(
3694             (RepositoryPurgeConfiguration) unserializeObject( repoPurge ) ) );
3695     }
3696 
3697     public Map<String, Object> getRepositoryPurgeConfigurationRPC( int repoPurgeId )
3698         throws Exception
3699     {
3700         return serializeObject( this.getRepositoryPurgeConfiguration( repoPurgeId ) );
3701     }
3702 
3703     public List<Object> getAllRepositoryPurgeConfigurationsRPC()
3704         throws Exception
3705     {
3706         return serializeObject( this.getAllDirectoryPurgeConfigurations() );
3707     }
3708 
3709     public Map<String, Object> addDirectoryPurgeConfigurationRPC( Map<String, Object> dirPurge )
3710         throws Exception
3711     {
3712         return serializeObject( this.addDirectoryPurgeConfiguration( (DirectoryPurgeConfiguration) unserializeObject(
3713             dirPurge ) ) );
3714     }
3715 
3716     public int updateDirectoryPurgeConfigurationRPC( Map<String, Object> dirPurge )
3717         throws Exception
3718     {
3719         return serializeObject( this.updateDirectoryPurgeConfiguration( (DirectoryPurgeConfiguration) unserializeObject(
3720             dirPurge ) ) );
3721     }
3722 
3723     public Map<String, Object> getDirectoryPurgeConfigurationRPC( int dirPurgeId )
3724         throws Exception
3725     {
3726         return serializeObject( this.getDirectoryPurgeConfiguration( dirPurgeId ) );
3727     }
3728 
3729     public List<Object> getAllDirectoryPurgeConfigurationsRPC()
3730         throws Exception
3731     {
3732         return serializeObject( this.getAllRepositoryPurgeConfigurations() );
3733     }
3734 
3735     public Map<String, Object> addLocalRepositoryRPC( Map<String, Object> repository )
3736         throws Exception
3737     {
3738         return serializeObject( this.addLocalRepository( (LocalRepository) unserializeObject( repository ) ) );
3739     }
3740 
3741     public int updateLocalRepositoryRPC( Map<String, Object> repository )
3742         throws Exception
3743     {
3744         return serializeObject( this.updateLocalRepository( (LocalRepository) unserializeObject( repository ) ) );
3745     }
3746 
3747     public Map<String, Object> getLocalRepositoryRPC( int repositoryId )
3748         throws Exception
3749     {
3750         return serializeObject( this.getLocalRepository( repositoryId ) );
3751     }
3752 
3753     public List<Object> getAllLocalRepositoriesRPC()
3754         throws Exception
3755     {
3756         return serializeObject( this.getAllLocalRepositories() );
3757     }
3758 
3759     public Map<String, Object> addBuildAgentRPC( Map<String, Object> buildAgentConfiguration )
3760         throws Exception
3761     {
3762         return serializeObject( this.addBuildAgent( (BuildAgentConfiguration) unserializeObject(
3763             buildAgentConfiguration ) ) );
3764     }
3765 
3766     public Map<String, Object> getBuildAgentRPC( String url )
3767     {
3768         return serializeObject( this.getBuildAgent( url ) );
3769     }
3770 
3771     public Map<String, Object> updateBuildAgentRPC( Map<String, Object> buildAgentConfiguration )
3772         throws ConfigurationStoringException, ContinuumConfigurationException
3773     {
3774         return serializeObject( this.updateBuildAgent( (BuildAgentConfiguration) unserializeObject(
3775             buildAgentConfiguration ) ) );
3776     }
3777 
3778     public List<Object> getAllBuildAgentsRPC()
3779     {
3780         return serializeObject( this.getAllBuildAgents() );
3781     }
3782 
3783     public List<Object> getBuildAgentsWithInstallationsRPC()
3784         throws Exception
3785     {
3786         return serializeObject( this.getBuildAgentsWithInstallations() );
3787     }
3788 
3789     public Map<String, Object> addBuildAgentGroupRPC( Map<String, Object> buildAgentGroup )
3790         throws ConfigurationException, ConfigurationStoringException, ContinuumConfigurationException
3791     {
3792         return serializeObject( this.addBuildAgentGroup( (BuildAgentGroupConfiguration) unserializeObject(
3793             buildAgentGroup ) ) );
3794     }
3795 
3796     public Map<String, Object> getBuildAgentGroupRPC( String name )
3797     {
3798         return serializeObject( this.getBuildAgentGroup( name ) );
3799     }
3800 
3801     public Map<String, Object> updateBuildAgentGroupRPC( Map<String, Object> buildAgentGroup )
3802         throws ConfigurationException, ConfigurationStoringException, ContinuumConfigurationException
3803     {
3804         return serializeObject( this.updateBuildAgentGroup( (BuildAgentGroupConfiguration) unserializeObject(
3805             buildAgentGroup ) ) );
3806     }
3807 
3808     public String releasePrepare( int projectId, Properties releaseProperties, Map<String, String> releaseVersions,
3809                                   Map<String, String> developmentVersions, Map<String, String> environments,
3810                                   String username )
3811         throws Exception
3812     {
3813         org.apache.maven.continuum.model.project.Project project = continuum.getProject( projectId );
3814 
3815         if ( project != null )
3816         {
3817             checkBuildProjectInGroupAuthorization( project.getProjectGroup().getName() );
3818 
3819             if ( continuum.getConfiguration().isDistributedBuildEnabled() )
3820             {
3821                 return continuum.getDistributedReleaseManager().releasePrepare( project, releaseProperties,
3822                                                                                 releaseVersions, developmentVersions,
3823                                                                                 environments, username );
3824             }
3825             else
3826             {
3827                 String executable = null;
3828 
3829                 if ( environments != null )
3830                 {
3831                     String m2Home = environments.get( continuum.getInstallationService().getEnvVar(
3832                         InstallationService.MAVEN2_TYPE ) );
3833                     if ( StringUtils.isNotEmpty( m2Home ) )
3834                     {
3835                         executable = m2Home + File.separator + "bin" + File.separator + executable;
3836                     }
3837                 }
3838 
3839                 releaseProperties.setProperty( "release-by", username );
3840                 return continuum.getReleaseManager().prepare( project, releaseProperties, releaseVersions,
3841                                                               developmentVersions, null, continuum.getWorkingDirectory(
3842                     projectId ).getPath(), environments, executable );
3843             }
3844         }
3845         else
3846         {
3847             throw new Exception(
3848                 "Unable to prepare release project with id : " + projectId + " because it doesn't exist" );
3849         }
3850     }
3851 
3852     public int releasePerform( int projectId, String releaseId, String goals, String arguments,
3853                                boolean useReleaseProfile, String repositoryName, String username )
3854         throws Exception
3855     {
3856         org.apache.maven.continuum.model.project.Project project = continuum.getProject( projectId );
3857 
3858         if ( project != null )
3859         {
3860             checkBuildProjectInGroupAuthorization( project.getProjectGroup().getName() );
3861 
3862             org.apache.continuum.model.repository.LocalRepository repository =
3863                 continuum.getRepositoryService().getLocalRepositoryByName( repositoryName );
3864 
3865             if ( continuum.getConfiguration().isDistributedBuildEnabled() )
3866             {
3867                 continuum.getDistributedReleaseManager().releasePerform( projectId, releaseId, goals, arguments,
3868                                                                          useReleaseProfile, repository, username );
3869             }
3870             else
3871             {
3872                 File performDirectory = new File( continuum.getConfiguration().getWorkingDirectory(),
3873                                                   "releases-" + System.currentTimeMillis() );
3874                 performDirectory.mkdirs();
3875 
3876                 continuum.getReleaseManager().perform( releaseId, performDirectory, goals, arguments, useReleaseProfile,
3877                                                        null, repository );
3878             }
3879 
3880             return 0;
3881         }
3882         else
3883         {
3884             throw new Exception(
3885                 "Unable to perform release project with id : " + projectId + " because it doesn't exist" );
3886         }
3887     }
3888 
3889     public ReleaseListenerSummary getListener( int projectId, String releaseId )
3890         throws Exception
3891     {
3892         org.apache.maven.continuum.model.project.Project project = continuum.getProject( projectId );
3893 
3894         if ( project != null )
3895         {
3896             checkBuildProjectInGroupAuthorization( project.getProjectGroup().getName() );
3897 
3898             if ( continuum.getConfiguration().isDistributedBuildEnabled() )
3899             {
3900                 Map<String, Object> map = continuum.getDistributedReleaseManager().getListener( releaseId );
3901                 return processListenerMap( map );
3902             }
3903             else
3904             {
3905                 return populateReleaseListenerSummary( continuum.getReleaseManager().getListener( releaseId ) );
3906             }
3907         }
3908         else
3909         {
3910             throw new Exception( "Unable to get release listener for '" + releaseId + "'" );
3911         }
3912     }
3913 
3914     public int releaseCleanup( int projectId, String releaseId )
3915         throws Exception
3916     {
3917         return releaseCleanup( projectId, releaseId, null );
3918     }
3919 
3920     public int releaseCleanup( int projectId, String releaseId, String releaseType )
3921         throws Exception
3922     {
3923         org.apache.maven.continuum.model.project.Project project = continuum.getProject( projectId );
3924 
3925         if ( project != null )
3926         {
3927             checkBuildProjectInGroupAuthorization( project.getProjectGroup().getName() );
3928             org.apache.continuum.model.release.ContinuumReleaseResult result = continuum.addContinuumReleaseResult(
3929                 projectId, releaseId, releaseType );
3930 
3931             if ( continuum.getConfiguration().isDistributedBuildEnabled() )
3932             {
3933                 continuum.getDistributedReleaseManager().releaseCleanup( releaseId );
3934             }
3935             else
3936             {
3937                 continuum.getReleaseManager().getReleaseResults().remove( releaseId );
3938                 continuum.getReleaseManager().getListeners().remove( releaseId );
3939             }
3940 
3941             return result != null ? result.getId() : 0;
3942         }
3943         else
3944         {
3945             throw new Exception( "Unable to do release cleanup for release '" + releaseId + "'" );
3946         }
3947     }
3948 
3949     public int releaseRollback( int projectId, String releaseId )
3950         throws Exception
3951     {
3952         org.apache.maven.continuum.model.project.Project project = continuum.getProject( projectId );
3953 
3954         if ( project != null )
3955         {
3956             checkBuildProjectInGroupAuthorization( project.getProjectGroup().getName() );
3957             if ( continuum.getConfiguration().isDistributedBuildEnabled() )
3958             {
3959                 continuum.getDistributedReleaseManager().releaseRollback( releaseId, projectId );
3960             }
3961             else
3962             {
3963                 continuum.getReleaseManager().rollback( releaseId, continuum.getWorkingDirectory( projectId ).getPath(),
3964                                                         null );
3965                 continuum.getReleaseManager().getPreparedReleases().remove( releaseId );
3966             }
3967             return 0;
3968         }
3969         else
3970         {
3971             throw new Exception( "Unable to rollback the release for '" + releaseId + "'" );
3972         }
3973     }
3974 
3975     public Map<String, Object> getReleasePluginParameters( int projectId )
3976         throws Exception
3977     {
3978         org.apache.maven.continuum.model.project.Project project = continuum.getProject( projectId );
3979 
3980         if ( project != null )
3981         {
3982             checkBuildProjectInGroupAuthorization( project.getProjectGroup().getName() );
3983             Map<String, Object> params;
3984 
3985             if ( continuum.getConfiguration().isDistributedBuildEnabled() )
3986             {
3987                 params = continuum.getDistributedReleaseManager().getReleasePluginParameters( projectId, "pom.xml" );
3988             }
3989             else
3990             {
3991                 params = ReleaseUtil.getReleasePluginParameters( continuum.getWorkingDirectory( projectId ).getPath(),
3992                                                                  "pom.xml" );
3993             }
3994 
3995             // set scm tag and scm tag base if no values yet
3996             // scm tag
3997             if ( StringUtils.isBlank( (String) params.get( "scm-tag" ) ) )
3998             {
3999                 String scmTag;
4000                 if ( project.getScmTag() != null )
4001                 {
4002                     scmTag = project.getScmTag();
4003                 }
4004                 else
4005                 {
4006                     String version = project.getVersion();
4007                     int idx = version.indexOf( "-SNAPSHOT" );
4008 
4009                     if ( idx >= 0 )
4010                     {
4011                         // strip the snapshot version suffix
4012                         scmTag = project.getArtifactId() + "-" + version.substring( 0, idx );
4013                     }
4014                     else
4015                     {
4016                         scmTag = project.getArtifactId() + "-" + version;
4017                     }
4018                 }
4019 
4020                 continuum.getReleaseManager().sanitizeTagName( project.getScmUrl(), scmTag );
4021                 params.put( "scm-tag", scmTag );
4022             }
4023 
4024             // scm tagbase
4025             if ( StringUtils.isBlank( (String) params.get( "scm-tagbase" ) ) )
4026             {
4027                 if ( project.getScmUrl().startsWith( "scm:svn" ) )
4028                 {
4029                     String scmTagBase = new SvnScmProviderRepository( project.getScmUrl(), project.getScmUsername(),
4030                                                                       project.getScmPassword() ).getTagBase();
4031                     // strip the Maven scm protocol prefix
4032                     params.put( "scm-tagbase", scmTagBase.substring( "scm:svn".length() + 1 ) );
4033                 }
4034                 else
4035                 {
4036                     params.put( "scm-tagbase", "" );
4037                 }
4038             }
4039 
4040             return params;
4041         }
4042         else
4043         {
4044             throw new Exception( "Unable to get release plugin parameters for project with id " + projectId );
4045         }
4046     }
4047 
4048     public List<Map<String, String>> getProjectReleaseAndDevelopmentVersions( int projectId, String pomFilename,
4049                                                                               boolean autoVersionSubmodules )
4050         throws Exception
4051     {
4052         org.apache.maven.continuum.model.project.Project project = continuum.getProject( projectId );
4053 
4054         if ( project != null )
4055         {
4056             checkBuildProjectInGroupAuthorization( project.getProjectGroup().getName() );
4057             List<Map<String, String>> projects = new ArrayList<Map<String, String>>();
4058 
4059             if ( continuum.getConfiguration().isDistributedBuildEnabled() )
4060             {
4061                 projects = continuum.getDistributedReleaseManager().processProject( projectId, pomFilename,
4062                                                                                     autoVersionSubmodules );
4063             }
4064             else
4065             {
4066                 ReleaseUtil.processProject( continuum.getWorkingDirectory( projectId ).getPath(), pomFilename,
4067                                             autoVersionSubmodules, projects );
4068             }
4069 
4070             return projects;
4071         }
4072         else
4073         {
4074             throw new Exception( "Unable to get release plugin parameters for project with id " + projectId );
4075         }
4076     }
4077 
4078     private ReleaseListenerSummary processListenerMap( Map<String, Object> context )
4079     {
4080         ReleaseListenerSummary listenerSummary = new ReleaseListenerSummary();
4081         Object value = context.get( "release-in-progress" );
4082         if ( value != null )
4083         {
4084             listenerSummary.setInProgress( (String) value );
4085         }
4086 
4087         value = context.get( "release-error" );
4088         if ( value != null )
4089         {
4090             listenerSummary.setError( (String) value );
4091         }
4092 
4093         value = context.get( "username" );
4094         if ( value != null )
4095         {
4096             listenerSummary.setUsername( (String) value );
4097         }
4098 
4099         value = context.get( "state" );
4100         if ( value != null )
4101         {
4102             listenerSummary.setState( (Integer) value );
4103         }
4104 
4105         value = context.get( "release-phases" );
4106         if ( value != null )
4107         {
4108             listenerSummary.setPhases( getList( value ) );
4109         }
4110 
4111         value = context.get( "completed-release-phases" );
4112         if ( value != null )
4113         {
4114             listenerSummary.setCompletedPhases( getList( value ) );
4115         }
4116 
4117         return listenerSummary;
4118     }
4119 
4120     private ReleaseListenerSummary populateReleaseListenerSummary(
4121         org.apache.continuum.model.release.ReleaseListenerSummary listener )
4122     {
4123         return (ReleaseListenerSummary) mapper.map( listener, ReleaseListenerSummary.class );
4124     }
4125 
4126     public boolean pingBuildAgent( String buildAgentUrl )
4127         throws Exception
4128     {
4129         return distributedBuildManager.pingBuildAgent( buildAgentUrl );
4130     }
4131 
4132     private List<String> getList( Object obj )
4133     {
4134         List<String> list = new ArrayList<String>();
4135 
4136         if ( obj instanceof String[] )
4137         {
4138             list.addAll( Arrays.asList( (String[]) obj ) );
4139         }
4140         else if ( obj instanceof Object[] )
4141         {
4142             // fallback needed since XMLRPC to the build agent will return a List<String> as Object[]
4143             for ( Object o : (Object[]) obj )
4144             {
4145                 list.add( (String) o );
4146             }
4147         }
4148         else
4149         {
4150             list = (List<String>) obj;
4151         }
4152 
4153         return list;
4154     }
4155 
4156     // testing
4157     public void setContinuum( Continuum continuum )
4158     {
4159         this.continuum = continuum;
4160     }
4161 
4162     public void setDistributedBuildManager( DistributedBuildManager distributedBuildManager )
4163     {
4164         this.distributedBuildManager = distributedBuildManager;
4165     }
4166 
4167     public void setRoleManager( RoleManager roleManager )
4168     {
4169         this.roleManager = roleManager;
4170     }
4171 }