File: MigrationUtils.java

package info (click to toggle)
mysql-admin 1.2.5rc-2
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 80,944 kB
  • ctags: 43,103
  • sloc: sql: 295,916; pascal: 256,535; cpp: 74,487; ansic: 68,881; objc: 26,417; sh: 16,867; yacc: 10,755; java: 9,917; xml: 8,453; php: 2,806; python: 2,068; makefile: 1,252; perl: 3
file content (333 lines) | stat: -rw-r--r-- 10,572 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
package com.mysql.grt.modules;

import java.util.HashMap;
import java.util.regex.Pattern;
import java.util.List;
import java.util.ArrayList;
import com.mysql.grt.*;
import com.mysql.grt.base.*;
import com.mysql.grt.db.migration.*;

/**
 * GRT Migration Class
 * 
 * @author MikeZ
 * @version 1.0, 01/23/05
 * 
 */
public class MigrationUtils {

	private HashMap logObjects = new HashMap();

	private HashMap sourceTargetObjectMapping = new HashMap();

	private List ignoreList;

	protected final static int logNoText = 0;

	protected final static int logWarning = 1;

	protected final static int logError = 2;
 
	/**
	 * Checks if an object is on the ignore list
	 * 
	 * @param mig
	 *            the migration object
	 * @param sourceObject
	 *            the object that should be migrated
	 * @return the migrated object
	 */
	public boolean isOnIgnoreList(com.mysql.grt.db.migration.Migration migObj,
			GrtObject sourceObject) {
		// only instances of DatabaseObject can be on the ignore list
		// if they are not a Schema
		if ((sourceObject instanceof com.mysql.grt.db.DatabaseObject)
				&& !(sourceObject instanceof com.mysql.grt.db.Schema)) {

			// if the ignore list was not needed till now
			// build it
			if (ignoreList == null) {
				ignoreList = new ArrayList();

				for (int i = 0; i < migObj.getIgnoreList().size(); i++) {
					String ignoreString = (String) migObj.getIgnoreList()
							.getObject(i);
					
					ignoreString = Grt.replace(ignoreString, "$", "\\$");

					ignoreString = ignoreString.replaceAll("\\\\", "\\\\")
							.replaceAll("\\.",
									"\\\\.").replaceAll("\\*", ".*")
							.replaceAll("\\?", ".");

					ignoreList.add(Pattern.compile(ignoreString));
				}
			}

			// the format of objectName is, e.g. db.oracle.Table:SCOTT.emp
			String objectName = sourceObject.getClass().getName().substring(14)
					+ ":" + sourceObject.getOwner().getName() + "."
					+ sourceObject.getName();

			// check if that object is on the ignore list
			for (int i = 0; i < ignoreList.size(); i++) {
				Pattern p = (Pattern) ignoreList.get(i);

				// if this is a match, the object is on the ignore list
				// so null is returned
				if (p.matcher(objectName).matches())
					return true;
			}
		}
		return false;
	}

	/**
	 * Migrates an object based on the mappings defined in the migration object.
	 * If no explicit mapping is defined, the object is migrated using the
	 * default migration method for the source object's class
	 * 
	 * @param callerObject
	 *            the object that is calling this function
	 * @param mig
	 *            the migration object
	 * @param sourceObject
	 *            the object that should be migrated
	 * @param parent
	 *            the object will become the parent of the migrated object
	 * @return the migrated object
	 */
	public GrtObject migrateObject(Object callerObject,
			com.mysql.grt.db.migration.Migration migObj,
			GrtObject sourceObject, GrtObject parent) {

		if (isOnIgnoreList(migObj, sourceObject))
			return null;

		// check if we have a special mapping for this item
		MappingList mappings = migObj.getMappingDefinitions();

		if (mappings != null) {
			for (int i = 0; i < mappings.size(); i++) {
				Mapping mapping = mappings.get(i);

				if (mapping.getSourceObject().get_id().equals(
						sourceObject.get_id())) {

					String sourceStructName = Grt.GrtPackagePrefix
							+ mapping.getSourceStructName();

					return callMigrationMethod(callerObject, migObj, mapping
							.getModuleName(), mapping.getMethodName(),
							sourceStructName, sourceObject,
							mapping.getParams(), parent);
				}
			}
		}

		// if it was not found, use default mapping if there is any
		MappingList defaultMappings = migObj.getMappingDefaults();

		if (defaultMappings != null) {
			for (int i = 0; i < defaultMappings.size(); i++) {
				Mapping mapping = defaultMappings.get(i);

				try {
					Class mappingSourceClass = Class
							.forName(Grt.GrtPackagePrefix
									+ mapping.getSourceStructName());

					// if this method returns the correct class
					if (mappingSourceClass.isInstance(sourceObject)) {
						return callMigrationMethod(callerObject, migObj,
								mapping.getModuleName(), mapping
										.getMethodName(), mappingSourceClass
										.getName(), sourceObject, mapping
										.getParams(), parent);
					}
				} catch (ClassNotFoundException e) {
					// if the class is not found do not migrate
				}
			}
		}

		// now check the complete method list to see if there is a appropriate
		// method to migrate the source object. If there are several, take the
		// highes rated as it will be the best
		MethodList methods = migObj.getMigrationMethods();

		if (methods != null) {
			com.mysql.grt.db.migration.Method bestMethod = null;
			Class bestMethodSourceClass = null;

			for (int i = 0; i < methods.size(); i++) {
				com.mysql.grt.db.migration.Method method = methods.get(i);

				try {
					Class mappingSourceClass = Class
							.forName(Grt.GrtPackagePrefix
									+ method.getSourceStructName());

					// if this method returns the correct class
					// and we do not have any other method yet or
					// the method just found has a higher rating than the
					// one we had before the method is stored as to best one
					// so far
					if ((mappingSourceClass.isInstance(sourceObject))
							&& ((bestMethod == null) || (method.getRating() > bestMethod
									.getRating()))) {
						bestMethod = method;
						bestMethodSourceClass = mappingSourceClass;
					}
				} catch (ClassNotFoundException e) {
					// if the class is not found, ignore it
				}
			}

			try {
				if ((bestMethod != null) && (bestMethodSourceClass != null))
					return callMigrationMethod(callerObject, migObj, bestMethod
							.getModuleName(), bestMethod.getName(),
							bestMethodSourceClass.getName(), sourceObject,
							bestMethod.getParams(), parent);
			} catch (Exception e) {
				addMigrationLogEntry(
						migObj,
						sourceObject,
						null,
						"An error occured during the call of the "
								+ bestMethod.getName()
								+ " function to migrate an object from the class "
								+ sourceObject.getClass().getName() + ".",
						logError);
			}
		}

		// if no mapping was found at all, set make an entry in to the log and
		// return null
		addMigrationLogEntry(migObj, sourceObject, null,
				"There is no method defined to migration an object of the type "
						+ sourceObject.getClass().getName() + ".", logError);

		return null;
	}

