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 and getNumInputs methods of AdapterHandler.
  • 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 the AdapterHandler.

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.<br/>
   * 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.<br/>
   * 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 passthough 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;
          }
        }
      }
    }
  }

+ Recent posts