blob: d8d24ee5a97192ffc919c03984c42ccd6ea942d3 [file] [log] [blame]
/**
* Copyright (c) 2004 - 2011 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.emf.cdo.threedee.common;
import org.eclipse.net4j.util.io.ExtendedDataInputStream;
import org.eclipse.net4j.util.io.ExtendedDataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @author Eike Stepper
*/
public abstract class ElementEvent
{
public abstract int getType();
public abstract void write(ExtendedDataOutputStream out) throws IOException;
public static ElementEvent read(ExtendedDataInputStream in, ElementProvider provider, byte type) throws IOException
{
switch (type)
{
case Create.TYPE:
return new Create(in, provider);
case Call.TYPE:
return new Call(in, provider);
case Transmit.TYPE:
return new Transmit(in, provider);
case Change.TYPE:
return new Change(in);
case Remove.TYPE:
return new Remove(in);
default:
throw new RuntimeException();
}
}
/**
* @author Eike Stepper
*/
public static class Create extends ElementEvent
{
public static final byte TYPE = 1;
private Element element;
private boolean root;
public Create(Element element, boolean root)
{
this.element = element;
this.root = root;
}
public Create(ExtendedDataInputStream in, ElementProvider provider) throws IOException
{
element = new Element(in, provider);
root = in.readBoolean();
}
@Override
public void write(ExtendedDataOutputStream out) throws IOException
{
element.write(out);
out.writeBoolean(root);
}
@Override
public int getType()
{
return TYPE;
}
public Element getElement()
{
return element;
}
public boolean isRoot()
{
return root;
}
@Override
public String toString()
{
return "CREATE " + element;
}
}
/**
* @author Eike Stepper
*/
public static class Call extends ElementEvent
{
public static final byte TYPE = 2;
private Element source;
private Element target;
private String what;
private When when;
public Call(Element source, Element target, String what, When when)
{
this.source = source;
this.target = target;
this.what = what;
this.when = when;
}
public Call(ExtendedDataInputStream in, ElementProvider provider) throws IOException
{
int sourceID = in.readInt();
source = provider.getElement(sourceID);
int targetID = in.readInt();
target = provider.getElement(targetID);
what = in.readString();
when = in.readBoolean() ? When.BEFORE : When.AFTER;
}
@Override
public void write(ExtendedDataOutputStream out) throws IOException
{
out.writeInt(source.getID());
out.writeInt(target.getID());
out.writeString(what);
out.writeBoolean(when == When.BEFORE);
}
@Override
public int getType()
{
return TYPE;
}
public Element getSource()
{
return source;
}
public Element getTarget()
{
return target;
}
public String getWhat()
{
return what;
}
public When getWhen()
{
return when;
}
@Override
public String toString()
{
String prefix = "CALL " + when + " ";
String suffix = target.getDescriptor().getLabel() + "." + what + "()";
if (source == null)
{
return prefix + suffix;
}
return prefix + source.getDescriptor().getLabel() + " --> " + suffix;
}
/**
* @author Eike Stepper
*/
public static enum When
{
BEFORE, AFTER
}
}
/**
* @author Eike Stepper
*/
public static class Transmit extends ElementEvent
{
public static final byte TYPE = 3;
private Element transmitter;
public Transmit(Element transmitter)
{
this.transmitter = transmitter;
}
public Transmit(ExtendedDataInputStream in, ElementProvider provider) throws IOException
{
int connectorID = in.readInt();
transmitter = provider.getElement(connectorID);
}
@Override
public void write(ExtendedDataOutputStream out) throws IOException
{
out.writeInt(transmitter.getID());
}
@Override
public int getType()
{
return TYPE;
}
public Element getTransmitter()
{
return transmitter;
}
@Override
public String toString()
{
return "TRANSMIT " + transmitter;
}
}
/**
* @author Eike Stepper
*/
public static class Change extends ElementEvent
{
public static final byte TYPE = 5;
private int id;
private List<ChangeInfo> changeInfos;
public Change(int id)
{
this.id = id;
}
public Change(ExtendedDataInputStream in) throws IOException
{
id = in.readInt();
int size = in.readInt();
changeInfos = new ArrayList<ChangeInfo>(size);
for (int i = 0; i < size; i++)
{
if (in.readBoolean())
{
changeInfos.add(new ChangeInfo.Attribute(in));
}
else
{
changeInfos.add(new ChangeInfo.Reference(in));
}
}
}
@Override
public void write(ExtendedDataOutputStream out) throws IOException
{
out.writeInt(id);
out.writeInt(changeInfos.size());
for (ChangeInfo changeInfo : changeInfos)
{
out.writeBoolean(changeInfo instanceof ChangeInfo.Attribute);
changeInfo.write(out);
}
}
@Override
public int getType()
{
return TYPE;
}
public int getID()
{
return id;
}
public List<ChangeInfo> getChangeInfos()
{
return changeInfos;
}
public boolean isEmpty()
{
return changeInfos == null;
}
public void attributeChanged(String key, String newValue)
{
List<ChangeInfo> changeInfo = ensureChangeInfos();
changeInfo.add(new ChangeInfo.Attribute(key, newValue));
}
public void attributeRemoved(String key)
{
attributeChanged(key, null);
}
public void referenceAdded(int id, boolean containment)
{
List<ChangeInfo> changeInfo = ensureChangeInfos();
changeInfo.add(new ChangeInfo.Reference(ChangeInfo.Reference.Kind.ADDED, id, containment));
}
public void referenceRemoved(int id, boolean containment)
{
List<ChangeInfo> changeInfo = ensureChangeInfos();
changeInfo.add(new ChangeInfo.Reference(ChangeInfo.Reference.Kind.REMOVED, id, containment));
}
public void referenceType(int id, boolean containment)
{
List<ChangeInfo> changeInfo = ensureChangeInfos();
changeInfo.add(new ChangeInfo.Reference(ChangeInfo.Reference.Kind.TYPE, id, containment));
}
@Override
public String toString()
{
return "CHANGE " + id + " " + changeInfos;
}
private List<ChangeInfo> ensureChangeInfos()
{
if (changeInfos == null)
{
changeInfos = new ArrayList<ChangeInfo>();
}
return changeInfos;
}
/**
* @author Eike Stepper
*/
public static abstract class ChangeInfo
{
public abstract void write(ExtendedDataOutputStream out) throws IOException;
/**
* @author Eike Stepper
*/
public static class Attribute extends ChangeInfo
{
private String key;
private String value;
public Attribute(String key, String value)
{
this.key = key;
this.value = value;
}
public Attribute(ExtendedDataInputStream in) throws IOException
{
key = in.readString();
value = in.readString();
}
@Override
public void write(ExtendedDataOutputStream out) throws IOException
{
out.writeString(key);
out.writeString(value);
}
public String getKey()
{
return key;
}
public String getValue()
{
return value;
}
@Override
public String toString()
{
return "SET " + key + "=" + value;
}
}
/**
* @author Eike Stepper
*/
public static class Reference extends ChangeInfo
{
private Kind kind;
private int id;
public Reference(Kind kind, int id, boolean containment)
{
this.kind = kind;
this.id = containment ? -id : id;
}
public Reference(ExtendedDataInputStream in) throws IOException
{
kind = Kind.values()[in.readByte()];
id = in.readInt();
}
@Override
public void write(ExtendedDataOutputStream out) throws IOException
{
out.writeByte(kind.ordinal());
out.writeInt(id);
}
public Kind getKind()
{
return kind;
}
public int getID()
{
return Math.abs(id);
}
public boolean isContainment()
{
return id < 0;
}
@Override
public String toString()
{
return kind.toString() + " " + getID() + "=" + isContainment();
}
/**
* @author Eike Stepper
*/
public static enum Kind
{
ADDED, REMOVED, TYPE
}
}
}
}
/**
* @author Eike Stepper
*/
public static class Remove extends ElementEvent
{
public static final byte TYPE = 4;
private int id;
public Remove(int id)
{
this.id = id;
}
public Remove(ExtendedDataInputStream in) throws IOException
{
id = in.readInt();
}
@Override
public void write(ExtendedDataOutputStream out) throws IOException
{
out.writeInt(id);
}
@Override
public int getType()
{
return TYPE;
}
public int getID()
{
return id;
}
@Override
public String toString()
{
return "REMOVE " + id;
}
}
}