	/**
	 * Calls a migration method base on the module and method name
	 * 
	 * @param moduleName
	 *            the module the method belongs to, e.g. MigrationOracle
	 * @param methodName
	 *            the name of the method
	 * @param sourceObject
	 *            the object to migrate
	 * @param params
	 *            the parameters that should be used to migrate the source
	 *            object
	 * @return the migrated object
	 */
	public GrtObject callMigrationMethod(Object callerObject,
			com.mysql.grt.db.migration.Migration migObj, String moduleName,
			String methodName, String sourceObjectClassName,
			GrtObject sourceObject, GrtStringHashMap params, GrtObject parent) {
		try {
			// find the module's class
			Class moduleClass = Class.forName(Grt.GrtModulePackagePrefix
					+ moduleName);

			// prepare the method's arguments
			Class[] arguments = new Class[] {
					com.mysql.grt.db.migration.Migration.class,
					Class.forName(sourceObjectClassName),
					GrtStringHashMap.class, GrtObject.class };

			// find the method
			java.lang.reflect.Method method = moduleClass.getDeclaredMethod(
					methodName, arguments);

			// invoke migration method
			return (GrtObject) method.invoke(callerObject, new Object[] {
					migObj, sourceObject, params, parent });
		} catch (Exception e) {
			String name = sourceObject.getName();
			if (name == null)
				name = "<NULL>";
			
			addMigrationLogEntry(migObj, sourceObject, null,
					"An exception occured when the migration method was invoked for "
							+ name + " (" + e.getMessage()
							+ ").", logError);
			return null;
		}
	}

	public void addMigrationLogEntry(
			com.mysql.grt.db.migration.Migration migObj, GrtObject sourceObj,
			GrtObject targetObj) {
		addMigrationLogEntry(migObj, sourceObj, targetObj, null, logNoText);
	}

	public void addMigrationLogEntry(
			com.mysql.grt.db.migration.Migration migObj, GrtObject sourceObj,
			GrtObject targetObj, String message, int messageType) {

		// Add sourceObj and targetObj to sourceTargetObjectMapping
		// so it is faster to find the sourceObj to a given targetObj
		if ((sourceObj != null) && (targetObj != null))
			sourceTargetObjectMapping.put(sourceObj.get_id(), targetObj
					.get_id());

		// try to find existing log entry for this object
		ObjectLog objectLog = (ObjectLog) logObjects.get(sourceObj);

		// if no entry is found add a new one
		if (objectLog == null) {
			objectLog = new ObjectLog(null);
			objectLog.setLogObject(sourceObj);

			if (targetObj != null)
				objectLog.setRefObject(targetObj);

			// insert log entry into log list and get the global reference back
			objectLog = migObj.getMigrationLog().add(objectLog);

			// store the entry on the hashmap, so it can be found faster
			logObjects.put(sourceObj, objectLog);
		}

		if ((messageType != logNoText) && (message != null)) {
			// if there is a targetObj defined, set it
			if (targetObj != null)
				objectLog.setRefObject(targetObj);

			// create new log message
			ObjectLogEntry logMessage = new ObjectLogEntry(null);

			// set message members
			logMessage.setName(message);
			logMessage.setEntryType(messageType);

			// store it in the global logEntry
			objectLog.getEntries().add(logMessage);
		}
	}

	public GrtObject findTargetObject(GrtObject sourceObj) {
		return (GrtObject) Grt.getInstance().getObjectByRefId(
				(String) (sourceTargetObjectMapping.get(sourceObj.get_id())));
	}

	public String getTargetName(GrtStringHashMap migrationParams,
			String sourceName) {
		String targetName = null;

		if (migrationParams != null)
			targetName = migrationParams.get("targetName");

		if ((targetName != null) && !targetName.equals(""))
			return targetName;
		else
			return sourceName;
	}
}