blob: db2cfbcdf3493c15b8f6ec12cdacf2d815b302ed [file] [log] [blame]
package org.eclipse.emf.cdo.threedee.common;
import org.eclipse.emf.cdo.threedee.common.ElementEvent.Call.When;
import org.eclipse.emf.cdo.threedee.common.ElementEvent.Change;
import org.eclipse.emf.cdo.threedee.common.descriptors._INIT_;
import org.eclipse.net4j.util.collection.Pair;
import org.eclipse.net4j.util.event.ValueNotifier;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Eike Stepper
*/
public abstract class ElementDescriptor implements Comparable<ElementDescriptor>
{
private static final ThreadLocal<Boolean> INITIALIZING_ELEMENT = new ThreadLocal<Boolean>()
{
@Override
protected Boolean initialValue()
{
return false;
}
};
protected static final Class<ElementDescriptor> FOLDER_TYPE = ElementDescriptor.class;
private static final Color[] COLORS = initColors();
private static int nextColor;
private ValueNotifier<Color> color = new ValueNotifier<Color>(getNextColor());
public ElementDescriptor()
{
}
public abstract Class<?> getElementType();
public boolean isFolder()
{
return getElementType() == FOLDER_TYPE;
}
public final String getName()
{
return getClass().getSimpleName();
}
public String getLabel()
{
return getBaseLabel();
}
protected String getBaseLabel()
{
return strip(getClass().getSimpleName(), "Descriptor");
}
public ValueNotifier<Color> getColor()
{
return color;
}
public String getLabel(Element element)
{
String label = element.getAttributes().get(Element.LABEL_ATTRIBUTE);
if (label == null)
{
label = element.getAttributes().get("_label");
if (label == null)
{
label = element.getAttributes().get(Element.NAME_ATTRIBUTE);
if (label == null)
{
label = element.getAttributes().get(Element.KEY_ATTRIBUTE);
if (label == null)
{
label = element.getAttributes().get(Element.ID_ATTRIBUTE);
if (label == null)
{
return getLabel();
}
}
}
}
}
return getLabel() + " " + label;
}
public ElementDescriptor getSuperDescriptor()
{
String superName = getSuperDescriptorName();
return Registry.INSTANCE.get(superName);
}
protected String getSuperDescriptorName()
{
return getClass().getSuperclass().getSimpleName();
}
public List<ElementDescriptor> getSubDescriptors()
{
return Registry.INSTANCE.getSubDescriptors(getName());
}
public boolean matches(Object object)
{
return getElementType().isInstance(object);
}
public boolean isActive(Object object)
{
return LifecycleUtil.isActive(object);
}
public void initElement(Object object, Element element)
{
try
{
INITIALIZING_ELEMENT.set(true);
doInitElement(object, element);
}
finally
{
INITIALIZING_ELEMENT.set(false);
}
}
protected abstract void doInitElement(Object object, Element element);
public boolean isHomogenous()
{
return true;
}
public ElementEvent.Call createCallEvent(Element sourceElement, Element targetElement, String what, When when)
{
return new ElementEvent.Call(sourceElement, targetElement, what, when);
}
public ElementEvent createTransmitEvent(Element connector)
{
return new ElementEvent.Transmit(connector);
}
public Pair<ElementEvent.Change, Element> createChangeEvent(Element oldElement, Object newObject)
{
return doCreateChangeEvent(oldElement, newObject);
}
protected final Pair<ElementEvent.Change, Element> doCreateChangeEvent(Element oldElement, Object newObject)
{
Element newElement = new Element(oldElement.getID(), oldElement.getDescriptor(), oldElement.getProvider());
initElement(newObject, newElement);
Change event = newElement.compare(oldElement);
if (event == null)
{
return null;
}
return new Pair<Change, Element>(event, newElement);
}
public int compareTo(ElementDescriptor d2)
{
Class<?> t1 = getElementType();
Class<?> t2 = d2.getElementType();
boolean a = t1.isAssignableFrom(t2);
boolean b = t2.isAssignableFrom(t1);
if (a && !b)
{
return 1;
}
if (b && !a)
{
return -1;
}
return t1.getName().compareTo(t2.getName());
}
@Override
public String toString()
{
return getName();
}
public static boolean isInitializingElement()
{
return INITIALIZING_ELEMENT.get();
}
private static String strip(String string, String suffix)
{
if (string.endsWith(suffix))
{
return string.substring(0, string.length() - suffix.length());
}
return string;
}
private static Color[] initColors()
{
List<Color> colors = new ArrayList<Color>();
colors.add(Color.pink);
colors.add(Color.blue);
colors.add(Color.cyan);
colors.add(Color.darkGray);
colors.add(Color.gray);
colors.add(Color.green);
colors.add(Color.lightGray);
colors.add(Color.magenta);
colors.add(Color.red);
colors.add(Color.white);
colors.add(Color.yellow);
colors.add(new Color(20, 93, 20));
colors.add(new Color(200, 50, 50));
colors.add(new Color(100, 98, 77));
colors.add(new Color(200, 20, 200));
colors.add(new Color(0, 100, 100));
colors.add(new Color(0, 200, 200));
colors.add(new Color(100, 0, 100));
colors.add(new Color(200, 0, 200));
colors.add(new Color(100, 100, 0));
colors.add(new Color(200, 200, 0));
colors.add(new Color(255, 100, 100));
colors.add(new Color(255, 200, 200));
colors.add(new Color(100, 255, 100));
colors.add(new Color(200, 255, 200));
colors.add(new Color(100, 100, 225));
colors.add(new Color(200, 200, 255));
colors.add(new Color(100, 255, 255));
colors.add(new Color(200, 255, 255));
colors.add(new Color(255, 255, 100));
colors.add(new Color(255, 255, 200));
colors.add(new Color(255, 100, 255));
colors.add(new Color(255, 200, 255));
return colors.toArray(new Color[colors.size()]);
}
private static Color getNextColor()
{
try
{
nextColor = nextColor % COLORS.length;
return COLORS[nextColor];
}
finally
{
++nextColor;
}
}
/**
* @author Eike Stepper
*/
public static class Registry extends HashMap<String, ElementDescriptor>
{
public static final Registry INSTANCE = new Registry();
private static final long serialVersionUID = 1L;
private List<ElementDescriptor> values;
private List<ElementDescriptor> rootDescriptors;
private Map<String, List<ElementDescriptor>> subDescriptors;
public void register(ElementDescriptor descriptor, Color color, float intensity)
{
float red = color.getRed() * intensity;
float green = color.getGreen() * intensity;
float blue = color.getBlue() * intensity;
Color effective = new Color(Math.round(red), Math.round(green), Math.round(blue));
descriptor.getColor().setValue(effective);
put(descriptor.getName(), descriptor);
}
@Override
public ElementDescriptor put(String key, ElementDescriptor value)
{
values = null;
rootDescriptors = null;
subDescriptors = null;
return super.put(key, value);
}
@Override
public Collection<ElementDescriptor> values()
{
if (values == null)
{
values = new ArrayList<ElementDescriptor>(super.values());
Collections.sort(values);
}
return values;
}
public List<ElementDescriptor> getRootDescriptors()
{
if (rootDescriptors == null)
{
initHierarchy();
}
return rootDescriptors;
}
public List<ElementDescriptor> getSubDescriptors(String name)
{
List<ElementDescriptor> result = subDescriptors.get(name);
if (result == null)
{
return Collections.emptyList();
}
return result;
}
private void initHierarchy()
{
rootDescriptors = new ArrayList<ElementDescriptor>();
subDescriptors = new HashMap<String, List<ElementDescriptor>>();
for (ElementDescriptor descriptor : values())
{
String superName = descriptor.getSuperDescriptorName();
ElementDescriptor superDescriptor = get(superName);
if (superDescriptor != null)
{
List<ElementDescriptor> list = subDescriptors.get(superName);
if (list == null)
{
list = new ArrayList<ElementDescriptor>();
subDescriptors.put(superName, list);
}
list.add(descriptor);
}
else
{
rootDescriptors.add(descriptor);
}
}
}
public ElementDescriptor match(Object object)
{
for (ElementDescriptor descriptor : values())
{
if (descriptor.matches(object))
{
return descriptor;
}
}
return null;
}
static
{
_INIT_.init(INSTANCE);
}
}
}