merge-update from trunk
[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.common.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 protected abstract boolean updateVersion(ICdmDataSource datasource, IProgressMonitor monitor) throws SQLException;
36
37 protected abstract String getCurrentVersion(ICdmDataSource datasource, IProgressMonitor monitor) throws SQLException;
38
39 @Override
40 public int countSteps(ICdmDataSource datasource, IProgressMonitor monitor){
41 int result = 0;
42 //TODO test if previous updater is needed
43 if (isToBeInvoked(/*targetVerison, */datasource, monitor)){
44 for (T step: list){
45 result++; //+= list.size();
46 result += step.getInnerSteps().size();
47 }
48 if (getPreviousUpdater() != null){
49 result += getPreviousUpdater().countSteps(/*targetVerison, */datasource, monitor);
50 }
51 }
52 return result;
53 }
54
55
56 private boolean isToBeInvoked(ICdmDataSource datasource, IProgressMonitor monitor) {
57 boolean result = true;
58 String datasourceVersion;
59 try {
60 datasourceVersion = getCurrentVersion(datasource, monitor);
61 } catch (SQLException e1) {
62 monitor.warning("SQLException", e1);
63 return false;
64 }
65
66 boolean isAfterMyStartVersion = isAfterMyStartVersion(datasourceVersion, monitor);
67 boolean isBeforeMyStartVersion = isBeforeMyStartVersion(datasourceVersion, monitor);
68 // boolean isBeforeMyTargetVersion = isBeforeMyTargetVersion(targetVersion, monitor);
69 boolean isBeforeMyTargetVersion = isBeforeMyTargetVersion(targetVersion, monitor);
70 boolean isDatasourceBeforeMyTargetVersion = isBeforeMyTargetVersion(datasourceVersion, monitor);
71
72 result &= isDatasourceBeforeMyTargetVersion;
73 result &= !(isAfterMyStartVersion && isBeforeMyTargetVersion);
74 result &= ! (isBeforeMyStartVersion && getPreviousUpdater() == null);
75 result &= !isBeforeMyTargetVersion;
76 return result;
77 }
78
79
80 @Override
81 public boolean invoke(ICdmDataSource datasource, IProgressMonitor monitor) throws Exception{
82 String currentLibrarySchemaVersion = CdmMetaData.getDbSchemaVersion();
83 return invoke(currentLibrarySchemaVersion, datasource, monitor);
84 }
85
86 /* (non-Javadoc)
87 * @see eu.etaxonomy.cdm.database.update.IUpdater#invoke(java.lang.String, eu.etaxonomy.cdm.database.ICdmDataSource, eu.etaxonomy.cdm.common.IProgressMonitor)
88 */
89 @Override
90 public boolean invoke(String targetVersion, ICdmDataSource datasource, IProgressMonitor monitor) throws Exception{
91 boolean result = true;
92 String datasourceVersion;
93 try {
94 datasourceVersion = getCurrentVersion(datasource, monitor);
95 } catch (SQLException e1) {
96 monitor.warning("SQLException", e1);
97 return false;
98 }
99
100
101 boolean isAfterMyStartVersion = isAfterMyStartVersion(datasourceVersion, monitor);
102 boolean isBeforeMyStartVersion = isBeforeMyStartVersion(datasourceVersion, monitor);
103 // boolean isAfterMyTargetVersion = isAfterMyTargetVersion(targetVersion, monitor);
104 boolean isBeforeMyTargetVersion = isBeforeMyTargetVersion(targetVersion, monitor);
105 boolean isDatasourceBeforeMyTargetVersion = isBeforeMyTargetVersion(datasourceVersion, monitor);
106
107
108
109 if (! isDatasourceBeforeMyTargetVersion){
110 String warning = "Target version ("+targetVersion+") is not before updater target version ("+this.targetVersion+"). Nothing to update.";
111 monitor.warning(warning);
112 return true;
113 }
114
115 if (isAfterMyStartVersion && isBeforeMyTargetVersion){
116 String warning = "Database version is higher than updater start version but lower than updater target version";
117 RuntimeException exeption = new RuntimeException(warning);
118 monitor.warning(warning, exeption);
119 throw exeption;
120 }
121
122 if (isBeforeMyStartVersion){
123 if (getPreviousUpdater() == null){
124 String warning = "Database version is before updater version but no previous version updater exists";
125 RuntimeException exeption = new RuntimeException(warning);
126 monitor.warning(warning, exeption);
127 throw exeption;
128 }
129 result &= getPreviousUpdater().invoke(startVersion, datasource, monitor);
130 }
131
132
133
134 if (isBeforeMyTargetVersion){
135 String warning = "Target version ("+targetVersion+") is lower than updater target version ("+this.targetVersion+")";
136 RuntimeException exeption = new RuntimeException(warning);
137 monitor.warning(warning, exeption);
138 throw exeption;
139 }
140
141 if (result == false){
142 return result;
143 }
144 // datasource.startTransaction(); transaction already started by CdmUpdater
145 try {
146 for (T step : list){
147 result &= handleSingleStep(datasource, monitor, result, step, false);
148 if (result == false){
149 break;
150 }
151 }
152 if (result == true){
153 result &= updateVersion(datasource, monitor);
154 }else{
155 datasource.rollback();
156 }
157
158 } catch (Exception e) {
159 datasource.rollback();
160 logger.error("Error occurred while trying to run updater: " + this.getClass().getName());
161 result = false;
162 }
163 return result;
164
165 }
166
167 // protected abstract boolean handleSingleStep(ICdmDataSource datasource, IProgressMonitor monitor, boolean result, ISchemaUpdaterStep step, boolean isInnerStep) throws Exception;
168
169 protected boolean handleSingleStep(ICdmDataSource datasource, IProgressMonitor monitor, boolean result, ISchemaUpdaterStep step, boolean isInnerStep)
170 throws Exception {
171 try {
172 monitor.subTask(step.getStepName());
173 Integer invokeResult = step.invoke(datasource, monitor);
174 result &= (invokeResult != null);
175 for (ISchemaUpdaterStep innerStep : step.getInnerSteps()){
176 result &= handleSingleStep(datasource, monitor, result, innerStep, true);
177 }
178 // if (! isInnerStep){
179 monitor.worked(1);
180 // }
181 } catch (Exception e) {
182 monitor.warning("Monitor: Exception occurred while handling single schema updating step", e);
183 datasource.rollback();
184 result = false;
185 }
186 return result;
187 }
188
189 protected boolean isAfterMyStartVersion(String dataSourceSchemaVersion, IProgressMonitor monitor) {
190 int depth = 4;
191 int compareResult = CdmMetaData.compareVersion(dataSourceSchemaVersion, startVersion, depth, monitor);
192 return compareResult > 0;
193 }
194
195 protected boolean isBeforeMyStartVersion(String dataSourceSchemaVersion, IProgressMonitor monitor) {
196 int depth = 4;
197 int compareResult = CdmMetaData.compareVersion(dataSourceSchemaVersion, startVersion, depth, monitor);
198 return compareResult < 0;
199 }
200
201 protected boolean isAfterMyTargetVersion(String dataSourceSchemaVersion, IProgressMonitor monitor) {
202 int depth = 4;
203 int compareResult = CdmMetaData.compareVersion(dataSourceSchemaVersion, targetVersion, depth, monitor);
204 return compareResult > 0;
205 }
206
207 protected boolean isBeforeMyTargetVersion(String dataSourceSchemaVersion, IProgressMonitor monitor) {
208 int depth = 4;
209 int compareResult = CdmMetaData.compareVersion(dataSourceSchemaVersion, targetVersion, depth, monitor);
210 return compareResult < 0;
211 }
212
213 /* (non-Javadoc)
214 * @see eu.etaxonomy.cdm.database.update.IUpdater#getNextUpdater()
215 */
216 @Override
217 public abstract U getNextUpdater();
218
219 /* (non-Javadoc)
220 * @see eu.etaxonomy.cdm.database.update.IUpdater#getPreviousUpdater()
221 */
222 @Override
223 public abstract U getPreviousUpdater();
224
225
226 /**
227 * @return
228 */
229 public String getTargetVersion() {
230 return this.targetVersion;
231 }
232 }