View Javadoc

1   package org.apache.maven.continuum.management;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.continuum.model.project.v1_0_9.BuildDefinition;
23  import org.apache.maven.continuum.model.project.v1_0_9.BuildResult;
24  import org.apache.maven.continuum.model.project.v1_0_9.ContinuumDatabase;
25  import org.apache.maven.continuum.model.project.v1_0_9.Project;
26  import org.apache.maven.continuum.model.project.v1_0_9.ProjectDependency;
27  import org.apache.maven.continuum.model.project.v1_0_9.ProjectDeveloper;
28  import org.apache.maven.continuum.model.project.v1_0_9.ProjectGroup;
29  import org.apache.maven.continuum.model.project.v1_0_9.ProjectNotifier;
30  import org.apache.maven.continuum.model.project.v1_0_9.Schedule;
31  import org.apache.maven.continuum.model.project.v1_0_9.io.stax.ContinuumStaxReader;
32  import org.apache.maven.continuum.model.project.v1_0_9.io.stax.ContinuumStaxWriter;
33  import org.apache.maven.continuum.model.scm.v1_0_9.ChangeFile;
34  import org.apache.maven.continuum.model.scm.v1_0_9.ChangeSet;
35  import org.apache.maven.continuum.model.scm.v1_0_9.ScmResult;
36  import org.apache.maven.continuum.model.scm.v1_0_9.SuiteResult;
37  import org.apache.maven.continuum.model.scm.v1_0_9.TestCaseFailure;
38  import org.apache.maven.continuum.model.scm.v1_0_9.TestResult;
39  import org.apache.maven.continuum.model.system.v1_0_9.SystemConfiguration;
40  import org.apache.maven.continuum.store.ContinuumStoreException;
41  import org.codehaus.plexus.jdo.DefaultConfigurableJdoFactory;
42  import org.codehaus.plexus.jdo.PlexusJdoUtils;
43  import org.codehaus.plexus.util.IOUtil;
44  
45  import javax.jdo.FetchPlan;
46  import javax.jdo.JDOHelper;
47  import javax.jdo.PersistenceManager;
48  import javax.jdo.PersistenceManagerFactory;
49  import javax.xml.stream.XMLStreamException;
50  import java.io.File;
51  import java.io.FileOutputStream;
52  import java.io.FileReader;
53  import java.io.IOException;
54  import java.io.OutputStream;
55  import java.io.OutputStreamWriter;
56  import java.io.Writer;
57  import java.nio.charset.Charset;
58  import java.util.ArrayList;
59  import java.util.Arrays;
60  import java.util.Collection;
61  import java.util.HashMap;
62  import java.util.Iterator;
63  import java.util.List;
64  import java.util.Map;
65  import java.util.Properties;
66  
67  /**
68   * JDO implementation the database management tool API.
69   * @version $Id: LegacyJdoDataManagementTool.java 785095 2009-06-16 07:20:12Z ctan $
70   * @plexus.component role="org.apache.maven.continuum.management.DataManagementTool" role-hint="legacy-continuum-jdo"
71   */
72  public class LegacyJdoDataManagementTool
73      implements DataManagementTool
74  {
75      protected static final String BUILDS_XML = "builds.xml";
76  
77      /**
78       * @plexus.requirement role="org.codehaus.plexus.jdo.JdoFactory" role-hint="continuum"
79       */
80      protected DefaultConfigurableJdoFactory factory;
81  
82      public void backupDatabase( File backupDirectory )
83          throws IOException
84      {
85          PersistenceManagerFactory pmf = getPersistenceManagerFactory( "jdo109" );
86  
87          ContinuumDatabase database = new ContinuumDatabase();
88          try
89          {
90              database.setSystemConfiguration( retrieveSystemConfiguration( pmf ) );
91          }
92          catch ( ContinuumStoreException e )
93          {
94              throw new DataManagementException( e );
95          }
96  
97          Collection<ProjectGroup> projectGroups = retrieveAllProjectGroups( pmf );
98          database.setProjectGroups( new ArrayList<ProjectGroup>( projectGroups ) );
99  
100         database.setSchedules( retrieveAllSchedules( pmf ) );
101 
102         ContinuumStaxWriter writer = new ContinuumStaxWriter();
103 
104         backupDirectory.mkdirs();
105         OutputStream out = new FileOutputStream( new File( backupDirectory, BUILDS_XML ) );
106         Writer fileWriter = new OutputStreamWriter( out, Charset.forName( database.getModelEncoding() ) );
107 
108         try
109         {
110             writer.write( fileWriter, database );
111         }
112         catch ( XMLStreamException e )
113         {
114             throw new DataManagementException( "Modello failure: unable to write data to StAX writer", e );
115         }
116         finally
117         {
118             IOUtil.close( fileWriter );
119         }
120     }
121 
122     private List retrieveAllSchedules( PersistenceManagerFactory pmf )
123     {
124         return PlexusJdoUtils.getAllObjectsDetached( getPersistenceManager( pmf ), Schedule.class, "name ascending",
125                                                      (String) null );
126     }
127 
128     private Collection<ProjectGroup> retrieveAllProjectGroups( PersistenceManagerFactory pmf )
129     {
130         List<String> fetchGroups = Arrays.asList( "project-with-builds", "projectgroup-projects",
131                                                   "build-result-with-details", "project-with-checkout-result",
132                                                   "project-all-details", "project-build-details" );
133         return PlexusJdoUtils.getAllObjectsDetached( getPersistenceManager( pmf ), ProjectGroup.class, "name ascending",
134                                                      fetchGroups );
135     }
136 
137     private SystemConfiguration retrieveSystemConfiguration( PersistenceManagerFactory pmf )
138         throws ContinuumStoreException
139     {
140         SystemConfiguration result;
141         List systemConfs = PlexusJdoUtils.getAllObjectsDetached( getPersistenceManager( pmf ),
142                                                                  SystemConfiguration.class, null, (String) null );
143 
144         if ( systemConfs == null || systemConfs.isEmpty() )
145         {
146             result = null;
147         }
148         else if ( systemConfs.size() > 1 )
149         {
150             throw new ContinuumStoreException(
151                 "Database is corrupted. There are more than one systemConfiguration object." );
152         }
153         else
154         {
155             result = (SystemConfiguration) systemConfs.get( 0 );
156         }
157         return result;
158     }
159 
160     @SuppressWarnings({"OverlyCoupledMethod"})
161     public void eraseDatabase()
162     {
163         PersistenceManagerFactory pmf = getPersistenceManagerFactory( "jdo109" );
164         PersistenceManager persistenceManager = getPersistenceManager( pmf );
165         PlexusJdoUtils.removeAll( persistenceManager, ProjectGroup.class );
166         PlexusJdoUtils.removeAll( persistenceManager, Project.class );
167         PlexusJdoUtils.removeAll( persistenceManager, Schedule.class );
168         PlexusJdoUtils.removeAll( persistenceManager, ScmResult.class );
169         PlexusJdoUtils.removeAll( persistenceManager, BuildResult.class );
170         PlexusJdoUtils.removeAll( persistenceManager, TestResult.class );
171         PlexusJdoUtils.removeAll( persistenceManager, SuiteResult.class );
172         PlexusJdoUtils.removeAll( persistenceManager, TestCaseFailure.class );
173         PlexusJdoUtils.removeAll( persistenceManager, SystemConfiguration.class );
174         PlexusJdoUtils.removeAll( persistenceManager, ProjectNotifier.class );
175         PlexusJdoUtils.removeAll( persistenceManager, ProjectDeveloper.class );
176         PlexusJdoUtils.removeAll( persistenceManager, ProjectDependency.class );
177         PlexusJdoUtils.removeAll( persistenceManager, ChangeSet.class );
178         PlexusJdoUtils.removeAll( persistenceManager, ChangeFile.class );
179         PlexusJdoUtils.removeAll( persistenceManager, BuildDefinition.class );
180     }
181 
182     private PersistenceManager getPersistenceManager( PersistenceManagerFactory pmf )
183     {
184         PersistenceManager pm = pmf.getPersistenceManager();
185 
186         pm.getFetchPlan().setMaxFetchDepth( -1 );
187         pm.getFetchPlan().setDetachmentOptions( FetchPlan.DETACH_LOAD_FIELDS );
188 
189         return pm;
190     }
191 
192     public void restoreDatabase( File backupDirectory, boolean strict )
193         throws IOException
194     {
195         ContinuumStaxReader reader = new ContinuumStaxReader();
196 
197         FileReader fileReader = new FileReader( new File( backupDirectory, BUILDS_XML ) );
198 
199         ContinuumDatabase database;
200         try
201         {
202             database = reader.read( fileReader, strict );
203         }
204         catch ( XMLStreamException e )
205         {
206             throw new DataManagementException( e );
207         }
208         finally
209         {
210             IOUtil.close( fileReader );
211         }
212 
213         PersistenceManagerFactory pmf = getPersistenceManagerFactory( "jdorepl109" );
214 
215         PlexusJdoUtils.addObject( pmf.getPersistenceManager(), database.getSystemConfiguration() );
216 
217         Map<Integer, Schedule> schedules = new HashMap<Integer, Schedule>();
218         for ( Iterator i = database.getSchedules().iterator(); i.hasNext(); )
219         {
220             Schedule schedule = (Schedule) i.next();
221 
222             schedule = (Schedule) PlexusJdoUtils.addObject( pmf.getPersistenceManager(), schedule );
223             schedules.put( Integer.valueOf( schedule.getId() ), schedule );
224         }
225 
226         for ( Iterator i = database.getProjectGroups().iterator(); i.hasNext(); )
227         {
228             ProjectGroup projectGroup = (ProjectGroup) i.next();
229 
230             // first, we must map up any schedules, etc.
231             processBuildDefinitions( projectGroup.getBuildDefinitions(), schedules );
232 
233             for ( Iterator j = projectGroup.getProjects().iterator(); j.hasNext(); )
234             {
235                 Project project = (Project) j.next();
236 
237                 processBuildDefinitions( project.getBuildDefinitions(), schedules );
238             }
239 
240             PlexusJdoUtils.addObject( pmf.getPersistenceManager(), projectGroup );
241         }
242         pmf.close();
243     }
244 
245     private PersistenceManagerFactory getPersistenceManagerFactory( String ext )
246     {
247         // Take control of the JDO instead of using the store, and configure a new persistence factory
248         // that won't generate new object IDs.
249         Properties properties = new Properties();
250         //noinspection UseOfPropertiesAsHashtable
251         properties.putAll( factory.getProperties() );
252         properties.setProperty( "org.jpox.metadata.jdoFileExtension", ext );
253         return JDOHelper.getPersistenceManagerFactory( properties );
254     }
255 
256     private static void processBuildDefinitions( List buildDefinitions, Map<Integer, Schedule> schedules )
257     {
258         for ( Iterator i = buildDefinitions.iterator(); i.hasNext(); )
259         {
260             BuildDefinition def = (BuildDefinition) i.next();
261 
262             if ( def.getSchedule() != null )
263             {
264                 def.setSchedule( schedules.get( Integer.valueOf( def.getSchedule().getId() ) ) );
265             }
266         }
267     }
268 }