SampleJavaManipulator.java
is a working sample
manipulator that you can use as a shell code for writing your own Java
manipulators.
This sample shows you how to use the
com.endeca.edf.adapter.Adapter
interface and its
classes and methods in order to:
Acquire multiple record sources, by using
getRecord
andgetNumInputs
methods ofAdapterHandler
.Specify which properties you want to modify via pass throughs, by using
AdapterConfig
.Enable logging and debugging, by using the
JVM java.util.logging.Logger
class.Prepare records for future processing in the pipeline, by using the
emit
method of theAdapterHandler
.
This Java manipulator looks for a record property specified by the
SourceProp
pass through. If it finds that property,
it creates a new property, specified by the
TargetProp
pass through by copying the value of the
source property into the target. It uses the first arbitrary source value if
multiple values exist. Next, the code emits all records to the next component
in the pipeline, regardless of whether the property for the record was
transformed.
package com.endeca.soleng.javamanipulator; import java.util.logging.Logger; import java.util.logging.Level; import com.endeca.edf.adapter.Adapter; import com.endeca.edf.adapter.AdapterConfig; import com.endeca.edf.adapter.AdapterException; import com.endeca.edf.adapter.AdapterHandler; import com.endeca.edf.adapter.PVal; import com.endeca.edf.adapter.Record; /** * * This is a sample Java Manipulator; you can use this code as a shell for writing your own manipulators. * This manipulator looks for a property specified by the "SourceProp" pass through. If it finds that property it creates a new property, specified by the "TargetProp" pass through, * copying the source's value into the target. * It will use the first arbitrary source value if multiple values exist. * */ public class SampleJavaManipulator implements Adapter { // all Java Manipulators must implement com.endeca.edf.adapter.Adapter // define constants for our passthrough names private static final String PASSTHROUGH_SOURCEPROP = "SourceProp"; private static final String PASSTHROUGH_TARGETPROP = "TargetProp"; // grab a logger from java.util.logging so we can write to the Forge logs private Logger logger = Logger.getLogger(this.getClass().getName()); // because they implement Adapter, all Java Manipulators must have this // execute(AdapterConfig, AdapterHandler) method public void execute(AdapterConfig config, AdapterHandler handler) throws AdapterException { // read passthrough values from the config object; // the config object contains all our configuration. String sourceprop = config.first(PASSTHROUGH_SOURCEPROP); String targetprop = config.first(PASSTHROUGH_TARGETPROP); // validate passthrough values if (sourceprop == null) throw new AdapterException(PASSTHROUGH_SOURCEPROP + " passthrough not specified; aborting"); if (targetprop == null) throw new AdapterException(PASSTHROUGH_TARGETPROP + " passthrough not specified; aborting"); // loop through all input sources of this manipulator for (int inp = 0; inp != handler.getNumInputs(); inp++) { // create this flag for testing in our while loop, below boolean hasMoreRecords = true; long currentRecord = 0; // loop through all of the records for the current input while(hasMoreRecords) { // get the records, one by one, from the current input source. Record rec = handler.getRecord(inp); // when we are out of records, the last record will be null. if (rec != null) { ++currentRecord; String sourcepropValue = null; // placeholder for our source property // each record is a collection of properties. // loop through the properties to find the one we want. // if we are looking for multiple different properties of a single // record, it may be more efficient to stuff them into a Map. for (PVal prop : rec) { if (prop.getName().equals(sourceprop)) { // we found the property we are looking for. Save its value. sourcepropValue = prop.getValue(); break; } } // If we found the sourceprop, copy its // value into another prop, add the new prop to the // record, and write to the Forge log. if (sourcepropValue != null) { rec.add(new PVal(targetprop,sourcepropValue)); if (logger.isLoggable(Level.INFO)) logger.info("Input source: " + inp + "; Record " + currentRecord + ": found " + sourceprop + "=\"" + sourcepropValue + "\", copying to " + targetprop); } // we must emit() each record we want to pass out of this // manipulator into the next downstream component (e.g. PropertyMapper) handler.emit(rec); } else { hasMoreRecords = false; } } } } }