Generated Java™ operator
The operator spl.utility.JavaOp
can generate Java™ source templates for the specific
invocation of the operator.
The generated templates include generated interfaces specific to
the input and output port schemas. These interfaces include getter
and setter
methods
corresponding to the type and name of each attribute in the port's
schema. These templates are generated by the SPL compiler when the JavaOp invocation
has the generated parameter set to true
.
Start with this example.
stream <int32 id, ustring tag, list<float64> data> CoolStream
= JavaOp(SENSORS)
{
param
generated: true;
className: "com.acme.streams.CoolOperator";
classLibrary: "";
}
CoolOperator
contains the application
logic for the operator. Compiling the application generates two Java™ source files in the directory opt/java/src in
the application directory (assumed here to be /streams/app).
The abstract operator in this case is AbstractCoolOperator
in
the package com.acme.streams
and, thus, its source
file is found in the following location /streams/app/opt/java/src/com/acme/streams/AbstractCoolOperator.java.
This file is generated for each compilation and is not to be changed
by the developer.Now look through the key aspects of the generated abstract operator.
First, the abstract class definition.
package com.acme.streams;
// Required imports from Streams API (only one shown)
import com.ibm.streams.operator.AbstractOperator;
public class AbstractCoolOperator extends AbstractOperator
Then, the input ports.
public interface IPort0 {
public int get_id();
public long[] get_timestamps();
public short[][] get_readings();
public String get_tag();
public Tuple getTuple();
}
// Tuples for port 0 are delivered to the operator via this method.
protected abstract void process0(IPort0 tuple) throws Exception;
IPortN
is created
for each input port as an inner-class of the abstract operator. This
interface includes getters for the tuple attributes that return the
corresponding Java™ type for
the attribute, using a Java™ primitive
where possible. A getTuple
method is provided to
get the generic tuple representation. An abstract processN
method
is defined and it requires that a developer implements the corresponding
concrete class. This class handles the processing of tuples that arrive
on that port. Similarly, a specific interface is created for each
output port, along with methods to support the port.// Interface for output port 0
public interface OPort0 {
public int get_id();
public String get_tag();
public double[] get_data();
public void set_id(int value);
public void set_tag(String value);
public void set_data(double[] value);
public OutputTuple getOutputTuple();
}
// Method to obtain output description for port 0
public StreamingOutput<OPort0> getOutput0();
// Method to submit tuples to port 0.
public boolean submit0(OPort0 tuple) throws Exception { … }
OPortN
is
created as an inner-class of the abstract operator class. This interface
includes getters and setters for the attributes that return the corresponding Java™ type for each attribute, using Java™ primitive types where possible.
A getOutputTuple
method is provided to retrieve the
generic output tuple representation. New instances of the OPortN
interface
are created using the StreamingOutput<OPortN>
interface
available through the generated method getOutputN
.
Tuples can then be submitted using the port specific method submitN
.The
template for the concrete operator class is created only if the source
file does not exist. Here is an example of a generated template, showing
two methods that need to be completed (marked with TODO
) to
provide the required function.
package com.acme.streams;
// Required imports from Streams API (only one shown)
import com.ibm.streams.operator.OperatorContext;
public class CoolOperator extends AbstractCoolOperator {
@Override
public void initialize(OperatorContext context) throws Exception {
super.initialize(context);
// TODO Auto-generated method stub
}
@Override
protected void process0(IPort0 tuple) throws Exception {
// TODO Auto-generated method stub
}
}
package com.acme.streams;
import com.ibm.streams.operator.OperatorContext;
public class CoolOperator extends AbstractCoolOperator {
@Override
public void initialize(OperatorContext context) throws Exception {
super.initialize(context);
}
@Override
protected void process0(IPort0 tuple) throws Exception {
Oport0 outputTuple = getOutput0().newTuple();
outputTuple.set_id(tuple.get_id());
outputTuple.set_tag(tuple.get_tag());
long[] timestamps = tuple.get_timestamps();
short[][] readings = tuple.get_readings();
// calculate data from timestamps & readings
double[] data = …
outputTuple.set_data(data);
submit0(outputTuple);
}
com.ibm.streams.operator.jar
.