reverting preliminar commits on security and permissions r15723 r15724
[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 * @author a.mueller
24 * @date 16.11.2010
25 *
26 */
27 public abstract class UpdaterBase<T extends ISchemaUpdaterStep, U extends IUpdater<U>> implements IUpdater<U> {
28 @SuppressWarnings("unused")
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 datasourceSchemaVersion;
59 try {
60 datasourceSchemaVersion = getCurrentVersion(datasource, monitor);
61 } catch (SQLException e1) {
62 monitor.warning("SQLException", e1);
63 return false;
64 }
65
66 boolean isAfterMyStartVersion = isAfterMyStartVersion(datasourceSchemaVersion, monitor);
67 boolean isBeforeMyStartVersion = isBeforeMyStartVersion(datasourceSchemaVersion, monitor);
68 // boolean isBeforeMyTargetVersion = isBeforeMyTargetVersion(targetVersion, monitor);
69 boolean isDatasourceBeforeMyTargetVersion = isBeforeMyTargetVersion(datasourceSchemaVersion, monitor);
70
71 result &= isDatasourceBeforeMyTargetVersion;
72 result &= !(isAfterMyStartVersion /*&& isBeforeMyTargetVersion*/);
73 result &= ! (isBeforeMyStartVersion && getPreviousUpdater() == null);
74 // result &= !isBeforeMyTargetVersion;
75 return result;
76 }
77
78
79 @Override
80 public boolean invoke(ICdmDataSource datasource, IProgressMonitor monitor) throws Exception{
81 String currentLibrarySchemaVersion = CdmMetaData.getDbSchemaVersion();
82 return invoke(currentLibrarySchemaVersion, datasource, monitor);
83 }
84
85 /* (non-Javadoc)
86 * @see eu.etaxonomy.cdm.database.update.IUpdater#invoke(java.lang.String, eu.etaxonomy.cdm.database.ICdmDataSource, eu.etaxonomy.cdm.common.IProgressMonitor)
87 */
88 @Override
89 public boolean invoke(String targetVersion, ICdmDataSource datasource, IProgressMonitor monitor) throws Exception{
90 boolean result = true;
91 String datasourceSchemaVersion;
92 try {
93 datasourceSchemaVersion = getCurrentVersion(datasource, monitor);
94 } catch (SQLException e1) {
95 monitor.warning("SQLException", e1);
96 return false;
97 }
98
99
100 boolean isAfterMyStartVersion = isAfterMyStartVersion(datasourceSchemaVersion, monitor);
101 boolean isBeforeMyStartVersion = isBeforeMyStartVersion(datasourceSchemaVersion, monitor);
102 // boolean isAfterMyTargetVersion = isAfterMyTargetVersion(targetVersion, monitor);
103 boolean isBeforeMyTargetVersion = isBeforeMyTargetVersion(targetVersion, monitor);
104 boolean isDatasourceBeforeMyTargetVersion = isBeforeMyTargetVersion(datasourceSchemaVersion, 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);
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();
144 try {
145 for (T step : list){
146 result &= handleSingleStep(datasource, monitor, result, step, false);
147 if (result == false){
148 break;
149 }
150 }
151 // TODO schema version gets updated even if something went utterly wrong while executing the steps
152 // I don't think we want this to happen
153 if (result == true){
154 result &= updateVersion(datasource, monitor);
155 }else{
156 datasource.rollback();
157 }
158
159 } catch (Exception e) {
160 logger.error("Error occurred while trying to run updater: " + this.getClass().getName());
161 result = false;
162 }
163 if (result == false){
164 datasource.commitTransaction();
165 }else{
166 datasource.rollback();
167 }
168 return result;
169
170 }
171
172 // protected abstract boolean handleSingleStep(ICdmDataSource datasource, IProgressMonitor monitor, boolean result, ISchemaUpdaterStep step, boolean isInnerStep) throws Exception;
173
174 protected boolean handleSingleStep(ICdmDataSource datasource, IProgressMonitor monitor, boolean result, ISchemaUpdaterStep step, boolean isInnerStep)
175 throws Exception {
176 try {
177 monitor.subTask(step.getStepName());
178 Integer invokeResult = step.invoke(datasource, monitor);
179 result &= (invokeResult != null);
180 for (ISchemaUpdaterStep innerStep : step.getInnerSteps()){
181 result &= handleSingleStep(datasource, monitor, result, innerStep, true);
182 }
183 // if (! isInnerStep){
184 monitor.worked(1);
185 // }
186 } catch (Exception e) {
187 monitor.warning("Monitor: Exception occurred while updating schema", e);
188 datasource.rollback();
189 result = false;
190 }
191 return result;
192 }
193
194 protected boolean isAfterMyStartVersion(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 isBeforeMyStartVersion(String dataSourceSchemaVersion, IProgressMonitor monitor) {
201 int depth = 4;
202 int compareResult = CdmMetaData.compareVersion(dataSourceSchemaVersion, startVersion, depth, monitor);
203 return compareResult < 0;
204 }
205
206 protected boolean isAfterMyTargetVersion(String dataSourceSchemaVersion, IProgressMonitor monitor) {
207 int depth = 4;
208 int compareResult = CdmMetaData.compareVersion(dataSourceSchemaVersion, targetVersion, depth, monitor);
209 return compareResult > 0;
210 }
211
212 protected boolean isBeforeMyTargetVersion(String dataSourceSchemaVersion, IProgressMonitor monitor) {
213 int depth = 4;
214 int compareResult = CdmMetaData.compareVersion(dataSourceSchemaVersion, targetVersion, depth, monitor);
215 return compareResult < 0;
216 }
217
218 /* (non-Javadoc)
219 * @see eu.etaxonomy.cdm.database.update.IUpdater#getNextUpdater()
220 */
221 @Override
222 public abstract U getNextUpdater();
223
224 /* (non-Javadoc)
225 * @see eu.etaxonomy.cdm.database.update.IUpdater#getPreviousUpdater()
226 */
227 @Override
228 public abstract U getPreviousUpdater();
229
230
231 /**
232 * @return
233 */
234 public String getTargetVersion() {
235 return this.targetVersion;
236 }
237 }