LAE

Welcome to the LAE community!  Please feel free to start a discussion in the discussion tab or join in a conversation.

Discussions

Members

Resources

Events

 View Only
  • 1.  Java Node Input and Output

    Employee
    Posted 07-22-2011 07:19

    Note: This was originally posted by an inactive account. Content was preserved by moving under an admin account.

    Originally posted by: jodycrutchfield

    I have a Java Node that I want to pass all of the input fields plus one new field to the output.

    Here is how I am building my Metadata.

    RecordMetadata metadata = output(0).newMetadata();
    metadata.copyFrom(input(0).metadata());
    metadata.add(new SimpleFieldMetadata("TaskID",java.lang.String.clas s));
    output(0).metadata(metadata);
    openOutput(0);

    I read my input record.
    Record inRec = read(0);

    I try to combine the fields for the output.
    inRec.field("TaskID",taskID);
    write(0,inRec);

    Not sure what I am doing wrong. I can output the inRec by itself or the TaskID by itself, but not both at the same time.

    Thanks,

    Jody


  • 2.  RE: Java Node Input and Output

    Employee
    Posted 07-22-2011 09:36

    Note: This was originally posted by an inactive account. Content was preserved by moving under an admin account.

    Originally posted by: jodycrutchfield

    Found this in the javadoc about the metadata.add method.

    "This method can only be called when the RecordMetadata has not been locked. This means that this method should not be called after this metadata has been written, assigned to a RecordOutput, or if this metadata was obtained from an existing RecordInput for which records exist. "

    Here is how I built the output

    Class<?> ft = null;
    RecordMetadata metadata = output(0).newMetadata();
    RecordMetadata inRecMeta = input(0).metadata();
    for (int i=0;i<inRecMeta.numFields();i++)
    {
    FieldMetadata fmd = input(0).metadata().field(i);
    String fn = fmd.name();
    ft = fmd.type();
    metadata.add(new SimpleFieldMetadata(fn, ft));
    logger().error("name is " + fn + " class is " + ft);
    }
    metadata.add(new SimpleFieldMetadata("TaskID", Long.class));
    output(0).metadata(metadata);
    openOutput(0);


    Here is how I write the output

    Record outRec = output(0).metadata().newRecord();
    for (int i=0;i<inRec.numFields();i++)
    {
    outRec.field(i, inRec.field(i));
    }
    outRec.field(outRec.metadata().find("TaskID"), tid);
    write(0, outRec);


  • 3.  RE: Java Node Input and Output

    Employee
    Posted 07-25-2011 11:46

    Note: This was originally posted by an inactive account. Content was preserved by moving under an admin account.

    Originally posted by: rpigneri

    Dear Jody,

    Your approach seems like an awful lot of work for simply adding a field to an input record. Perhaps there are some other smarts that are being baked into this node that aren't in the original post? Here is how I did it using 4.5.2:


    	public void setup() throws NodeFailedException
    	{
    		RecordMetadata metadata = output(0).newMetadata();
    		metadata.copyFrom(input(0).metadata());
    		metadata.add(new SimpleFieldMetadata("TaskID",java.lang.String.class));
    		output(0).metadata(metadata);
    		openOutput(0);
    	}
    	
    	public void processAll() throws NodeFailedException
    	{
    		Record outputRecord = output(0).metadata().newRecord();
    		String taskID = "10";
    		Record inputRecord = read(0);
    		int taskIdIndex = output(0).metadata().find("TaskID");
    		while (inputRecord != RecordInput.EOF)
    		{
    			outputRecord.copyFrom(inputRecord);
    			outputRecord.field(taskIdIndex,taskID);
    			write(0,outputRecord);
    			inputRecord = read(0);
    		}
    	}
    What version of LAE are you using?

    Rocco


  • 4.  RE: Java Node Input and Output

    Employee
    Posted 07-26-2011 08:35

    Note: This was originally posted by an inactive account. Content was preserved by moving under an admin account.

    Originally posted by: jodycrutchfield

    Updated:
    I tried these changes and it worked just fine. I had a combination of things that I was missing.

    Previous note:

    Thanks Rocco, I will try your code.

    I might have been causing a problem since I was not getting the index for the TaskID field. I was trying to assign by name.

    I am using version 4.5.1.

    Jody


  • 5.  RE: Java Node Input and Output

    Employee
    Posted 07-26-2011 10:48

    Note: This was originally posted by an inactive account. Content was preserved by moving under an admin account.

    Originally posted by: Tim Meagher

    Hey,


    So further to the previous posts....
    The main problem was the use of the following:

    Record inRec = read(0);
    ...
    inRec.field("TaskID",taskID);
    write(0,inRec);
    The inRec Record will have it's metadata based on the metadata of the input pin from which it is read. In this case, input 0.
    However, the output pin 0 has a different metadata set.
    This is based on the input metadata, but contains the additional field "TaskId".

    The Record inRec will have it's metadata set such that there is no field "TaskId". Therefore, attempting to to set the field "TaskId" will result in an error.

    The correct way, as Rocco rightly points out is to construct a new output Record based on the metadata of the output pin you are writing to, using:

    Record outRec = output(outputIndex).newMetadata();
    As a final note, the code:
    outputRecord.copyFrom(inputRecord);
    Is not the most efficient way to map all of the fields on the input record to the output record. This is because there is no mapping provided to the outputRecord for it to know which fields in the inputRecord should be placed on which output fields. Therefore, when populating each output record, it has to obtain all of the metadata from the inputRecord, and locate (i.e. do a textual search on the field name of each field in the output metadata) where that should be placed on the outputRecord.

    The more efficient way to do this would be to do the following:

    	private int[] m_mapping;
    
    	public void setup() throws NodeFailedException
    	{
    		RecordMetadata metadata = output(0).newMetadata();
    		metadata.copyFrom(input(0).metadata());
    		metadata.add(new SimpleFieldMetadata("TaskID",java.lang.String.class));
    		output(0).metadata(metadata);
    		
    		m_mapping = metadata.mapping(input(0).metadata());
    
    		openOutput(0);
    	}
    	
    	public void processAll() throws NodeFailedException
    	{
    		Record outputRecord = output(0).metadata().newRecord();
    		String taskID = "10";
    		Record inputRecord = read(0);
    		int taskIdIndex = output(0).metadata().find("TaskID");
    		while (inputRecord != RecordInput.EOF)
    		{
    			outputRecord.copyFrom(inputRecord, m_mapping);
    			outputRecord.field(taskIdIndex,taskID);
    			write(0,outputRecord);
    			inputRecord = read(0);
    		}
    	}
    Regards,
    Tim.