public Object clone() { MappingInputMeta retval = (MappingInputMeta) super.clone(); int nrfields = fieldName.length; retval.allocate(nrfields); for (int i = 0; i < nrfields; i++) { retval.fieldName[i] = fieldName[i]; retval.fieldType[i] = fieldType[i]; fieldLength[i] = fieldLength[i]; fieldPrecision[i] = fieldPrecision[i]; } return retval; }
public void getFields( RowMetaInterface row, String origin, RowMetaInterface info[], StepMeta nextStep, VariableSpace space) throws KettleStepException { // First load some interesting data... // Then see which fields get added to the row. // TransMeta mappingTransMeta = null; try { mappingTransMeta = loadMappingMeta(this, repository, space); } catch (KettleException e) { throw new KettleStepException( BaseMessages.getString(PKG, "MappingMeta.Exception.UnableToLoadMappingTransformation"), e); } // The field structure may depend on the input parameters as well (think of parameter // replacements in MDX queries for instance) if (mappingParameters != null) { // See if we need to pass all variables from the parent or not... // if (mappingParameters.isInheritingAllVariables()) { mappingTransMeta.copyVariablesFrom(space); } // Just set the variables in the transformation statically. // This just means: set a number of variables or parameter values: // List<String> subParams = Arrays.asList(mappingTransMeta.listParameters()); for (int i = 0; i < mappingParameters.getVariable().length; i++) { String name = mappingParameters.getVariable()[i]; String value = space.environmentSubstitute(mappingParameters.getInputField()[i]); if (!Const.isEmpty(name) && !Const.isEmpty(value)) { if (subParams.contains(name)) { try { mappingTransMeta.setParameterValue(name, value); } catch (UnknownParamException e) { // this is explicitly checked for up front } } mappingTransMeta.setVariable(name, value); } } } // Keep track of all the fields that need renaming... // List<MappingValueRename> inputRenameList = new ArrayList<MappingValueRename>(); /* * Before we ask the mapping outputs anything, we should teach the mapping * input steps in the sub-transformation about the data coming in... */ for (MappingIODefinition definition : inputMappings) { RowMetaInterface inputRowMeta; if (definition.isMainDataPath() || Const.isEmpty(definition.getInputStepname())) { // The row metadata, what we pass to the mapping input step // definition.getOutputStep(), is "row" // However, we do need to re-map some fields... // inputRowMeta = row.clone(); if (!inputRowMeta.isEmpty()) { for (MappingValueRename valueRename : definition.getValueRenames()) { ValueMetaInterface valueMeta = inputRowMeta.searchValueMeta(valueRename.getSourceValueName()); if (valueMeta == null) { throw new KettleStepException( BaseMessages.getString( PKG, "MappingMeta.Exception.UnableToFindField", valueRename.getSourceValueName())); } valueMeta.setName(valueRename.getTargetValueName()); } } } else { // The row metadata that goes to the info mapping input comes from the // specified step // In fact, it's one of the info steps that is going to contain this // information... // String[] infoSteps = getInfoSteps(); int infoStepIndex = Const.indexOfString(definition.getInputStepname(), infoSteps); if (infoStepIndex < 0) { throw new KettleStepException( BaseMessages.getString( PKG, "MappingMeta.Exception.UnableToFindMetadataInfo", definition.getInputStepname())); } if (info[infoStepIndex] != null) { inputRowMeta = info[infoStepIndex].clone(); } else { inputRowMeta = null; } } // What is this mapping input step? // StepMeta mappingInputStep = mappingTransMeta.findMappingInputStep(definition.getOutputStepname()); // We're certain it's a MappingInput step... // MappingInputMeta mappingInputMeta = (MappingInputMeta) mappingInputStep.getStepMetaInterface(); // Inform the mapping input step about what it's going to receive... // mappingInputMeta.setInputRowMeta(inputRowMeta); // What values are we changing names for? // mappingInputMeta.setValueRenames(definition.getValueRenames()); // Keep a list of the input rename values that need to be changed back at // the output // if (definition.isRenamingOnOutput()) Mapping.addInputRenames(inputRenameList, definition.getValueRenames()); } // All the mapping steps now know what they will be receiving. // That also means that the sub-transformation / mapping has everything it // needs. // So that means that the MappingOutput steps know exactly what the output // is going to be. // That could basically be anything. // It also could have absolutely no resemblance to what came in on the // input. // The relative old approach is therefore no longer suited. // // OK, but what we *can* do is have the MappingOutput step rename the // appropriate fields. // The mapping step will tell this step how it's done. // // Let's look for the mapping output step that is relevant for this actual // call... // MappingIODefinition mappingOutputDefinition = null; if (nextStep == null) { // This is the main step we read from... // Look up the main step to write to. // This is the output mapping definition with "main path" enabled. // for (MappingIODefinition definition : outputMappings) { if (definition.isMainDataPath() || Const.isEmpty(definition.getOutputStepname())) { // This is the definition to use... // mappingOutputDefinition = definition; } } } else { // Is there an output mapping definition for this step? // If so, we can look up the Mapping output step to see what has changed. // for (MappingIODefinition definition : outputMappings) { if (nextStep.getName().equals(definition.getOutputStepname()) || definition.isMainDataPath() || Const.isEmpty(definition.getOutputStepname())) { mappingOutputDefinition = definition; } } } if (mappingOutputDefinition == null) { throw new KettleStepException( BaseMessages.getString(PKG, "MappingMeta.Exception.UnableToFindMappingDefinition")); } // OK, now find the mapping output step in the mapping... // This method in TransMeta takes into account a number of things, such as // the step not specified, etc. // The method never returns null but throws an exception. // StepMeta mappingOutputStep = mappingTransMeta.findMappingOutputStep(mappingOutputDefinition.getInputStepname()); // We know it's a mapping output step... MappingOutputMeta mappingOutputMeta = (MappingOutputMeta) mappingOutputStep.getStepMetaInterface(); // Change a few columns. mappingOutputMeta.setOutputValueRenames(mappingOutputDefinition.getValueRenames()); // Perhaps we need to change a few input columns back to the original? // mappingOutputMeta.setInputValueRenames(inputRenameList); // Now we know wat's going to come out of there... // This is going to be the full row, including all the remapping, etc. // RowMetaInterface mappingOutputRowMeta = mappingTransMeta.getStepFields(mappingOutputStep); row.clear(); row.addRowMeta(mappingOutputRowMeta); }