Commit cf5898cb authored by Nico Mack's avatar Nico Mack

Started generalization of Scripting

parent 6a667a65
......@@ -43,6 +43,7 @@ DEFINING_SHAPE_NODE=definingShape
DELAY_NODE=delay
DESCRIPTION_NODE=description
DESELECTED_ELEMENT=deselected
DISPLAY_NAME_NODE=displayName
DISPLAY_TIME_NODE=displayTime
DISTANCE_NODE=distance
DRAGGABLE_NODE=draggable
......
......@@ -25,7 +25,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.util.regex.Pattern;
/**
* @author mack
......@@ -47,8 +46,6 @@ public class Script implements Cloneable {
// * Constants *
// ***************************************************************************
private static final Pattern PROPERTY_PATTERN = Pattern.compile("([a-z0-9_]+)(\\.([a-z0-9_]+))?", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
private static final Logger LOGGER = LoggerFactory.getLogger(Script.class.getName());
// ---------------------------------------------------------------------------
......
/**
* Copyright Luxembourg Institute of Science and Technology, 2018. All rights reserved.
*
* This file is part of TULIP.
*
* TULIP is free software: you can redistribute it and/or modify it under the terms of the GNU
* Lesser General Public License as published by the Free Software Foundation, version 3 of the
* License.
*
* TULIP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with TULIP. If
* not, see <http://www.gnu.org/licenses/lgpl-3.0.html>.
*/
package lu.list.itis.dkd.tui.scripting;
import com.jgoodies.common.base.Preconditions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author mack
* @since [major].[minor]
* @version [major].[minor].[micro]
*/
// ***************************************************************************
// * Constants *
// ***************************************************************************
public class ScriptUtils {
// ***************************************************************************
// * Constants *
// ***************************************************************************
private static final String SETTER_PREFIX = "set"; //$NON-NLS-1$
protected static final Pattern CAMELCASE_PATTERN = Pattern.compile("^([a-z]{1})([a-z0-9_]*)", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
protected static final Pattern PROPERTY_PATTERN = Pattern.compile("([a-z0-9_]+)(\\\\.([a-z0-9_]+))?", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
private static final Logger LOGGER = LoggerFactory.getLogger(ScriptUtils.class.getName());
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s)
// ***************************************************************************
// ---------------------------------------------------------------------------
private ScriptUtils() {
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Primitive(s)
// ***************************************************************************
private static String camelCase(String lowercase) {
Matcher camelCase = CAMELCASE_PATTERN.matcher(lowercase);
if (camelCase.matches()) {
StringBuilder camelCased = new StringBuilder();
camelCased.append(camelCase.group(1).toUpperCase());
camelCased.append(camelCase.group(2));
return camelCased.toString();
}
LOGGER.warn("Failed to camelcase {}! Returnin as is!", lowercase); //$NON-NLS-1$
return lowercase;
}
// ---------------------------------------------------------------------------
private static String getSetterName(String property) {
StringBuilder setterName = new StringBuilder(SETTER_PREFIX);
setterName.append(camelCase(property));
return setterName.toString();
}
// ---------------------------------------------------------------------------
private static List<String> decompose(String property) {
List<String> propertyTree = new ArrayList<>();
Matcher propertyMatcher = PROPERTY_PATTERN.matcher(property);
while (propertyMatcher.find()) {
propertyTree.add(propertyMatcher.group(0));
}
return propertyTree;
}
// ---------------------------------------------------------------------------
private static Field findField(Class<?> candidate, String fieldName) {
Field field = null;
for (Class<?> clazz = candidate; clazz != null && field == null; clazz = clazz.getSuperclass()) {
try {
field = clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException | SecurityException e) {
// Can be ignored here.
}
}
return field;
}
// ---------------------------------------------------------------------------
private static Method findSetter(Class<?> candidate, String setterName, Class<?> argumentType) {
Method setter = null;
Class<?>[] argumentTypes = {argumentType};
for (Class<?> clazz = candidate; clazz != null && setter == null; clazz = clazz.getSuperclass()) {
try {
setter = clazz.getDeclaredMethod(setterName, argumentTypes);
} catch (NoSuchMethodException | SecurityException e) {
// Can be ignored here.
}
}
return setter;
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body
// ***************************************************************************
// ---------------------------------------------------------------------------
/**
* @param object
* @param property
* @return
*/
// ---------------------------------------------------------------------------
public static ScriptableProperty findProperty(Object root, String property, Class<?> propertyType) {
Preconditions.checkArgument(root != null, "Object to find property of CAN'T be NULL!"); //$NON-NLS-1$
Preconditions.checkArgument(property != null && (!property.isEmpty()), "Property to look for CAN'T be NULL or empty!"); //$NON-NLS-1$
Class<?> candidate = root.getClass();
ScriptableProperty scriptable = null;
List<String> propertyTree = decompose(property);
for (String declaration : propertyTree) {
Method setter = findSetter(candidate, declaration, propertyType);
scriptable = new ScriptableProperty(root, setter);
if (setter == null) {
Field field = findField(candidate, declaration);
scriptable = new ScriptableProperty(root, field);
}
}
if (scriptable == null) {
LOGGER.error("No such property {} in class {}!", property, root.getClass().getSimpleName()); //$NON-NLS-1$
}
return scriptable;
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * End of Class
// ***************************************************************************
// ---------------------------------------------------------------------------
}
/**
* Copyright Luxembourg Institute of Science and Technology, 2018. All rights reserved.
*
* This file is part of TULIP.
*
* TULIP is free software: you can redistribute it and/or modify it under the terms of the GNU
* Lesser General Public License as published by the Free Software Foundation, version 3 of the
* License.
*
* TULIP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with TULIP. If
* not, see <http://www.gnu.org/licenses/lgpl-3.0.html>.
*/
package lu.list.itis.dkd.tui.scripting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @author mack
* @since [major].[minor]
* @version [major].[minor].[micro]
*/
// ***************************************************************************
// * Class Definition and Members *
// ***************************************************************************
public class ScriptableProperty {
private Object object;
private Field field;
private Method setter;
// ***************************************************************************
// * Constants *
// ***************************************************************************
private static final Logger LOGGER = LoggerFactory.getLogger(ScriptableProperty.class.getName());
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s) *
// ***************************************************************************
// ---------------------------------------------------------------------------
/**
* @param object
* @param field
*/
// ---------------------------------------------------------------------------
public ScriptableProperty(Object object, Field field) {
this.object = object;
this.field = field;
}
// ---------------------------------------------------------------------------
/**
* @param object
* @param method
*/
// ---------------------------------------------------------------------------
public ScriptableProperty(Object object, Method method) {
this.object = object;
this.setter = method;
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Primitive(s) *
// ***************************************************************************
// ---------------------------------------------------------------------------
private boolean setFieldTo(Object value) {
boolean success = false;
try {
field.set(object, value);
success = true;
} catch (IllegalArgumentException | IllegalAccessException e) {
LOGGER.error("Failed to set property {} of object {} to value {}!", field.getName(), object.getClass().getName(), value, e); //$NON-NLS-1$
}
return success;
}
// ---------------------------------------------------------------------------
private boolean callSetterWith(Object value) {
boolean success = false;
try {
setter.invoke(this, value);
success = true;
} catch (Exception e) {
LOGGER.error("Failed to call setter {} of object {} with value {}!", setter.getName(), object.getClass().getName(), value, e); //$NON-NLS-1$
}
return success;
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s) *
// ***************************************************************************
// ---------------------------------------------------------------------------
public boolean set(Object value) {
boolean success = false;
if (this.setter != null) {
success = this.callSetterWith(value);
} else {
success = this.setFieldTo(value);
}
return success;
}
// ---------------------------------------------------------------------------
}
......@@ -23,66 +23,102 @@ import java.awt.Color;
* @since [major].[minor]
* @version [major].[minor].[micro]
*/
// ***************************************************************************
// * Class Definition and Members *
// ***************************************************************************
public class ColorPair {
private Color firstColor;
private Color secondColor;
private boolean switched;
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s) *
// ***************************************************************************
// ---------------------------------------------------------------------------
/**
* @param firstColor
* @param secondColor
*/
// ---------------------------------------------------------------------------
public ColorPair(Color firstColor, Color secondColor) {
this.firstColor = firstColor;
this.secondColor = secondColor;
this.switched = false;
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body *
// ***************************************************************************
// ---------------------------------------------------------------------------
/**
* @return
*/
// ---------------------------------------------------------------------------
public Color getFirstColor() {
return firstColor;
}
// ---------------------------------------------------------------------------
/**
* @param color
*/
// ---------------------------------------------------------------------------
public void setFirstColor(Color color) {
this.firstColor = color;
}
// ---------------------------------------------------------------------------
/**
* @return
*/
// ---------------------------------------------------------------------------
public Color getSecondColor() {
return secondColor;
}
// ---------------------------------------------------------------------------
/**
* @param color
*/
// ---------------------------------------------------------------------------
public void setSecondColor(Color color) {
this.secondColor = color;
}
// ---------------------------------------------------------------------------
/**
* @return
*/
// ---------------------------------------------------------------------------
public boolean isSwitched() {
return switched;
}
// ---------------------------------------------------------------------------
/**
* @param switchIt
*/
// ---------------------------------------------------------------------------
public void setSwitched(boolean switchIt) {
this.switched = switchIt;
}
// ---------------------------------------------------------------------------
/**
* @return
*/
// ---------------------------------------------------------------------------
public Color getColor() {
return (switched) ? firstColor : secondColor;
}
......
......@@ -78,6 +78,7 @@ public class Externalization extends NLS {
public static String DELAY_NODE;
public static String DESCRIPTION_NODE;
public static String DESELECTED_ELEMENT;
public static String DISPLAY_NAME_NODE;
public static String DISPLAY_TIME_NODE;
public static String DISTANCE_NODE;
public static String DRAGGABLE_NODE;
......
......@@ -253,25 +253,6 @@ public class Point extends Float implements Comparable<Point>, KdComparator<Poin
this.y = (float) BootstrappingUtils.getContentAsDouble(rootNode, Externalization.Y_NODE, BootstrappingUtils.OPTIONAL, 0.0, context);
this.angle = (float) BootstrappingUtils.getContentAsRadians(rootNode, Externalization.Z_NODE, BootstrappingUtils.OPTIONAL, 0.0, context);
this.state = CoordinateStateBootstrapper.getCoordinateState(rootNode, this, context, callback);
//
//
// if (rootNode.getChild(Externalization.STATE_NODE) != null) {
// try {
// Class<?> stateClass = Class.forName(Point.class.getPackage().getName() + "." +
// rootNode.getChildText(Externalization.STATE_NODE)); //$NON-NLS-1$
// Constructor<?> stateConstructor = stateClass.getConstructor(new Class[] {Point.class,
// java.lang.Float.TYPE, java.lang.Float.TYPE});
// this.state = (CoordinateState) stateConstructor.newInstance(new Object[] {this, x, y});
// } catch (ClassNotFoundException | NoSuchMethodException | SecurityException |
// InstantiationException | IllegalAccessException | IllegalArgumentException |
// InvocationTargetException e) {
// throw new BuildException("The state of the point cannot be resolved for " +
// rootNode.getChildText(Externalization.STATE_NODE), e); //$NON-NLS-1$
// }
// } else {
// state = new CameraCoordinates(this, x, y);
// }
rotationDirection = (float) BootstrappingUtils.getContentAsDouble(rootNode, Externalization.ROTATION_DIRECTION_NODE, BootstrappingUtils.OPTIONAL, 0.0, context);
}
......
......@@ -23,7 +23,9 @@ package lu.list.itis.dkd.tui.widget.corona;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.scripting.Script;
import lu.list.itis.dkd.tui.scripting.ScriptUtils;
import lu.list.itis.dkd.tui.scripting.Scriptable;
import lu.list.itis.dkd.tui.scripting.ScriptableProperty;
import lu.list.itis.dkd.tui.utility.Point;
import lu.list.itis.dkd.tui.utility.PolarCoordinateHelper;
import lu.list.itis.dkd.tui.utility.ScreenCoordinates;
......
......@@ -214,7 +214,6 @@ public abstract class SelectableCorona extends FadingCorona implements Selectabl
return this.condition;
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * End of Class
......
......@@ -92,8 +92,11 @@ public abstract class CoronaBuilder<B extends CoronaBuilder<B>> {
/** Field holding the initial rotation value in radians. Default: 0; */
public double initialRotation = 0;
/** */
public List<Script> scripts = null;
/**
* Constructor setting the centre of the corona.
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment