org.datacleaner.descriptors.RemoteConfiguredPropertyDescriptor Maven / Gradle / Ivy
/**
* DataCleaner (community edition)
* Copyright (C) 2014 Neopost - Customer Information Management
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.datacleaner.descriptors;
import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.datacleaner.api.Alias;
import org.datacleaner.api.Converter;
import org.datacleaner.api.InputColumn;
import org.datacleaner.components.remote.RemoteTransformer;
import org.datacleaner.restclient.Serializator;
import com.fasterxml.jackson.databind.JsonNode;
/**
* A Base class for property descriptors of remote transformers, implementing
* common functions. See the child classes for details.
*
* @Since 25.9.15
*/
public abstract class RemoteConfiguredPropertyDescriptor implements ConfiguredPropertyDescriptor {
private static final long serialVersionUID = 1L;
private final String name;
private final String description;
private final boolean required;
private final ComponentDescriptor> component;
private final Map, Annotation> annotations;
private final JsonNode defaultValue;
RemoteConfiguredPropertyDescriptor(final String name, final String description, final boolean required,
final ComponentDescriptor> component, final Map, Annotation> annotations,
final JsonNode defaultValue) {
this.name = name;
this.annotations = annotations;
this.defaultValue = defaultValue;
this.description = description;
this.required = required;
this.component = component;
}
@Override
public String getDescription() {
return description;
}
@Override
public boolean isRequired() {
return required;
}
@Override
public Converter> createCustomConverter() {
return null;
}
@Override
public String[] getAliases() {
final Alias alias = getAnnotation(Alias.class);
if (alias == null) {
return new String[0];
}
return alias.value();
}
@Override
public String getName() {
return name;
}
@Override
public void setValue(final Object component, final Object value) throws IllegalArgumentException {
((RemoteTransformer) component).setPropertyValue(getName(), value);
}
public void setDefaultValue(final Object component) {
if (defaultValue != null) {
setValue(component, createDefaultValue());
}
}
private Object createDefaultValue() {
// TODO: this is code duplicate with
// ComponentHandler.convertPropertyValue
// (which is used to deserialize properties values on the server side).
// TODO: But on server side a StringConverter is used for string values,
// which is not fully available on client
// side (some extenstions providing custom converters may be not
// available on client classpath).
// We must unify how values are serialized on client as well as server
// side. Maybe use pure JSON string?
// Maybe it is enough to support JsonNode in StringConverter? That
// should fit the unknown values...
try {
return Serializator.getJacksonObjectMapper().treeToValue(defaultValue, getType());
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
@Override
public boolean isInputColumn() {
return InputColumn.class.isAssignableFrom(getBaseType());
}
@Override
public Object getValue(final Object component) throws IllegalArgumentException {
return ((RemoteTransformer) component).getPropertyValue(getName());
}
@Override
public Set getAnnotations() {
return new HashSet<>(annotations.values());
}
@SuppressWarnings("unchecked")
@Override
public A getAnnotation(final Class annotationClass) {
return (A) annotations.get(annotationClass);
}
@Override
public ComponentDescriptor> getComponentDescriptor() {
return component;
}
@Override
public int getTypeArgumentCount() {
return 0;
}
@Override
public Class> getTypeArgument(final int i) throws IndexOutOfBoundsException {
return Object.class;
}
@Override
public int compareTo(final PropertyDescriptor o) {
return getName().compareTo(o.getName());
}
}