1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.jumpmind.symmetric.model;
23
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.Date;
27 import java.util.List;
28 import java.util.StringTokenizer;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.ddlutils.model.Column;
33 import org.apache.ddlutils.model.Table;
34
35 /***
36 * Defines the trigger via which a table will be synchronized.
37 */
38 public class Trigger {
39
40 static final Log logger = LogFactory.getLog(Trigger.class);
41
42 private static final long serialVersionUID = 8947288471097851573L;
43
44 private static final String DEFAULT_CONDITION = "1=1";
45
46 private int triggerId;
47
48 private String sourceTableName;
49
50 private String targetTableName;
51
52 private String sourceGroupId;
53
54 private String channelId;
55
56 private String targetGroupId;
57
58 private String sourceSchemaName;
59
60 private String sourceCatalogName;
61
62 private String targetSchemaName;
63
64 private boolean syncOnUpdate = true;
65
66 private boolean syncOnInsert = true;
67
68 private boolean syncOnDelete = true;
69
70 private boolean syncOnIncomingBatch = false;
71
72 private boolean syncColumnLevel = false;
73
74 private String nameForInsertTrigger;
75
76 private String nameForUpdateTrigger;
77
78 private String nameForDeleteTrigger;
79
80 private String syncOnUpdateCondition = DEFAULT_CONDITION;
81
82 private String syncOnInsertCondition = DEFAULT_CONDITION;
83
84 private String syncOnDeleteCondition = DEFAULT_CONDITION;
85
86 private String excludedColumnNames = null;
87
88 /***
89 * Allows the end user to limit the data loaded when doing the initial load.
90 * if null, will default to 'from tablename'
91 */
92 private String initialLoadSelect = DEFAULT_CONDITION;
93
94 /***
95 * Default to selecting all. This can be changed to select based on joins
96 * between node parameters and data column values.
97 */
98 private String nodeSelect = "";
99
100 /***
101 * This is a sql expression that creates a unique id which the sync process
102 * can use to 'group' events together and commit together.
103 */
104 private String txIdExpression = null;
105
106 /***
107 * This is the order in which the definitions will be processed.
108 */
109 private int initialLoadOrder;
110
111 private Date inactiveTime;
112
113 private Date createdOn;
114
115 private Date lastModifiedTime;
116
117 private String updatedBy;
118
119 public Trigger() {
120 }
121
122 public Trigger(String tableName, boolean syncOnUpdate, boolean syncOnInsert, boolean syncOnDelete,
123 String configurationId, String channelId, String syncOnUpdateCondition, String syncOnInsertCondition,
124 String syncOnDeleteCondition) {
125 this.sourceTableName = tableName;
126 this.syncOnUpdate = syncOnUpdate;
127 this.syncOnInsert = syncOnInsert;
128 this.syncOnDelete = syncOnDelete;
129 this.sourceGroupId = configurationId;
130 this.channelId = channelId;
131 this.syncOnUpdateCondition = syncOnUpdateCondition;
132 this.syncOnInsertCondition = syncOnInsertCondition;
133 this.syncOnDeleteCondition = syncOnDeleteCondition;
134 }
135
136 public Date getCreatedOn() {
137 return createdOn;
138 }
139
140 public Date getLastModifiedTime() {
141 return lastModifiedTime;
142 }
143
144 public String getUpdatedBy() {
145 return updatedBy;
146 }
147
148 public void setCreatedOn(Date createdOn) {
149 this.createdOn = createdOn;
150 }
151
152 public void setLastModifiedTime(Date lastModifiedOn) {
153 this.lastModifiedTime = lastModifiedOn;
154 }
155
156 public void setUpdatedBy(String updatedBy) {
157 this.updatedBy = updatedBy;
158 }
159
160 /***
161 * When dealing with columns, always use this method to order the columns so
162 * that the primary keys are first.
163 */
164 public Column[] orderColumnsForTable(Table table) {
165 List<String> excludedColumnNames = getExcludedColumnNamesAsList();
166 Column[] pks = table.getPrimaryKeyColumns();
167 Column[] cols = table.getColumns();
168 List<Column> orderedColumns = new ArrayList<Column>(cols.length);
169 for (int i = 0; i < pks.length; i++) {
170 orderedColumns.add(pks[i]);
171 }
172 for (int i = 0; i < cols.length; i++) {
173 Column col = cols[i];
174 if (!col.isPrimaryKey() && !excludedColumnNames.contains(col.getName().toLowerCase())) {
175 orderedColumns.add(col);
176 }
177 }
178 return orderedColumns.toArray(new Column[orderedColumns.size()]);
179 }
180
181 @SuppressWarnings("unchecked")
182 private List<String> getExcludedColumnNamesAsList() {
183 if (excludedColumnNames != null && excludedColumnNames.length() > 0) {
184 StringTokenizer tokenizer = new StringTokenizer(excludedColumnNames, ",");
185 List<String> columnNames = new ArrayList<String>(tokenizer.countTokens());
186 while (tokenizer.hasMoreTokens()) {
187 columnNames.add(tokenizer.nextToken().toLowerCase());
188 }
189 return columnNames;
190 } else {
191 return Collections.EMPTY_LIST;
192 }
193 }
194
195 public boolean hasChangedSinceLastTriggerBuild(Date lastTriggerBuildTime) {
196 return lastTriggerBuildTime == null || getLastModifiedTime() == null
197 || lastTriggerBuildTime.before(getLastModifiedTime());
198 }
199
200 public String getChannelId() {
201 return channelId;
202 }
203
204 public void setChannelId(String channelId) {
205 this.channelId = channelId;
206 }
207
208 public String getSourceGroupId() {
209 return sourceGroupId;
210 }
211
212 public void setSourceGroupId(String domainName) {
213 this.sourceGroupId = domainName;
214 }
215
216 public boolean isSyncOnDelete() {
217 return syncOnDelete;
218 }
219
220 public void setSyncOnDelete(boolean syncOnDelete) {
221 this.syncOnDelete = syncOnDelete;
222 }
223
224 public String getSyncOnDeleteCondition() {
225 return syncOnDeleteCondition;
226 }
227
228 public void setSyncOnDeleteCondition(String syncOnDeleteCondition) {
229 this.syncOnDeleteCondition = syncOnDeleteCondition;
230 }
231
232 public boolean isSyncOnInsert() {
233 return syncOnInsert;
234 }
235
236 public void setSyncOnInsert(boolean syncOnInsert) {
237 this.syncOnInsert = syncOnInsert;
238 }
239
240 public String getSyncOnInsertCondition() {
241 return syncOnInsertCondition;
242 }
243
244 public void setSyncOnInsertCondition(String syncOnInsertCondition) {
245 this.syncOnInsertCondition = syncOnInsertCondition;
246 }
247
248 public boolean isSyncOnUpdate() {
249 return syncOnUpdate;
250 }
251
252 public void setSyncOnUpdate(boolean syncOnUpdate) {
253 this.syncOnUpdate = syncOnUpdate;
254 }
255
256 public String getSyncOnUpdateCondition() {
257 return syncOnUpdateCondition;
258 }
259
260 public void setSyncOnUpdateCondition(String syncOnUpdateCondition) {
261 this.syncOnUpdateCondition = syncOnUpdateCondition;
262 }
263
264 public String getSourceTableName() {
265 return sourceTableName;
266 }
267
268 public void setSourceTableName(String tableName) {
269 this.sourceTableName = tableName;
270 }
271
272 public String getNodeSelect() {
273 return nodeSelect;
274 }
275
276 public void setNodeSelect(String registrantSelect) {
277 this.nodeSelect = registrantSelect;
278 }
279
280 public String getTxIdExpression() {
281 return txIdExpression;
282 }
283
284 public void setTxIdExpression(String batchIdExpression) {
285 this.txIdExpression = batchIdExpression;
286 }
287
288 public String getInitialLoadSelect() {
289 return initialLoadSelect;
290 }
291
292 public void setInitialLoadSelect(String initialLoadExpression) {
293 this.initialLoadSelect = initialLoadExpression;
294 }
295
296 public int getInitialLoadOrder() {
297 return initialLoadOrder;
298 }
299
300 public void setInitialLoadOrder(int order) {
301 this.initialLoadOrder = order;
302 }
303
304 public String getSourceSchemaName() {
305 return sourceSchemaName;
306 }
307
308 public void setSourceSchemaName(String schemaName) {
309 this.sourceSchemaName = schemaName;
310 }
311
312 public String getExcludedColumnNames() {
313 return excludedColumnNames;
314 }
315
316 public void setExcludedColumnNames(String excludeColumnNames) {
317 this.excludedColumnNames = excludeColumnNames;
318 }
319
320 public String getTargetGroupId() {
321 return targetGroupId;
322 }
323
324 public void setTargetGroupId(String targetDomainName) {
325 this.targetGroupId = targetDomainName;
326 }
327
328 public String getNameForDeleteTrigger() {
329 return nameForDeleteTrigger;
330 }
331
332 public void setNameForDeleteTrigger(String nameForDeleteTrigger) {
333 this.nameForDeleteTrigger = nameForDeleteTrigger;
334 }
335
336 public String getNameForInsertTrigger() {
337 return nameForInsertTrigger;
338 }
339
340 public void setNameForInsertTrigger(String nameForInsertTrigger) {
341 this.nameForInsertTrigger = nameForInsertTrigger;
342 }
343
344 public String getNameForUpdateTrigger() {
345 return nameForUpdateTrigger;
346 }
347
348 public void setNameForUpdateTrigger(String nameForUpdateTrigger) {
349 this.nameForUpdateTrigger = nameForUpdateTrigger;
350 }
351
352 public int getTriggerId() {
353 return triggerId;
354 }
355
356 public void setTriggerId(int triggerId) {
357 this.triggerId = triggerId;
358 }
359
360 public Date getInactiveTime() {
361 return inactiveTime;
362 }
363
364 public void setInactiveTime(Date inactiveTime) {
365 this.inactiveTime = inactiveTime;
366 }
367
368 public String getTargetSchemaName() {
369 return targetSchemaName;
370 }
371
372 public void setTargetSchemaName(String targetSchemaName) {
373 this.targetSchemaName = targetSchemaName;
374 }
375
376 public String getTargetTableName() {
377 return targetTableName;
378 }
379
380 public void setTargetTableName(String targetTableName) {
381 this.targetTableName = targetTableName;
382 }
383
384 public boolean isSyncOnIncomingBatch() {
385 return syncOnIncomingBatch;
386 }
387
388 public void setSyncOnIncomingBatch(boolean syncOnIncomingBatch) {
389 this.syncOnIncomingBatch = syncOnIncomingBatch;
390 }
391
392 public String getSourceCatalogName() {
393 return sourceCatalogName;
394 }
395
396 public void setSourceCatalogName(String sourceCatalogName) {
397 this.sourceCatalogName = sourceCatalogName;
398 }
399
400 public boolean isSyncColumnLevel() {
401 return syncColumnLevel;
402 }
403
404 public void setSyncColumnLevel(boolean syncColumnLevel) {
405 this.syncColumnLevel = syncColumnLevel;
406 }
407
408 public long getHashedValue() {
409 long hashedValue = triggerId;
410 if (null != sourceTableName) {
411 hashedValue += sourceTableName.hashCode();
412 }
413
414 if (null != targetTableName ) {
415 hashedValue += targetTableName.hashCode();
416 }
417
418 if (null != sourceGroupId) {
419 hashedValue += sourceGroupId.hashCode();
420 }
421
422 if (null != channelId) {
423 hashedValue += channelId.hashCode();
424 }
425
426 if (null != targetGroupId) {
427 hashedValue += targetGroupId.hashCode();
428 }
429
430 if (null != sourceSchemaName) {
431 hashedValue += sourceSchemaName.hashCode();
432 }
433
434 if (null != sourceCatalogName) {
435 hashedValue += sourceCatalogName.hashCode();
436 }
437
438 if (null != targetSchemaName) {
439 hashedValue += targetSchemaName.hashCode();
440 }
441
442 hashedValue += syncOnUpdate ? 1 : 0;
443 hashedValue += syncOnInsert ? 1 : 0;
444 hashedValue += syncOnDelete ? 1 : 0;
445 hashedValue += syncOnIncomingBatch ? 1 : 0;
446 hashedValue += syncColumnLevel ? 1 : 0;
447
448 if (null != nameForInsertTrigger) {
449 hashedValue += nameForInsertTrigger.hashCode();
450 }
451
452 if (null != nameForUpdateTrigger) {
453 hashedValue += nameForUpdateTrigger.hashCode();
454 }
455
456 if (null != nameForDeleteTrigger) {
457 hashedValue += nameForDeleteTrigger.hashCode();
458 }
459
460 if (null != syncOnUpdateCondition) {
461 hashedValue += syncOnUpdateCondition.hashCode();
462 }
463
464 if (null != syncOnInsertCondition) {
465 hashedValue += syncOnInsertCondition.hashCode();
466 }
467
468 if (null != syncOnDeleteCondition) {
469 hashedValue += syncOnDeleteCondition.hashCode();
470 }
471
472 if (null != excludedColumnNames) {
473 hashedValue += excludedColumnNames.hashCode();
474 }
475
476 return hashedValue;
477 }
478
479 }