Project

General

Profile

Download (9.11 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2009 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.database.update;
10

    
11
import java.sql.SQLException;
12
import java.util.List;
13

    
14
import org.apache.log4j.Logger;
15

    
16
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
17
import eu.etaxonomy.cdm.database.ICdmDataSource;
18
import eu.etaxonomy.cdm.model.metadata.CdmMetaData;
19

    
20

    
21
/**
22
 * Common updater base class for updating schema or terms.
23
 *
24
 * Note: prior to v4.8 this was a common base class for {@link SchemaUpdaterBase}
25
 * and term updater. Since v4.8 we do not have a term updater anymore.
26
 * Therefore in future this class could be merged with {@link SchemaUpdaterBase}
27
 *
28
 * @see CdmUpdater
29
 * @see ISchemaUpdater
30
 *
31
 * @author a.mueller
32
 * @since 16.11.2010
33
 *
34
 */
35
public abstract class UpdaterBase<T extends ISchemaUpdaterStep, U extends IUpdater<U>>
36
            implements IUpdater<U> {
37

    
38
	private static final Logger logger = Logger.getLogger(UpdaterBase.class);
39

    
40
	protected List<T> list;
41
	protected String startVersion;
42
	protected String targetVersion;
43

    
44

    
45
	protected abstract void updateVersion(ICdmDataSource datasource, IProgressMonitor monitor,
46
	        CaseType caseType, SchemaUpdateResult result) throws SQLException;
47

    
48
	protected abstract String getCurrentVersion(ICdmDataSource datasource,
49
	        IProgressMonitor monitor, CaseType caseType) throws SQLException;
50

    
51
	@Override
52
	public int countSteps(ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType){
53
		int result = 0;
54
		//TODO test if previous updater is needed
55
		if (isToBeInvoked(datasource, monitor, caseType)){
56
			for (T step: list){
57
				result++; //+= list.size();
58
				result += step.getInnerSteps().size();
59
			}
60
			if (getPreviousUpdater() != null){
61
				result += getPreviousUpdater().countSteps(datasource, monitor, caseType);
62
			}
63
		}
64
		return result;
65
	}
66

    
67

    
68
	private boolean isToBeInvoked(ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType) {
69
		boolean result = true;
70
		String datasourceVersion;
71
		try {
72
			datasourceVersion = getCurrentVersion(datasource, monitor, caseType);
73
		} catch (SQLException e1) {
74
			monitor.warning("SQLException", e1);
75
			return false;
76
		}
77

    
78
		boolean isAfterMyStartVersion = isAfterMyStartVersion(datasourceVersion, monitor);
79
		boolean isBeforeMyStartVersion = isBeforeMyStartVersion(datasourceVersion, monitor);
80
//		boolean isBeforeMyTargetVersion = isBeforeMyTargetVersion(targetVersion, monitor);
81
		boolean isBeforeMyTargetVersion = isBeforeMyTargetVersion(targetVersion, monitor);
82
		boolean isDatasourceBeforeMyTargetVersion = isBeforeMyTargetVersion(datasourceVersion, monitor);
83

    
84
		result &= isDatasourceBeforeMyTargetVersion;
85
		result &= !(isAfterMyStartVersion && isBeforeMyTargetVersion);
86
		result &= ! (isBeforeMyStartVersion && getPreviousUpdater() == null);
87
		result &= !isBeforeMyTargetVersion;
88
		return result;
89
	}
90

    
91
    @Override
92
	public void invoke(ICdmDataSource datasource, IProgressMonitor monitor,
93
	        CaseType caseType, SchemaUpdateResult result) throws Exception{
94
		String currentLibrarySchemaVersion = CdmMetaData.getDbSchemaVersion();
95
		invoke(currentLibrarySchemaVersion, datasource, monitor, caseType, result);
96
	}
97

    
98
	@Override
99
	public void invoke(String targetVersion, ICdmDataSource datasource,
100
	        IProgressMonitor monitor, CaseType caseType, SchemaUpdateResult result) throws Exception{
101

    
102
	    String datasourceVersion;
103

    
104
		try {
105
			datasourceVersion = getCurrentVersion(datasource, monitor, caseType);
106
		} catch (SQLException e1) {
107
		    String message = "SQLException";
108
			monitor.warning(message, e1);
109
			result.addException(e1, message, "UpdaterBase.invoke");
110
			return;
111
		}
112

    
113
		if (isBefore4_0_0(datasourceVersion, monitor, result)){
114
		    return;
115
		}
116

    
117
		boolean isAfterMyStartVersion = isAfterMyStartVersion(datasourceVersion, monitor);
118
		boolean isBeforeMyStartVersion = isBeforeMyStartVersion(datasourceVersion, monitor);
119
//		boolean isAfterMyTargetVersion = isAfterMyTargetVersion(targetVersion, monitor);
120
		boolean isBeforeMyTargetVersion = isBeforeMyTargetVersion(targetVersion, monitor);
121
		boolean isDatasourceBeforeMyTargetVersion = isBeforeMyTargetVersion(datasourceVersion, monitor);
122

    
123

    
124

    
125
		if (! isDatasourceBeforeMyTargetVersion){
126
			String warning = "Target version ("+targetVersion+") is not before updater target version ("+this.targetVersion+"). Nothing to update.";
127
			monitor.warning(warning);
128
			result.addWarning(warning);
129
			return;
130
		}
131

    
132
		if (isAfterMyStartVersion && isBeforeMyTargetVersion){
133
			String warning = "Database version is higher than updater start version but lower than updater target version";
134
			RuntimeException exeption = new RuntimeException(warning);
135
			monitor.warning(warning, exeption);
136
			throw exeption;
137
		}
138

    
139
		if (isBeforeMyStartVersion){
140
			if (getPreviousUpdater() == null){
141
				String warning = "Database version is before updater version but no previous version updater exists";
142
				RuntimeException exeption = new RuntimeException(warning);
143
				monitor.warning(warning, exeption);
144
				throw exeption;
145
			}
146
			getPreviousUpdater().invoke(startVersion, datasource, monitor, caseType, result);
147
		}
148

    
149
		if (isBeforeMyTargetVersion){
150
			String warning = "Target version ("+targetVersion+") is lower than updater target version ("+this.targetVersion+")";
151
			RuntimeException exeption = new RuntimeException(warning);
152
			monitor.warning(warning, exeption);
153
			throw exeption;
154
		}
155

    
156
		if (!result.isSuccess()){
157
			return;
158
		}
159
//		datasource.startTransaction();  transaction already started by CdmUpdater
160
		try {
161
			for (T step : list){
162
				handleSingleStep(datasource, monitor, result, step, false, caseType);
163
				if (!result.isSuccess()){
164
					break;
165
				}
166
			}
167
			if (result.isSuccess()){
168
				updateVersion(datasource, monitor, caseType, result);
169
			}else{
170
				datasource.rollback();
171
			}
172

    
173
		} catch (Exception e) {
174
			datasource.rollback();
175
			String message = "Error occurred while trying to run updater: " + this.getClass().getName();
176
			logger.error(message);
177
			result.addException(e, message, "UpdaterBase.invoke");
178
		}
179
		return;
180
	}
181

    
182
	protected void handleSingleStep(ICdmDataSource datasource, IProgressMonitor monitor, SchemaUpdateResult result, ISchemaUpdaterStep step, boolean isInnerStep, CaseType caseType)
183
			throws Exception {
184
		try {
185
			monitor.subTask(step.getStepName());
186
			step.invoke(datasource, monitor, caseType, result);
187
			for (ISchemaUpdaterStep innerStep : step.getInnerSteps()){
188
				handleSingleStep(datasource, monitor, result, innerStep, true, caseType);
189
				if (!result.isSuccess()){
190
				    break;
191
				}
192
			}
193
//			if (! isInnerStep){
194
			monitor.worked(1);
195
//			}
196
		} catch (Exception e) {
197
		    String message = "Monitor: Exception occurred while handling single schema updating step";
198
			monitor.warning(message, e);
199
			datasource.rollback();
200
			result.addException(e, message, "handleSingleStep:" + step.getStepName());
201
		}
202
		return;
203
	}
204

    
205
	   /**
206
     * @param datasourceVersion
207
     * @param monitor
208
     * @param result
209
     * @return
210
     */
211
    private boolean isBefore4_0_0(String datasourceVersion, IProgressMonitor monitor, SchemaUpdateResult result) {
212
        if (CdmMetaData.compareVersion(datasourceVersion, "4.0.0.0", 3, monitor) < 0){
213
            String message = "Schema version of the database is prior to version 4.0.0.\n"
214
                    + "Versions prior to 4.0.0 need to be updated by an EDIT Platform between 4.0 and 4.7 (including both).\n"
215
                    + "Please update first to version 4.0.0 (or higher) before updating to the current version.";
216
            result.addError(message, "CdmUpdater.updateToCurrentVersion");
217
            return true;
218
        }
219
        return false;
220
    }
221

    
222
	protected boolean isAfterMyStartVersion(String dataSourceSchemaVersion, IProgressMonitor monitor) {
223
		int depth = 4;
224
		int compareResult = CdmMetaData.compareVersion(dataSourceSchemaVersion, startVersion, depth, monitor);
225
		return compareResult > 0;
226
	}
227

    
228
	protected boolean isBeforeMyStartVersion(String dataSourceSchemaVersion, IProgressMonitor monitor) {
229
		int depth = 4;
230
		int compareResult = CdmMetaData.compareVersion(dataSourceSchemaVersion, startVersion, depth, monitor);
231
		return compareResult < 0;
232
	}
233

    
234
	protected boolean isAfterMyTargetVersion(String dataSourceSchemaVersion, IProgressMonitor monitor) {
235
		int depth = 4;
236
		int compareResult = CdmMetaData.compareVersion(dataSourceSchemaVersion, targetVersion, depth, monitor);
237
		return compareResult > 0;
238
	}
239

    
240
	protected boolean isBeforeMyTargetVersion(String dataSourceSchemaVersion, IProgressMonitor monitor) {
241
		int depth = 4;
242
		int compareResult = CdmMetaData.compareVersion(dataSourceSchemaVersion, targetVersion, depth, monitor);
243
		return compareResult < 0;
244
	}
245

    
246
	@Override
247
	public abstract U getNextUpdater();
248

    
249
	@Override
250
	public abstract U getPreviousUpdater();
251

    
252

    
253
	/**
254
	 * @return
255
	 */
256
	public String getTargetVersion() {
257
		return this.targetVersion;
258
	}
259
}
(34-34/35)