| /******************************************************************************* |
| * Copyright (c) 2008, 2013 Empolis Information Management GmbH and brox IT Solutions GmbH. All rights reserved. This |
| * program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which |
| * accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: Andreas Weber (Empolis Information Management GmbH) - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.smila.jdbc; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| |
| import org.eclipse.smila.datamodel.Any; |
| import org.eclipse.smila.datamodel.AnyMap; |
| import org.eclipse.smila.datamodel.Value; |
| import org.eclipse.smila.processing.Pipelet; |
| import org.eclipse.smila.processing.ProcessingException; |
| import org.eclipse.smila.processing.parameters.ParameterAccessor; |
| |
| /** |
| * Abstract base class for JDBC Pipelets. Contains constants for database connection and SQL prepared statement |
| * parameters. |
| * |
| * The values for the PreparedStatement are selected from the input record by following the configured value paths. |
| * |
| * If a value path references a single value, this is used. If it references a sequence of values, the first value is |
| * used. In any other case, the value is set 'null'. |
| */ |
| public abstract class AbstractJdbcPipelet implements Pipelet { |
| |
| /** parameter for database url. */ |
| public static final String PARAM_DB_URL = "dbUrl"; |
| |
| /** parameter for database specific properties, e.g. user/password. */ |
| public static final String PARAM_DB_PROPS = "dbProps"; |
| |
| /** parameter for the statement (PreparedStatement) to log. */ |
| public static final String PARAM_STMT = "stmt"; |
| |
| /** parameter for the value paths which reference the values to use in the log statement. */ |
| public static final String PARAM_VALUE_PATHS = "valuePaths"; |
| |
| /** The value path separator. */ |
| public static final String VALUE_PATH_SEPARATOR = "/"; |
| |
| /** The pipelet configuration. */ |
| protected AnyMap _configuration; |
| |
| protected String getDbUrl(final ParameterAccessor paramAccessor) throws ProcessingException { |
| return paramAccessor.getRequiredParameter(PARAM_DB_URL); |
| } |
| |
| protected AnyMap getDbProps(final ParameterAccessor paramAccessor) throws ProcessingException { |
| final Any dbProps = paramAccessor.getParameterAny(PARAM_DB_PROPS); |
| if (dbProps == null || !dbProps.isMap()) { |
| throw new ProcessingException("Parameter '" + PARAM_DB_PROPS + "' should be a map, but was " |
| + (dbProps == null ? "<null>" : dbProps.getValueType())); |
| } |
| return dbProps.asMap(); |
| } |
| |
| protected String getStatement(final ParameterAccessor paramAccessor) throws ProcessingException { |
| return paramAccessor.getRequiredParameter(PARAM_STMT); |
| } |
| |
| protected List<Value> getStatementValues(final ParameterAccessor paramAccessor, final AnyMap metadata) |
| throws ProcessingException { |
| final Any values = paramAccessor.getParameterAny(PARAM_VALUE_PATHS); |
| if (values != null && !values.isSeq()) { |
| throw new ProcessingException("Parameter '" + PARAM_VALUE_PATHS + "' should be a seq, but was " |
| + values.getValueType()); |
| } |
| List<Value> stmtValues = Collections.emptyList(); |
| if (values != null) { |
| stmtValues = new ArrayList<>(values.size()); |
| for (final Any vp : values.asSeq()) { |
| if (!vp.isString()) { |
| throw new ProcessingException("Element of parameter '" + PARAM_VALUE_PATHS |
| + "' should be a string, but was " + values.getValueType()); |
| } |
| final String valuePath = vp.asValue().asString(); |
| final String[] valuePathSplit = valuePath.split(VALUE_PATH_SEPARATOR); |
| final Value value = getValue(metadata, valuePathSplit); |
| // it is ok, if the value is null |
| stmtValues.add(value); |
| } |
| } |
| return stmtValues; |
| } |
| |
| /** select value from metadata for given path. */ |
| private Value getValue(final AnyMap metadata, final String[] valuePath) { |
| final Any value = getPathValue(metadata, valuePath); |
| // automatically adapt sequence and map values |
| if (value != null) { |
| if (value.isValue()) { |
| return value.asValue(); |
| } else if (value.isSeq() && !value.isEmpty()) { |
| final Any first = value.asSeq().get(0); |
| if (first.isValue()) { |
| return first.asValue(); |
| } |
| } |
| } |
| return null; |
| } |
| |
| private Any getPathValue(final AnyMap metadata, final String[] valuePath) { |
| AnyMap current = metadata; |
| final int lastIndex = valuePath.length - 1; |
| for (int i = 0; i < lastIndex; i++) { |
| Any element = current.get(valuePath[i]); |
| if (element == null || element.isValue()) { |
| return null; |
| } |
| if (element.isSeq() && !element.isEmpty()) { |
| element = element.asSeq().get(0); |
| } |
| if (element.isMap()) { |
| current = element.asMap(); |
| } |
| } |
| return current.get(valuePath[lastIndex]); |
| } |
| |
| @Override |
| public void configure(final AnyMap configuration) throws ProcessingException { |
| _configuration = configuration; |
| } |
| |
| } |