package nl.ipo.cds.etl.operations; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.annotation.PostConstruct; import javax.inject.Inject; import nl.ipo.cds.attributemapping.operations.Operation; import nl.ipo.cds.attributemapping.operations.OperationInput; import nl.ipo.cds.attributemapping.operations.OperationType; import nl.ipo.cds.attributemapping.operations.discover.OperationDiscoverer; import nl.ipo.cds.attributemapping.operations.discover.annotation.AnnotationOperationType; import nl.ipo.cds.etl.operations.input.StringConstantInput; import nl.ipo.cds.etl.operations.input.StringInput; import nl.ipo.cds.etl.operations.output.StringArrayOutput; import nl.ipo.cds.etl.operations.output.StringOutput; import nl.ipo.cds.etl.operations.transform.ConditionalTransform; import nl.ipo.cds.etl.operations.transform.MakeInspireIdTransform; import nl.ipo.cds.etl.operations.transform.MakeStringArrayTransform; import nl.ipo.cds.etl.operations.transform.SplitStringTransform; import nl.ipo.cds.etl.operations.transform.ToStringTransform; public class OperationFactory { @Inject private OperationDiscoverer discoverer; private Collection<OperationType> operationTypes; // Operation types: private @Inject StringConstantInput stringConstantInput; private @Inject ConditionalTransform conditionalTransform; private @Inject SplitStringTransform splitStringTransform; private @Inject StringOutput stringOutput; private @Inject StringArrayOutput stringArrayOutput; private @Inject StringInput stringInput; private @Inject ToStringTransform convertToString; private @Inject MakeInspireIdTransform makeInspireIdTransform; private @Inject MakeStringArrayTransform makeStringArrayTransform; @PostConstruct public void discoverOperations () { this.operationTypes = discoverer.getOperationTypes (); } public Operation stringInput (final String attributeName) { final StringInput.Settings settings = new StringInput.Settings (); settings.setAttributeName (attributeName); return op (stringInput, settings); } public Operation stringConstant (final String value) { final StringConstantInput.Settings settings = new StringConstantInput.Settings (); settings.setValue (value); return op (stringConstantInput, settings); } public Operation conditional (final Operation elseBranch, final ConditionalInput ... inputs) { final ConditionalTransform.Settings settings = new ConditionalTransform.Settings (); final Operation[] inputOperations = new Operation[inputs.length + 1]; final List<ConditionalTransform.Condition> conditions = new ArrayList<ConditionalTransform.Condition > (inputs.length); for (int i = 0; i < inputs.length; ++ i) { inputOperations[i] = inputs[i].input; conditions.add (inputs[i].condition); } settings.setConditions (conditions); inputOperations[inputs.length] = elseBranch; return op (conditionalTransform, settings, inputOperations); } public ConditionalInput conditionalInput (final Operation input, final String attribute, final ConditionalTransform.Operation operation, final String ... values) { return new ConditionalInput (input, condition (attribute, operation, values)); } public ConditionalTransform.Condition condition (final String attribute, final ConditionalTransform.Operation operation, final String ... values) { final ConditionalTransform.Condition condition = new ConditionalTransform.Condition (); condition.setAttribute (attribute); condition.setOperation (operation); condition.setValues (values); return condition; } public Operation split (final Operation input, final String boundary) { return split (input, boundary, true, false); } public Operation split (final Operation input, final String boundary, final boolean trimWhitespace) { return split (input, boundary, trimWhitespace, false); } public Operation split (final Operation input, final String boundary, final boolean trimWhitespace, final boolean ignoreEmpty) { final SplitStringTransform.Settings settings = new SplitStringTransform.Settings (); settings.setBoundary (boundary); settings.setTrimWhitespace (trimWhitespace); settings.setIgnoreEmptyItems (ignoreEmpty); return op (splitStringTransform, settings, input); } public Operation stringOut (final Operation input) { return op (stringOutput, null, input); } public Operation stringArrayOut (final Operation input) { return op (stringArrayOutput, null, input); } public Operation convertToString (final Operation input) { return op (convertToString, null, input); } public Operation makeInspireId (final Operation countryCode, final Operation bronhouderCode, final Operation uuid, final Operation datasetCode) { return op (makeInspireIdTransform, null, countryCode, bronhouderCode, uuid, datasetCode); } public Operation makeStringArray (final Operation ... inputs) { return op (makeStringArrayTransform, null, inputs); } public Operation op (final Object bean, final Object operationProperties, final Operation ... inputs) { final OperationType operationType = findOperationTypeForBean (bean); if (operationType == null) { throw new IllegalArgumentException ("Invalid bean"); } return new Operation() { @Override public OperationType getOperationType() { return operationType; } @Override public Object getOperationProperties() { return operationProperties; } @Override public List<OperationInput> getInputs() { final List<OperationInput> result = new ArrayList<OperationInput> (); for (final Operation operation: inputs) { result.add (new OperationInput() { @Override public Operation getOperation() { return operation; } }); } return result; } }; } private OperationType findOperationTypeForBean (final Object bean) { for (final OperationType ot: operationTypes) { if (!(ot instanceof AnnotationOperationType)) { continue; } if (((AnnotationOperationType)ot).getBean () == bean) { return ot; } } return null; } public static class ConditionalInput { final Operation input; final ConditionalTransform.Condition condition; public ConditionalInput (final Operation input, final ConditionalTransform.Condition condition) { this.input = input; this.condition = condition; } } }