minor
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / database / update / UpdaterBase.java
1 // $Id$
2 /**
3 * Copyright (C) 2009 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10 package eu.etaxonomy.cdm.database.update;
11
12 import java.sql.SQLException;
13 import java.util.List;
14
15 import org.apache.log4j.Logger;
16
17 import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
18 import eu.etaxonomy.cdm.database.ICdmDataSource;
19 import eu.etaxonomy.cdm.model.metadata.CdmMetaData;
20
21
22 /**
23 * Common updater base class for updating schema or terms.
24 * @author a.mueller
25 * @date 16.11.2010
26 *
27 */
28 public abstract class UpdaterBase<T extends ISchemaUpdaterStep, U extends IUpdater<U>> implements IUpdater<U> {
29 private static final Logger logger = Logger.getLogger(TermUpdaterBase.class);
30
31 protected List<T> list;
32 protected String startVersion;
33 protected String targetVersion;
34
35
36 protected abstract boolean updateVersion(ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType) throws SQLException;
37
38 protected abstract String getCurrentVersion(ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType) throws SQLException;
39
40 @Override
41 public int countSteps(ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType){
42 int result = 0;
43 //TODO test if previous updater is needed
44 if (isToBeInvoked(datasource, monitor, caseType)){
45 for (T step: list){
46 result++; //+= list.size();
47 result += step.getInnerSteps().size();
48 }
49 if (getPreviousUpdater() != null){
50 result += getPreviousUpdater().countSteps(datasource, monitor, caseType);
51 }
52 }
53 return result;
54 }
55
56
57 private boolean isToBeInvoked(ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType) {
58 boolean result = true;
59 String datasourceVersion;
60 try {
61 datasourceVersion = getCurrentVersion(datasource, monitor, caseType);
62 } catch (SQLException e1) {
63 monitor.warning("SQLException", e1);
64 return false;
65 }
66
67 boolean isAfterMyStartVersion = isAfterMyStartVersion(datasourceVersion, monitor);
68 boolean isBeforeMyStartVersion = isBeforeMyStartVersion(datasourceVersion, monitor);
69 // boolean isBeforeMyTargetVersion = isBeforeMyTargetVersion(targetVersion, monitor);
70 boolean isBeforeMyTargetVersion = isBeforeMyTargetVersion(targetVersion, monitor);
71 boolean isDatasourceBeforeMyTargetVersion = isBeforeMyTargetVersion(datasourceVersion, monitor);
72
73 result &= isDatasourceBeforeMyTargetVersion;
74 result &= !(isAfterMyStartVersion && isBeforeMyTargetVersion);
75 result &= ! (isBeforeMyStartVersion && getPreviousUpdater() == null);
76 result &= !isBeforeMyTargetVersion;
77 return result;
78 }
79
80
81 @Override
82 public boolean invoke(ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType) throws Exception{
83 String currentLibrarySchemaVersion = CdmMetaData.getDbSchemaVersion();
84 return invoke(currentLibrarySchemaVersion, datasource, monitor, caseType);
85 }
86
87 @Override
88 public boolean invoke(String targetVersion, ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType) throws Exception{
89 boolean result = true;
90 String datasourceVersion;
91
92 try {
93 datasourceVersion = getCurrentVersion(datasource, monitor, caseType);
94 } catch (SQLException e1) {
95 monitor.warning("SQLException", e1);
96 return false;
97 }
98
99
100 boolean isAfterMyStartVersion = isAfterMyStartVersion(datasourceVersion, monitor);
101 boolean isBeforeMyStartVersion = isBeforeMyStartVersion(datasourceVersion, monitor);
102 // boolean isAfterMyTargetVersion = isAfterMyTargetVersion(targetVersion, monitor);
103 boolean isBeforeMyTargetVersion = isBeforeMyTargetVersion(targetVersion, monitor);
104 boolean isDatasourceBeforeMyTargetVersion = isBeforeMyTargetVersion(datasourceVersion, monitor);
105
106
107
108 if (! isDatasourceBeforeMyTargetVersion){
109 String warning = "Target version ("+targetVersion+") is not before updater target version ("+this.targetVersion+"). Nothing to update.";
110 monitor.warning(warning);
111 return true;
112 }
113
114 if (isAfterMyStartVersion && isBeforeMyTargetVersion){
115 String warning = "Database version is higher than updater start version but lower than updater target version";
116 RuntimeException exeption = new RuntimeException(warning);
117 monitor.warning(warning, exeption);
118 throw exeption;
119 }
120
121 if (isBeforeMyStartVersion){
122 if (getPreviousUpdater() == null){
123 String warning = "Database version is before updater version but no previous version updater exists";
124 RuntimeException exeption = new RuntimeException(warning);
125 monitor.warning(warning, exeption);
126 throw exeption;
127 }
128 result &= getPreviousUpdater().invoke(startVersion, datasource, monitor, caseType);
129 }
130
131
132
133 if (isBeforeMyTargetVersion){
134 String warning = "Target version ("+targetVersion+") is lower than updater target version ("+this.targetVersion+")";
135 RuntimeException exeption = new RuntimeException(warning);
136 monitor.warning(warning, exeption);
137 throw exeption;
138 }
139
140 if (result == false){
141 return result;
142 }
143 // datasource.startTransaction(); transaction already started by CdmUpdater
144 try {
145 for (T step : list){
146 result &= handleSingleStep(datasource, monitor, result, step, false, caseType);
147 if (result == false){
148 break;
149 }
150 }
151 if (result == true){
152 result &= updateVersion(datasource, monitor, caseType);
153 }else{
154 datasource.rollback();
155 }
156
157 } catch (Exception e) {
158 datasource.rollback();
159 logger.error("Error occurred while trying to run updater: " + this.getClass().getName());
160 result = false;
161 }
162 return result;
163
164 }
165
166 // protected abstract boolean handleSingleStep(ICdmDataSource datasource, IProgressMonitor monitor, boolean result, ISchemaUpdaterStep step, boolean isInnerStep) throws Exception;
167
168 protected boolean handleSingleStep(ICdmDataSource datasource, IProgressMonitor monitor, boolean result, ISchemaUpdaterStep step, boolean isInnerStep, CaseType caseType)
169 throws Exception {
170 try {
171 monitor.subTask(step.getStepName());
172 Integer invokeResult = step.invoke(datasource, monitor, caseType);
173 result &= (invokeResult != null);
174 for (ISchemaUpdaterStep innerStep : step.getInnerSteps()){
175 result &= handleSingleStep(datasource, monitor, result, innerStep, true, caseType);
176 }
177 // if (! isInnerStep){
178 monitor.worked(1);
179 // }
180 } catch (Exception e) {
181 monitor.warning("Monitor: Exception occurred while handling single schema updating step", e);
182 datasource.rollback();
183 result = false;
184 }
185 return result;
186 }
187
188 protected boolean isAfterMyStartVersion(String dataSourceSchemaVersion, IProgressMonitor monitor) {
189 int depth = 4;
190 int compareResult = CdmMetaData.compareVersion(dataSourceSchemaVersion, startVersion, depth, monitor);
191 return compareResult > 0;
192 }
193
194 protected boolean isBeforeMyStartVersion(String dataSourceSchemaVersion, IProgressMonitor monitor) {
195 int depth = 4;
196 int compareResult = CdmMetaData.compareVersion(dataSourceSchemaVersion, startVersion, depth, monitor);
197 return compareResult < 0;
198 }
199
200 protected boolean isAfterMyTargetVersion(String dataSourceSchemaVersion, IProgressMonitor monitor) {
201 int depth = 4;
202 int compareResult = CdmMetaData.compareVersion(dataSourceSchemaVersion, targetVersion, depth, monitor);
203 return compareResult > 0;
204 }
205
206 protected boolean isBeforeMyTargetVersion(String dataSourceSchemaVersion, IProgressMonitor monitor) {
207 int depth = 4;
208 int compareResult = CdmMetaData.compareVersion(dataSourceSchemaVersion, targetVersion, depth, monitor);
209 return compareResult < 0;
210 }
211
212 /* (non-Javadoc)
213 * @see eu.etaxonomy.cdm.database.update.IUpdater#getNextUpdater()
214 */
215 @Override
216 public abstract U getNextUpdater();
217
218 /* (non-Javadoc)
219 * @see eu.etaxonomy.cdm.database.update.IUpdater#getPreviousUpdater()
220 */
221 @Override
222 public abstract U getPreviousUpdater();
223
224
225 /**
226 * @return
227 */
228 public String getTargetVersion() {
229 return this.targetVersion;
230 }
231 }