/* * Copyright (c) 2013, 2016 Eike Stepper (Berlin, Germany) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Eike Stepper - initial API and implementation */ package org.eclipse.net4j.internal.db.ddl.delta; import org.eclipse.net4j.db.ddl.IDBSchemaElement; import org.eclipse.net4j.db.ddl.delta.IDBDelta; import org.eclipse.net4j.db.ddl.delta.IDBDeltaVisitor; import org.eclipse.net4j.db.ddl.delta.IDBDeltaVisitor.StopRecursion; import org.eclipse.net4j.internal.db.ddl.DBNamedElement; import org.eclipse.net4j.internal.db.ddl.DBSchemaElement; import org.eclipse.net4j.util.StringUtil; import org.eclipse.net4j.util.collection.PositionProvider; import java.io.IOException; import java.io.Writer; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * @author Eike Stepper */ public abstract class DBDelta extends DBNamedElement implements IDBDelta { private static final IDBDelta[] NO_ELEMENTS = {}; private static final long serialVersionUID = 1L; private DBDelta parent; private ChangeKind changeKind; private transient IDBDelta[] elements; public DBDelta(DBDelta parent, String name, ChangeKind changeKind) { super(name); this.parent = parent; this.changeKind = changeKind; } /** * Constructor for deserialization. */ protected DBDelta() { } public DBDelta getParent() { return parent; } public final ChangeKind getChangeKind() { return changeKind; } public final int compareTo(IDBDelta delta2) { int result = getDeltaType().compareTo(delta2.getDeltaType()); if (result == 0) { if (this instanceof PositionProvider && delta2 instanceof PositionProvider) { PositionProvider withPosition1 = (PositionProvider)this; PositionProvider withPosition2 = (PositionProvider)delta2; return withPosition1.getPosition() - withPosition2.getPosition(); } result = getName().compareTo(delta2.getName()); } return result; } public final void accept(IDBDeltaVisitor visitor) { try { doAccept(visitor); } catch (StopRecursion ex) { return; } for (IDBDelta delta : getElements()) { delta.accept(visitor); } } protected abstract void doAccept(IDBDeltaVisitor visitor); public final boolean isEmpty() { return getElements().length == 0; } public final IDBDelta[] getElements() { if (elements == null) { List<IDBDelta> result = new ArrayList<IDBDelta>(); collectElements(result); if (result.isEmpty()) { elements = NO_ELEMENTS; } else { elements = result.toArray(new IDBDelta[result.size()]); Arrays.sort(elements); } } return elements; } protected final void resetElements() { elements = null; } protected abstract void collectElements(List<IDBDelta> elements); public void dump(Writer writer) throws IOException { int level = getLevel(); for (int i = 0; i < level; i++) { writer.append(" "); } writer.append(getChangeKind().toString()); writer.append(" "); writer.append(getDeltaType().toString()); writer.append(" "); writer.append(getName()); dumpAdditionalProperties(writer); writer.append(StringUtil.NL); for (IDBDelta delta : getElements()) { ((DBDelta)delta).dump(writer); } } protected void dumpAdditionalProperties(Writer writer) throws IOException { } private int getLevel() { if (parent == null) { return 0; } return parent.getLevel() + 1; } public static String getName(IDBSchemaElement element, IDBSchemaElement oldElement) { return oldElement == null ? element.getName() : oldElement.getName(); } public static ChangeKind getChangeKind(Object object, Object oldObject) { return object == null ? ChangeKind.REMOVE : oldObject == null ? ChangeKind.ADD : ChangeKind.CHANGE; } protected static <T extends IDBSchemaElement> void compare(T[] elements, T[] oldElements, SchemaElementComparator<T> comparator) { for (int i = 0; i < elements.length; i++) { T element = elements[i]; String name = element.getName(); T oldElement = DBSchemaElement.findElement(oldElements, name); comparator.compare(element, oldElement); } for (int i = 0; i < oldElements.length; i++) { T oldElement = oldElements[i]; String name = oldElement.getName(); if (DBSchemaElement.findElement(elements, name) == null) { comparator.compare(null, oldElement); } } } /** * @author Eike Stepper */ public interface SchemaElementComparator<T extends IDBSchemaElement> { public void compare(T element, T oldElement); } }