@Override
  public void emitTuples() {
    try {
      Scan scan = nextScan();
      if (scan == null) return;

      ResultScanner resultScanner = store.getTable().getScanner(scan);

      while (true) {
        Result result = resultScanner.next();
        if (result == null) break;

        String readRow = Bytes.toString(result.getRow());
        if (readRow.equals(lastReadRow)) continue;

        Object instance = pojoType.newInstance();
        rowSetter.set(instance, readRow);

        List<Cell> cells = result.listCells();

        for (Cell cell : cells) {
          String columnName = Bytes.toString(CellUtil.cloneQualifier(cell));
          byte[] value = CellUtil.cloneValue(cell);
          fieldValueGenerator.setColumnValue(instance, columnName, value, valueConverter);
        }

        outputPort.emit(instance);
        lastReadRow = readRow;
      }

    } catch (Exception e) {
      throw new RuntimeException(e.getMessage());
    }
  }
 @Override
 public void teardown() {
   try {
     store.disconnect();
   } catch (IOException ex) {
     throw new RuntimeException(ex);
   }
 }
 @Override
 public void setup(OperatorContext context) {
   try {
     store.connect();
     pojoType = Class.forName(pojoTypeName);
     pojoType.newInstance(); // try create new instance to verify the class.
     rowSetter = PojoUtils.createSetter(pojoType, tableInfo.getRowOrIdExpression(), String.class);
     fieldValueGenerator =
         FieldValueGenerator.getFieldValueGenerator(pojoType, tableInfo.getFieldsInfo());
     valueConverter = new BytesValueConverter();
   } catch (Exception ex) {
     throw new RuntimeException(ex);
   }
 }