blob: 0d72fe2587c3f4522ca9e5c03412419c58bffc41 [file] [log] [blame]
/*******************************************************************************
* 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;
}
}