Project

General

Profile

Download (8.84 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.logging.log4j.LogManager;import org.apache.logging.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 = LogManager.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
		if (! isDatasourceBeforeMyTargetVersion){
124
			String warning = "Target version ("+targetVersion+") is not before updater target version ("+this.targetVersion+"). Nothing to update.";
125
			monitor.warning(warning);
126
			result.addWarning(warning);
127
			return;
128
		}
129

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

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

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

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

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

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

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

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

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

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

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

    
244
	@Override
245
	public abstract U getPreviousUpdater();
246

    
247
	public String getTargetVersion() {
248
		return this.targetVersion;
249
	}
250
}
(40-40/41)