1 package org.apache.maven.continuum.management;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.FileOutputStream;
24 import java.io.FileReader;
25 import java.io.IOException;
26 import java.io.OutputStream;
27 import java.io.OutputStreamWriter;
28 import java.io.Writer;
29 import java.nio.charset.Charset;
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.HashMap;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Properties;
37 import java.util.Set;
38
39 import javax.jdo.JDOHelper;
40 import javax.jdo.PersistenceManagerFactory;
41 import javax.xml.stream.XMLStreamException;
42
43 import org.apache.continuum.dao.BuildDefinitionDao;
44 import org.apache.continuum.dao.BuildDefinitionTemplateDao;
45 import org.apache.continuum.dao.BuildQueueDao;
46 import org.apache.continuum.dao.ContinuumReleaseResultDao;
47 import org.apache.continuum.dao.DaoUtils;
48 import org.apache.continuum.dao.DirectoryPurgeConfigurationDao;
49 import org.apache.continuum.dao.InstallationDao;
50 import org.apache.continuum.dao.LocalRepositoryDao;
51 import org.apache.continuum.dao.ProfileDao;
52 import org.apache.continuum.dao.ProjectGroupDao;
53 import org.apache.continuum.dao.ProjectScmRootDao;
54 import org.apache.continuum.dao.RepositoryPurgeConfigurationDao;
55 import org.apache.continuum.dao.ScheduleDao;
56 import org.apache.continuum.dao.SystemConfigurationDao;
57 import org.apache.continuum.model.project.ProjectScmRoot;
58 import org.apache.continuum.model.release.ContinuumReleaseResult;
59 import org.apache.continuum.model.repository.DirectoryPurgeConfiguration;
60 import org.apache.continuum.model.repository.LocalRepository;
61 import org.apache.continuum.utils.ProjectSorter;
62 import org.apache.maven.continuum.model.project.BuildDefinition;
63 import org.apache.maven.continuum.model.project.BuildDefinitionTemplate;
64 import org.apache.maven.continuum.model.project.BuildQueue;
65 import org.apache.maven.continuum.model.project.ContinuumDatabase;
66 import org.apache.maven.continuum.model.project.Project;
67 import org.apache.maven.continuum.model.project.ProjectGroup;
68 import org.apache.maven.continuum.model.project.Schedule;
69 import org.apache.maven.continuum.model.project.io.stax.ContinuumStaxReader;
70 import org.apache.maven.continuum.model.project.io.stax.ContinuumStaxWriter;
71 import org.apache.maven.continuum.model.system.Installation;
72 import org.apache.maven.continuum.model.system.Profile;
73 import org.apache.maven.continuum.store.ContinuumStoreException;
74 import org.codehaus.plexus.jdo.ConfigurableJdoFactory;
75 import org.codehaus.plexus.jdo.PlexusJdoUtils;
76 import org.codehaus.plexus.util.IOUtil;
77 import org.codehaus.plexus.util.dag.CycleDetectedException;
78 import org.slf4j.Logger;
79 import org.slf4j.LoggerFactory;
80
81
82
83
84
85
86 public class JdoDataManagementTool
87 implements DataManagementTool
88 {
89 private Logger log = LoggerFactory.getLogger( JdoDataManagementTool.class );
90
91
92
93
94 private DaoUtils daoUtils;
95
96
97
98
99 private LocalRepositoryDao localRepositoryDao;
100
101
102
103
104 private DirectoryPurgeConfigurationDao directoryPurgeConfigurationDao;
105
106
107
108
109 private RepositoryPurgeConfigurationDao repositoryPurgeConfigurationDao;
110
111
112
113
114 private InstallationDao installationDao;
115
116
117
118
119 private ProfileDao profileDao;
120
121
122
123
124 private ProjectGroupDao projectGroupDao;
125
126
127
128
129 private ScheduleDao scheduleDao;
130
131
132
133
134 private SystemConfigurationDao systemConfigurationDao;
135
136
137
138
139 private ProjectScmRootDao projectScmRootDao;
140
141
142
143
144 private BuildDefinitionTemplateDao buildDefinitionTemplateDao;
145
146
147
148
149 private ContinuumReleaseResultDao releaseResultDao;
150
151
152
153
154 private BuildQueueDao buildQueueDao;
155
156
157
158
159 private BuildDefinitionDao buildDefinitionDao;
160
161 protected static final String BUILDS_XML = "builds.xml";
162
163
164
165
166 protected ConfigurableJdoFactory factory;
167
168 public void backupDatabase( File backupDirectory )
169 throws IOException
170 {
171 ContinuumDatabase database = new ContinuumDatabase();
172 try
173 {
174 database.setSystemConfiguration( systemConfigurationDao.getSystemConfiguration() );
175 }
176 catch ( ContinuumStoreException e )
177 {
178 throw new DataManagementException( e );
179 }
180
181
182 Collection projectGroups = projectGroupDao.getAllProjectGroupsWithTheLot();
183 database.setProjectGroups( new ArrayList( projectGroups ) );
184 try
185 {
186 database.setInstallations( installationDao.getAllInstallations() );
187
188 database.setBuildDefinitionTemplates( buildDefinitionTemplateDao.getAllBuildDefinitionTemplate() );
189
190 database.setBuildQueues( buildQueueDao.getAllBuildQueues() );
191
192 database.setBuildDefinitions( buildDefinitionDao.getAllTemplates() );
193 }
194 catch ( ContinuumStoreException e )
195 {
196 throw new DataManagementException( e );
197 }
198 database.setSchedules( scheduleDao.getAllSchedulesByName() );
199 database.setProfiles( profileDao.getAllProfilesByName() );
200 database.setLocalRepositories( localRepositoryDao.getAllLocalRepositories() );
201 database.setRepositoryPurgeConfigurations(
202 repositoryPurgeConfigurationDao.getAllRepositoryPurgeConfigurations() );
203 database.setDirectoryPurgeConfigurations( directoryPurgeConfigurationDao.getAllDirectoryPurgeConfigurations() );
204 database.setProjectScmRoots( projectScmRootDao.getAllProjectScmRoots() );
205 database.setContinuumReleaseResults( releaseResultDao.getAllContinuumReleaseResults() );
206
207 ContinuumStaxWriter writer = new ContinuumStaxWriter();
208
209 File backupFile = new File( backupDirectory, BUILDS_XML );
210 File parentFile = backupFile.getParentFile();
211 parentFile.mkdirs();
212
213 OutputStream out = new FileOutputStream( backupFile );
214 Writer fileWriter = new OutputStreamWriter( out, Charset.forName( database.getModelEncoding() ) );
215
216 try
217 {
218 writer.write( fileWriter, database );
219 }
220 catch ( XMLStreamException e )
221 {
222 throw new DataManagementException( "Modello failure: unable to write data to StAX writer", e );
223 }
224 finally
225 {
226 IOUtil.close( fileWriter );
227 }
228 }
229
230 public void eraseDatabase()
231 {
232 daoUtils.eraseDatabase();
233 }
234
235 public void restoreDatabase( File backupDirectory, boolean strict )
236 throws IOException
237 {
238 ContinuumStaxReader reader = new ContinuumStaxReader();
239
240 FileReader fileReader = new FileReader( new File( backupDirectory, BUILDS_XML ) );
241
242 ContinuumDatabase database;
243 try
244 {
245 database = reader.read( fileReader, strict );
246 }
247 catch ( XMLStreamException e )
248 {
249 throw new DataManagementException( e );
250 }
251 finally
252 {
253 IOUtil.close( fileReader );
254 }
255
256
257
258 Properties properties = new Properties();
259 properties.putAll( factory.getProperties() );
260 properties.setProperty( "org.jpox.metadata.jdoFileExtension", "jdorepl" );
261 PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory( properties );
262
263 PlexusJdoUtils.addObject( pmf.getPersistenceManager(), database.getSystemConfiguration() );
264
265 Map<Integer, BuildQueue> buildQueues = new HashMap<Integer, BuildQueue>();
266 for ( BuildQueue buildQueue : (List<BuildQueue>)database.getBuildQueues() )
267 {
268 buildQueue = (BuildQueue) PlexusJdoUtils.addObject( pmf.getPersistenceManager(), buildQueue );
269 buildQueues.put( buildQueue.getId(), buildQueue );
270 }
271
272 Map<Integer, Schedule> schedules = new HashMap<Integer, Schedule>();
273 for ( Iterator i = database.getSchedules().iterator(); i.hasNext(); )
274 {
275 Schedule schedule = (Schedule) i.next();
276 schedule.setBuildQueues( getBuildQueuesBySchedule( buildQueues, schedule ) );
277
278 schedule = (Schedule) PlexusJdoUtils.addObject( pmf.getPersistenceManager(), schedule );
279 schedules.put( Integer.valueOf( schedule.getId() ), schedule );
280 }
281
282 Map<Integer, Installation> installations = new HashMap<Integer, Installation>();
283 for ( Iterator i = database.getInstallations().iterator(); i.hasNext(); )
284 {
285 Installation installation = (Installation) i.next();
286
287 installation = (Installation) PlexusJdoUtils.addObject( pmf.getPersistenceManager(), installation );
288 installations.put( Integer.valueOf( installation.getInstallationId() ), installation );
289 }
290
291 Map<Integer, Profile> profiles = new HashMap<Integer, Profile>();
292 for ( Iterator i = database.getProfiles().iterator(); i.hasNext(); )
293 {
294 Profile profile = (Profile) i.next();
295
296
297 if ( profile.getJdk() != null )
298 {
299 profile.setJdk( installations.get( profile.getJdk().getInstallationId() ) );
300 }
301 if ( profile.getBuilder() != null )
302 {
303 profile.setBuilder( installations.get( profile.getBuilder().getInstallationId() ) );
304 }
305 List environmentVariables = new ArrayList();
306 for (Iterator envIt = profile.getEnvironmentVariables().listIterator(); envIt.hasNext();){
307 Installation installation = (Installation) envIt.next();
308 environmentVariables.add(installations.get(installation.getInstallationId()));
309 envIt.remove();
310 }
311 profile.setEnvironmentVariables( environmentVariables );
312 profile = (Profile) PlexusJdoUtils.addObject( pmf.getPersistenceManager(), profile );
313 profiles.put( Integer.valueOf( profile.getId() ), profile );
314 }
315
316 Map<Integer, BuildDefinition> buildDefinitions = new HashMap<Integer, BuildDefinition>();
317 for ( BuildDefinition buildDefinition : (List<BuildDefinition>) database.getBuildDefinitions() )
318 {
319 if ( buildDefinition.getSchedule() != null )
320 {
321 buildDefinition.setSchedule( schedules.get( Integer.valueOf( buildDefinition.getSchedule().getId() ) ) );
322 }
323
324 if ( buildDefinition.getProfile() != null )
325 {
326 buildDefinition.setProfile( profiles.get( Integer.valueOf( buildDefinition.getProfile().getId() ) ) );
327 }
328
329 buildDefinition = (BuildDefinition) PlexusJdoUtils.addObject( pmf.getPersistenceManager(), buildDefinition );
330 buildDefinitions.put( Integer.valueOf( buildDefinition.getId() ), buildDefinition );
331 }
332
333 Map<Integer, LocalRepository> localRepositories = new HashMap<Integer, LocalRepository>();
334 for ( LocalRepository localRepository : (List<LocalRepository>) database.getLocalRepositories() )
335 {
336 localRepository =
337 (LocalRepository) PlexusJdoUtils.addObject( pmf.getPersistenceManager(), localRepository );
338 localRepositories.put( Integer.valueOf( localRepository.getId() ), localRepository );
339 }
340
341 Map<Integer, ProjectGroup> projectGroups = new HashMap<Integer, ProjectGroup>();
342 for ( Iterator i = database.getProjectGroups().iterator(); i.hasNext(); )
343 {
344 ProjectGroup projectGroup = (ProjectGroup) i.next();
345
346
347 projectGroup.setBuildDefinitions( processBuildDefinitions( projectGroup.getBuildDefinitions(),
348 schedules, profiles, buildDefinitions ) );
349
350 for ( Iterator j = projectGroup.getProjects().iterator(); j.hasNext(); )
351 {
352 Project project = (Project) j.next();
353
354 project.setBuildDefinitions( processBuildDefinitions( project.getBuildDefinitions(),
355 schedules, profiles, buildDefinitions ) );
356 }
357
358 if ( projectGroup.getLocalRepository() != null )
359 {
360 projectGroup.setLocalRepository( localRepositories.get(
361 Integer.valueOf( projectGroup.getLocalRepository().getId() ) ) );
362 }
363
364 projectGroup = (ProjectGroup) PlexusJdoUtils.addObject( pmf.getPersistenceManager(), projectGroup );
365 projectGroups.put( Integer.valueOf( projectGroup.getId() ), projectGroup );
366 }
367
368
369 Map<Integer, ProjectScmRoot> projectScmRoots = new HashMap<Integer, ProjectScmRoot>();
370 Set<Integer> keys = projectGroups.keySet();
371 int id = 1;
372 for( Integer key : keys )
373 {
374 ProjectGroup projectGroup = projectGroups.get( key );
375 String url = " ";
376 List<Project> projects =
377 ProjectSorter.getSortedProjects( getProjectsByGroupIdWithDependencies( pmf, projectGroup.getId() ),
378 log );
379 for ( Iterator j = projects.iterator(); j.hasNext(); )
380 {
381 Project project = (Project) j.next();
382 if ( !project.getScmUrl().trim().startsWith( url ) )
383 {
384 url = project.getScmUrl();
385 ProjectScmRoot projectScmRoot = new ProjectScmRoot();
386 projectScmRoot.setId( id );
387 projectScmRoot.setProjectGroup( projectGroup );
388 projectScmRoot.setScmRootAddress( url );
389 projectScmRoot.setState( project.getState() );
390
391 projectScmRoot = (ProjectScmRoot) PlexusJdoUtils.addObject( pmf.getPersistenceManager(), projectScmRoot );
392 projectScmRoots.put( Integer.valueOf( projectScmRoot.getId() ), projectScmRoot );
393 id++;
394 }
395 }
396 }
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413 for ( DirectoryPurgeConfiguration dirPurge : (List<DirectoryPurgeConfiguration>) database.getDirectoryPurgeConfigurations() )
414 {
415 if ( dirPurge.getSchedule() != null )
416 {
417 dirPurge.setSchedule( schedules.get(
418 Integer.valueOf( dirPurge.getSchedule().getId() ) ) );
419 }
420
421 dirPurge = (DirectoryPurgeConfiguration) PlexusJdoUtils.addObject( pmf.getPersistenceManager(), dirPurge );
422 }
423
424 for ( ContinuumReleaseResult releaseResult : (List<ContinuumReleaseResult>) database.getContinuumReleaseResults() )
425 {
426 releaseResult.setProjectGroup( projectGroups.get(
427 Integer.valueOf( releaseResult.getProjectGroup().getId() ) ) );
428
429 ProjectGroup group = releaseResult.getProjectGroup();
430
431 for ( Project project : (List<Project>) group.getProjects() )
432 {
433 if ( project.getId() == releaseResult.getProject().getId() )
434 {
435 try
436 {
437 Project proj =
438 (Project) PlexusJdoUtils.getObjectById( pmf.getPersistenceManager(), Project.class, project.getId(), null );
439 releaseResult.setProject( proj );
440 }
441 catch ( Exception e )
442 {
443 throw new DataManagementException( e );
444 }
445 }
446 }
447
448 releaseResult =
449 (ContinuumReleaseResult) PlexusJdoUtils.addObject( pmf.getPersistenceManager(), releaseResult );
450 }
451
452 for ( BuildDefinitionTemplate template : (List<BuildDefinitionTemplate>) database.getBuildDefinitionTemplates() )
453 {
454 template.setBuildDefinitions( processBuildDefinitions( template.getBuildDefinitions(), buildDefinitions ) );
455
456 template =
457 (BuildDefinitionTemplate) PlexusJdoUtils.addObject( pmf.getPersistenceManager(), template );
458 }
459 }
460
461 private List<Project> getProjectsByGroupIdWithDependencies( PersistenceManagerFactory pmf, int projectGroupId )
462 {
463 List<Project> allProjects =
464 PlexusJdoUtils.getAllObjectsDetached( pmf.getPersistenceManager(), Project.class, "name ascending",
465 "project-dependencies" );
466 List<Project> groupProjects = new ArrayList<Project>();
467
468 for ( Project project : allProjects )
469 {
470 if ( project.getProjectGroup().getId() == projectGroupId )
471 {
472 groupProjects.add( project );
473 }
474 }
475
476 return groupProjects;
477 }
478
479 private List<BuildDefinition> processBuildDefinitions( List<BuildDefinition> buildDefinitions,
480 Map<Integer, Schedule> schedules,
481 Map<Integer, Profile> profiles,
482 Map<Integer, BuildDefinition> buildDefs )
483 {
484 List<BuildDefinition> buildDefsList = new ArrayList<BuildDefinition>();
485
486 for ( BuildDefinition def : buildDefinitions )
487 {
488 if ( buildDefs.get( Integer.valueOf( def.getId() ) ) != null )
489 {
490 buildDefsList.add( buildDefs.get( Integer.valueOf( def.getId() ) ) );
491 }
492 else
493 {
494 if ( def.getSchedule() != null )
495 {
496 def.setSchedule( schedules.get( Integer.valueOf( def.getSchedule().getId() ) ) );
497 }
498
499 if ( def.getProfile() != null )
500 {
501 def.setProfile( profiles.get( Integer.valueOf( def.getProfile().getId() ) ) );
502 }
503
504 buildDefsList.add( def );
505 }
506 }
507
508 return buildDefsList;
509 }
510
511 private List<BuildDefinition> processBuildDefinitions( List<BuildDefinition> buildDefinitions,
512 Map<Integer, BuildDefinition> buildDefs )
513 {
514 List<BuildDefinition> buildDefsList = new ArrayList<BuildDefinition>();
515
516 for ( BuildDefinition buildDefinition : buildDefinitions )
517 {
518 buildDefsList.add( buildDefs.get( Integer.valueOf( buildDefinition.getId() ) ) );
519 }
520
521 return buildDefsList;
522 }
523
524 private List<BuildQueue> getBuildQueuesBySchedule( Map<Integer, BuildQueue> allBuildQueues, Schedule schedule )
525 {
526 List<BuildQueue> buildQueues = new ArrayList<BuildQueue>();
527
528 for ( BuildQueue buildQueue : (List<BuildQueue>) schedule.getBuildQueues() )
529 {
530 buildQueues.add( allBuildQueues.get( Integer.valueOf( buildQueue.getId() ) ) );
531 }
532
533 return buildQueues;
534 }
535 }