Start page
Start page

Start page / Plug-In Development / Universal Extensions / Input Components / Value Processing / Value Engineer

Value Engineer

The input component's value engineer class manages conversion to and from a persistence format such that an input component may store and retrieve data. Specifically, this means the class converts objects of the component value type used by SiteArchitect and ContentCreator gadget implementations to and from a node list structure containing textual data and attributes which may be stored easily in XML form by FirstSpirit.

Implementing a Value Engineer

Interface: de.espirit.firstspirit.client.access.editor.ValueEngineer
Developer API documentation: ValueEngineer<T>

A value engineer class implements the Developer API interface ValueEngineer<T>, where T matches the component value type used by SiteArchitect and ContentCreator gadget implementations.

The value engineer code example listed further down on this page is parameterized with the class Point, which represents a point in a two-dimensional coordinate system and would be used as the working value type by the gadget classes the value engineer class is associated with:

public class Point {

private Integer _x;
private Integer _y;

public Point(@NotNull final Integer x, @NotNull final Integer y) {
_x = x;
_y = y;
}

@NotNull
public Integer getX() {
return _x;
}

@NotNull
public Integer getY() {
return _y;
}

}

Assuming the SiteArchitect and ContentCreator gadget classes operate on objects of type Point, the ValueEngineer implementation might implement the following functionality:

public class PointValueEngineer implements ValueEngineer<Point> {

private final ValueEngineerContext<GomPoint> _context;

private final Map<ValueEngineerAspectType<?>, Object> _aspects =
new HashMap<ValueEngineerAspectType<?>, Object>();

public PointValueEngineer(@NotNull final ValueEngineerContext<GomPoint> context) {
// This is a good place to register this value engineer class' aspects, e.g. by
// adding them to the map object "_aspects":
_aspects.put(DifferenceComputing.type, new AspectDifferenceComputing());

// Also, let's keep the context object in a private field in case it's needed later.
_context = context;
}

// Generate a list of text-based nodes based on a provided Point object.
// (Working value -> Persistence value)
@NotNull
@Override
public List<Node> write(@Nullable final Point value) {
if (value != null) {
final List<Node> nodes = new ArrayList<Node>();

final Node nodeX = Node.create('x', String.valueOf(value.getX()));
nodes.add(nodeX);

final Node nodeY = Node.create('y', String.valueOf(value.getY()));
nodes.add(nodeY);

return nodes;
}

// Since the parameter "value" was null, there's nothing to store...
return Collections.emptyList();
}

// Generate a Point object from a list of text-based nodes.
// (Persistence value -> Working value)
@Nullable
@Override
public Point read(@NotNull final List<Node> nodes) {
String x;
String y;

// Traverse nodes. Complying with the activity in read(...), we're assuming the
// node list (parameter "nodes") is a simple list and no node contains further nodes.
for (final Node node : nodes) {
if ("x".equals(node.getName())) {
x = node.getText();
} else if ("y".equals(node.getName())) {
y = node.getText();
}
}

// Attempt to generate a valid Point object from the data we retrieved above and return it.
if (x != null && !x.isEmpty() && y != null && !y.isEmpty()) {
try {
final Point pointFromNodes = new Point(Integer.valueOf(x), Integer.valueOf(y));
return pointFromNodes;
} catch (final NumberFormatException e) {
// The strings we retrieved from nodes don't represent integers.
// Do nothing. We'll return null at the end of this method.
}
}

// We couldn't generate a valid Point object. Return null.
return null;
}

// Produce an empty Point object. Since the class Point does not allow uninitialized fields,
// this method simply returns null.
@Nullable
@Override
public Point getEmpty() {
return null;
}

// Indicate whether the provided "value" is empty (here: null).
@Override
public boolean isEmpty(@Nullable final Point value) {
return value == null;
}

// Instantiate a copy of the provided "value" and return the copy (or null, if "value" is null).
@Nullable
@Override
public Point copy(@Nullalbe final Point value) {
if (value != null) {
final Point copiedPoint = new Point(value.getX(), value.getY());
return copiedPoint;
}
return null;
}

// If the ValueEngineer implementation supports a specific aspect
@Nullable
@Override
public <A> A getAspect(@NotNull final ValueEngineerAspectType<A> aspect) {
return aspect.cast(_aspects.get(aspect));
}

// Implementation of the aspect DifferenceComputing. This is only included here as the
// value engineer class' constructor (see above) refers to this aspect.
public static class AspectDifferenceComputing implements DifferenceComputing<Point> {
// Aspect implementation here...
}

}

© 2005 - 2015 e-Spirit AG | All rights reserved. | Last change: 2014-12-08