All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.linkedin.data.transform.DataComplexProcessor Maven / Gradle / Ivy

Go to download

Pegasus is a framework for building robust, scalable service architectures using dynamic discovery and simple asychronous type-checked REST + JSON APIs.

The newest version!
/*
   Copyright (c) 2012 LinkedIn Corp.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

/**
 * $id$
 */
package com.linkedin.data.transform;

import com.linkedin.data.DataComplex;
import com.linkedin.data.DataMap;
import com.linkedin.data.message.Message;
import com.linkedin.data.message.MessageList;

/**
 * DataMapProcessor abstracts DataMap processing when it can be described as an
 * object with layout similar to data object it operates on with additional information
 * how data should be modified. Examples of data processing that fit this description are:
 * patch, projections.
 *
 * @author jodzga
 *
 */
public class DataComplexProcessor
{
  public static final String DATA_PROCESSING_FAILED = "data processing failed";

  private final InstructionScheduler         _instructionScheduler;
  private final Interpreter                  _interpreter;
  private final DataMap                      _program;
  private final DataComplex                  _data;
  private static final ImmutableList _rootPath              = ImmutableList.empty();

  /**
   * Creates new DataMapProcessor.
   */
  public DataComplexProcessor(final InstructionScheduler instructionScheduler, final Interpreter interpreter, final DataMap program, final DataComplex data)
  {
    this._instructionScheduler = instructionScheduler;
    this._interpreter = interpreter;
    this._program = program;
    this._data = data;
  }

  /**
   * Constructor which uses default (FILO) InstructionScheduler.
   *
   * @param interpreter the interpreter
   * @param program the program
   * @param data the data
   */
  public DataComplexProcessor(final Interpreter interpreter, final DataMap program, final DataComplex data)
  {
    this(new FILOScheduler(), interpreter, program, data);
  }

  /**
   * Runs data processing and throws {@link DataProcessingException} if there were any errors.
   * 

If Interpreter was created with fast-fail flag, then processing is stopped * immediately after occurrence of first error. Otherwise, if possible, data processing is continued * and all errors are gathered and accessible through DataProcessingException thrown * by this method. * * @param fastFail if true, stop immediately after the first error, * otherwise gather as many errors as possible. * @throws DataProcessingException * @return information messages from the interpreter context. */ public MessageList runDataProcessing(boolean fastFail) throws DataProcessingException { if (_program != null) { InterpreterContext ic = new InterpreterContext(fastFail, _instructionScheduler); // create first instruction and schedule it for execution final Instruction firstInstruction = new Instruction(_program, _data, _rootPath); _instructionScheduler.scheduleInstruction(firstInstruction); // main loop while (_instructionScheduler.hasNext()) { final Instruction next = _instructionScheduler.next(); try { ic.setCurrentInstruction(next); _interpreter.interpret(ic); } catch (FastFailException ff) { //in case of fast fail exception, the behavior is to immediately stop processing, //don't generate child instructions, exception containing details is thrown below throw new DataProcessingException(DATA_PROCESSING_FAILED, ic.getErrorMessages()); } } //check for errors and throw exception if processing failed if (ic.failed()) throw new DataProcessingException(DATA_PROCESSING_FAILED, ic.getErrorMessages()); return ic.getInfoMessages(); } return null; } /** * Same as {@link #runDataProcessing(boolean)}, but returns void. */ public void run(boolean fastFail) throws DataProcessingException { runDataProcessing(fastFail); } }