integrating trunk
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / common / CdmMetaData.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 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
11 package eu.etaxonomy.cdm.model.common;
12
13 import java.util.ArrayList;
14 import java.util.Comparator;
15 import java.util.List;
16 import java.util.Map;
17
18 import javax.persistence.Entity;
19
20 import org.apache.log4j.Logger;
21 import org.joda.time.DateTime;
22
23 import eu.etaxonomy.cdm.common.IProgressMonitor;
24
25 /**
26 * @author a.mueller
27 * @created 07.09.2009
28 * @version 1.0
29 */
30 @Entity
31 public class CdmMetaData extends CdmBase{
32 private static final long serialVersionUID = -3033376680593279078L;
33 @SuppressWarnings("unused")
34 private static final Logger logger = Logger.getLogger(CdmMetaData.class);
35
36 /* It is a little bit confusing that this specific information is located in
37 * a generic class for metadata. Think about moving the schema version
38 *
39 */
40 /**
41 * The database schema version number.
42 * It is recommended to have the first two numbers equal to the CDM Library version number.
43 * But it is not obligatory as there may be cases when the library number changes but the
44 * schema version is not changing.
45 * The third should be incremented if the schema changes in a way that SCHEMA_VALIDATION.UPDATE
46 * will probably not work or will not be enough to transform old data into new data.
47 * The fourth number shoud be incremented when minor schema changes take place that can
48 * be handled by SCHEMA_VALIDATION.UPDATE
49 * The last number represents the date of change.
50 */
51 private static final String dbSchemaVersion = "3.0.0.0.201009201255";
52
53
54 /**
55 * @return a list of default metadata objects
56 */
57 public static final List<CdmMetaData> defaultMetaData(){
58 List<CdmMetaData> result = new ArrayList<CdmMetaData>();
59 // schema version
60 result.add(new CdmMetaData(MetaDataPropertyName.DB_SCHEMA_VERSION, dbSchemaVersion));
61 //term version
62 result.add(new CdmMetaData(MetaDataPropertyName.TERMS_VERSION, termsVersion));
63 // database create time
64 result.add(new CdmMetaData(MetaDataPropertyName.DB_CREATE_DATE, new DateTime().toString()));
65 return result;
66 }
67 /**
68 * The version number for the terms loaded by the termloader (csv-files)
69 * It is recommended to have the first two numbers equal to the CDM Library version number.
70 * But it is not obligatory as there may be cases when the library number changes but the
71 * schema version is not changing.
72 * The third should be incremented if the terms change in a way that is not compatible
73 * to the previous version (e.g. by changing the type of a term)
74 * The fourth number shoud be incremented when compatible term changes take place
75 * (e.g. when new terms were added)
76 * The last number represents the date of change.
77 */
78 private static final String termsVersion = "3.0.0.0.201009201255";
79
80
81 public enum MetaDataPropertyName{
82 DB_SCHEMA_VERSION,
83 TERMS_VERSION,
84 DB_CREATE_DATE,
85 DB_CREATE_NOTE
86 }
87
88 /* END OF CONFUSION */
89 private MetaDataPropertyName propertyName;
90 private String value;
91
92
93 /**
94 * Method to retrieve a CDM Libraries meta data
95 * @return
96 */
97 public static final List<CdmMetaData> propertyList(){
98 List<CdmMetaData> result = new ArrayList<CdmMetaData>();
99 result.add(new CdmMetaData(MetaDataPropertyName.DB_SCHEMA_VERSION, dbSchemaVersion));
100 result.add(new CdmMetaData(MetaDataPropertyName.TERMS_VERSION, termsVersion));
101 result.add(new CdmMetaData(MetaDataPropertyName.DB_CREATE_DATE, new DateTime().toString()));
102 return result;
103 }
104
105 //********************* Constructor *********************************************/
106
107 /**
108 * Simple constructor to be used by Spring
109 */
110 protected CdmMetaData(){
111 super();
112 }
113
114 public CdmMetaData(MetaDataPropertyName propertyName, String value) {
115 super();
116 this.propertyName = propertyName;
117 this.value = value;
118 }
119
120 //****************** instance methods ****************************************/
121
122 /**
123 * @return the propertyName
124 */
125 public MetaDataPropertyName getPropertyName() {
126 return propertyName;
127 }
128
129 /**
130 * @param propertyName the propertyName to set
131 */
132 public void setPropertyName(MetaDataPropertyName propertyName) {
133 this.propertyName = propertyName;
134 }
135
136 /**
137 * @return the value
138 */
139 public String getValue() {
140 return value;
141 }
142
143 /**
144 * @param value the value to set
145 */
146 public void setValue(String value) {
147 this.value = value;
148 }
149
150 //******************** Version comparator **********************************/
151
152 public static class VersionComparator implements Comparator<String>{
153 Integer depth;
154 IProgressMonitor monitor;
155
156 public VersionComparator(Integer depth, IProgressMonitor monitor){
157 this.depth = depth;
158 this.monitor = monitor;
159 }
160
161 /* (non-Javadoc)
162 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
163 */
164 public int compare(String version1, String version2) {
165 int result = 0;
166 String[] version1Split = version1.split("\\.");
167 String[] version2Split = version2.split("\\.");
168 if (version1Split.length != version2Split.length){
169 String warning = "Versionstrings are not compatible: " + version1 + "<->" + version2;
170 RuntimeException exception = new RuntimeException(warning);
171 if (monitor != null){
172 monitor.warning(warning, exception);
173 }
174 throw exception;
175 }
176 int length = (depth == null ||version1Split.length < depth) ? version1Split.length : depth;
177 for (int i = 0; i < length; i++){
178 Long version1Part = Long.valueOf(version1Split[i]);
179 Long version2Part = Long.valueOf(version2Split[i]);
180 int partCompare = version1Part.compareTo(version2Part);
181 if (partCompare != 0){
182 return partCompare;
183 }
184 }
185 return result;
186 }
187
188 }
189
190 /**
191 * Compares two version string. If version1 is higher than version2 a positive result is returned.
192 * If both are equal 0 is returned, otherwise -1 is returned.
193 * @see Comparator#compare(Object, Object)
194 * @param version1
195 * @param version2
196 * @param depth
197 * @param monitor
198 * @return
199 */
200 public static int compareVersion(String version1, String version2, Integer depth, IProgressMonitor monitor){
201 VersionComparator versionComparator = new VersionComparator(depth, monitor);
202 return versionComparator.compare(version1, version2);
203 }
204
205 //************************ STATIC SCHEMA VERSION METHODS ************************/
206
207 public static String getCurrentSchemaVersion() {
208 return dbSchemaVersion;
209 }
210
211 /**
212 * Gets the first i parts of the current CdmLibrary schema version.
213 * @param allCommonData
214 * @return current schema version.
215 */
216 public static String getCurrentSchemaVersion(int i) {
217 // Get current schema version
218 String schemaVersion = CdmMetaData.getCurrentSchemaVersion();
219 return getVersion(schemaVersion, i);
220 }
221
222 /**
223 * Gets the first i parts of the passed database schema version.
224 * @param allCommonData
225 * @return database schema version.
226 */
227 public static String getDatabaseSchemaVersion(Map<MetaDataPropertyName, CdmMetaData> cdmMetaDataFromDatabase, int i) {
228 // Get database schema version
229 String schemaVersion = cdmMetaDataFromDatabase.get(MetaDataPropertyName.DB_SCHEMA_VERSION).getValue();
230 return getVersion(schemaVersion, i);
231 }
232
233
234 public static boolean isVersionEqual(String databaseSchemaVersion, int index){
235 String currentSchemaVersionPrefix = getCurrentSchemaVersion(index);
236 String databaseSchemaVersionPrefix = getVersion(databaseSchemaVersion, index);
237 if (currentSchemaVersionPrefix.equals( databaseSchemaVersionPrefix)) {
238 return true;
239 }
240 return false;
241 }
242
243
244 //************************ STATIC TERMS VERSION METHODS ************************/
245 public static String getCurrentTermsVersion() {
246 return dbSchemaVersion;
247 }
248
249 /**
250 * Gets the first i parts of the current CdmLibrary terms version.
251 * @param allCommonData
252 * @return current schema version.
253 */
254 public static String getCurrentTermsVersion(int i) {
255 // Get current schema version
256 String schemaVersion = CdmMetaData.getCurrentTermsVersion();
257 return getVersion(schemaVersion, i);
258 }
259
260 /**
261 * Gets the first i parts of the passed database schema version.
262 * @param allCommonData
263 * @return database schema version.
264 */
265 public static String getDatabaseTermsVersion(Map<MetaDataPropertyName, CdmMetaData> cdmMetaDataFromDatabase, int i) {
266 // Get database schema version
267 String termsVersion = cdmMetaDataFromDatabase.get(MetaDataPropertyName.TERMS_VERSION).getValue();
268 return getVersion(termsVersion, i);
269 }
270
271
272
273
274 //************************ helping methods ************************/
275
276 /**
277 * @param versionProperty
278 * @return Version number as string.
279 */
280 private static String getVersion(String versionProperty, int i) {
281 return versionProperty.substring(0, nthIndexOf(versionProperty, ".", i));
282 }
283
284 /**
285 * Calculates the n-th occurrence of a string.
286 * @param versionProperty
287 * @return Index of N-th occurence of a string.
288 */
289 private static int nthIndexOf(String versionProperty, String pattern, int n) {
290 int currentIndex = -1;
291 for (int i=0; i<n; i++) {
292 currentIndex = versionProperty.indexOf(pattern, currentIndex + 1);
293 }
294 return currentIndex;
295 }
296
297
298
299 }