View Javadoc

1   package org.riverock.dbrevision.manager;
2   
3   import java.io.File;
4   import java.io.FileFilter;
5   import java.io.FileInputStream;
6   import java.io.FileNotFoundException;
7   import java.io.IOException;
8   import java.io.Serializable;
9   import java.sql.SQLException;
10  import java.util.ArrayList;
11  import java.util.List;
12  
13  import javax.xml.bind.JAXBException;
14  
15  import org.apache.commons.lang.StringUtils;
16  import org.apache.log4j.Logger;
17  
18  import org.riverock.dbrevision.Constants;
19  import org.riverock.dbrevision.annotation.schema.db.DbSchema;
20  import org.riverock.dbrevision.annotation.schema.db.Patch;
21  import org.riverock.dbrevision.annotation.schema.db.Patches;
22  import org.riverock.dbrevision.db.Database;
23  import org.riverock.dbrevision.exception.DbRevisionException;
24  import org.riverock.dbrevision.exception.InitStructureFileNotFoundException;
25  import org.riverock.dbrevision.exception.NoChildPatchFoundException;
26  import org.riverock.dbrevision.exception.PatchParseException;
27  import org.riverock.dbrevision.exception.PatchPrepareException;
28  import org.riverock.dbrevision.exception.TwoPatchesWithEmptyPreviousPatchException;
29  import org.riverock.dbrevision.exception.VersionPathNotFoundException;
30  import org.riverock.dbrevision.manager.dao.ManagerDaoFactory;
31  import org.riverock.dbrevision.manager.patch.PatchService;
32  import org.riverock.dbrevision.manager.patch.PatchSorter;
33  import org.riverock.dbrevision.system.DbStructureImport;
34  import org.riverock.dbrevision.utils.DbUtils;
35  import org.riverock.dbrevision.utils.Utils;
36  
37  /**
38   * User: SergeMaslyukov
39   * Date: 28.07.2007
40   * Time: 20:04:13
41   */
42  public class Version implements Serializable {
43      private final static Logger log = Logger.getLogger(Version.class);
44  
45      private Version previousVersion=null;
46      private Version nextVersion=null;
47  
48      List<Patch> patches=null;
49  
50      Database database =null;
51  
52      private boolean isComplete = false;
53  
54      private String versionName;
55  
56      private File versionPath=null;
57  
58      private File initStructureFile=null;
59  
60      private File patchPath=null;
61      
62      private File modulePath=null;
63  
64      public Version(Database database, File modulePath, String versionName) {
65          this.database = database;
66          this.modulePath = modulePath;
67          this.versionName = versionName;
68          this.versionPath = new File(modulePath, this.versionName);
69          if (!versionPath.exists()) {
70              throw new VersionPathNotFoundException("Version path not found: " + versionPath.getAbsolutePath() );
71          }
72          this.initStructureFile = new File(versionPath, Constants.INIT_STRUCTURE_FILE_NAME);
73          if (!initStructureFile.exists()) {
74              throw new InitStructureFileNotFoundException("Init structure file not found: " + initStructureFile.getAbsolutePath() );
75          }
76          this.patchPath = new File(versionPath, Constants.PATCH_DIR_NAME);
77          initPatches(); 
78      }
79  
80      public void destroy() {
81          this.setPreviousVersion(null);
82          this.setNextVersion(null);
83          if (database!=null) {
84              if (database.getConnection()!=null) {
85                  DbUtils.close(database.getConnection());
86                  database.setConnection(null);
87              }
88              database=null;
89          }
90          if (this.patches!=null) {
91              this.patches.clear();
92          }
93      }
94  
95      private void initPatches() {
96          File[] files = patchPath.listFiles(
97              new FileFilter() {
98                  public boolean accept(File pathname) {
99                      return pathname.isFile();
100                 }
101             }
102         );
103         if (files==null) {
104             patches = new ArrayList<Patch>();
105             return;
106         }
107         List<Patch> list = new ArrayList<Patch>();
108         try {
109             for (File file : files) {
110                 FileInputStream inputStream=null;
111                 Patches patches;
112                 try {
113                     inputStream = new FileInputStream(file);
114                     try {
115                         patches = Utils.getObjectFromXml(Patches.class, inputStream);
116                     }
117                     catch (JAXBException e) {
118                         throw new PatchParseException("Patch file: " + file.getAbsolutePath(), e);
119                     }
120                     list.addAll(patches.getPatches());
121                 }
122                 finally {
123                     if (inputStream!=null) {
124                         try {
125                             inputStream.close();
126                         }
127                         catch (IOException e1) {
128                             log.error("Error close input stream", e1);
129                         }
130                     }
131                 }
132             }
133             try {
134                 patches = PatchSorter.sort(list);
135             }
136             catch (TwoPatchesWithEmptyPreviousPatchException e) {
137                 String s="";
138                 for (File file : files) {
139                     s+=("\n"+file.getAbsolutePath());
140                 }
141                 throw new TwoPatchesWithEmptyPreviousPatchException(s, e);
142             }
143             catch (NoChildPatchFoundException e) {
144                 String s="";
145                 for (File file : files) {
146                     s+=("\n"+file.getAbsolutePath());
147                 }
148                 throw new NoChildPatchFoundException(s, e);
149             }
150         }
151         catch (Exception e) {
152             throw new PatchPrepareException(e);
153         }
154     }
155 
156     public void applyInitStructure() {
157         if (isComplete) {
158             return;
159         }
160         DbSchema dbSchema;
161         FileInputStream inputStream=null;
162         try {
163             inputStream = new FileInputStream(initStructureFile);
164             dbSchema = Utils.getObjectFromXml(DbSchema.class, inputStream);
165         }
166         catch (JAXBException e) {
167             throw new PatchParseException("Init structure file: " + initStructureFile.getAbsolutePath(), e);
168         }
169         catch (FileNotFoundException e) {
170             throw new InitStructureFileNotFoundException(e);
171         }
172         finally {
173             if (inputStream!=null) {
174                 try {
175                     inputStream.close();
176                 }
177                 catch (IOException e1) {
178                     log.error("Error close input stream", e1);
179                 }
180             }
181         }
182         DbStructureImport.importStructure(database, dbSchema, true);
183         ManagerDaoFactory.getManagerDao().makrCurrentVersion(database, modulePath.getName(), versionName, null);
184         try {
185             database.getConnection().commit();
186         }
187         catch (SQLException e) {
188             throw new DbRevisionException(e);
189         }
190         isComplete=true;
191 
192     }
193 
194     public void apply() {
195         if (isComplete) {
196             return;
197         }
198 
199         if (DbRevisionChecker.isModuleReleased(database, modulePath.getName())) {
200             for (Patch patch : patches) {
201                 if (patch.isProcessed()) {
202                     continue;
203                 }
204                 PatchService.processPatch(database, patch);
205                 ManagerDaoFactory.getManagerDao().makrCurrentVersion(database, modulePath.getName(), versionName, patch.getName());
206                 try {
207                     database.getConnection().commit();
208                 }
209                 catch (SQLException e) {
210                     throw new DbRevisionException(e);
211                 }
212             }
213             ManagerDaoFactory.getManagerDao().makrCurrentVersion(database, modulePath.getName(), versionName, null);
214             try {
215                 database.getConnection().commit();
216             }
217             catch (SQLException e) {
218                 throw new DbRevisionException(e);
219             }
220         }
221         else {
222             applyInitStructure();
223 
224         }
225         isComplete=true;
226     }
227 
228     public void applayPatch(String patchName) throws SQLException {
229         if (isComplete || StringUtils.isBlank(patchName)) {
230             return;
231         }
232         Patch firstNotProcessed=null;
233         for (Patch patch : patches) {
234             if (!patch.isProcessed()) {
235                 firstNotProcessed = patch;
236                 break;
237             }
238         }
239         
240         if (firstNotProcessed!=null && firstNotProcessed.getName().equals(patchName)) {
241             PatchService.processPatch(database, firstNotProcessed);
242             ManagerDaoFactory.getManagerDao().makrCurrentVersion(database, modulePath.getName(), versionName, firstNotProcessed.getName());
243             database.getConnection().commit();
244         }
245     }
246 
247     public Version getPreviousVersion() {
248         return previousVersion;
249     }
250 
251     void setPreviousVersion(Version previousVersion) {
252         this.previousVersion = previousVersion;
253     }
254 
255     public String getVersionName() {
256         return versionName;
257     }
258 
259     public File getPatchPath() {
260         return patchPath;
261     }
262 
263     public void setPatchPath(File patchPath) {
264         this.patchPath = patchPath;
265     }
266 
267     public Patch getLastPatch() {
268         if (patches.isEmpty()) {
269             return null;
270         }
271         return patches.get(patches.size()-1);
272     }
273 
274     public boolean isComplete() {
275         return isComplete;
276     }
277 
278     void setComplete(boolean complete) {
279         isComplete = complete;
280     }
281 
282     public List<Patch> getPatches() {
283         return patches;
284     }
285 
286     void setPatches(List<Patch> patches) {
287         this.patches = patches;
288     }
289 
290     Version getNextVersion() {
291         return nextVersion;
292     }
293 
294     void setNextVersion(Version nextVersion) {
295         this.nextVersion = nextVersion;
296     }
297 
298     public String toString() {
299         return "["+versionName+";"+isComplete+"]";
300     }
301 }