/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kie.workbench.common.stunner.core.backend.definition.adapter.binding;
import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import java.util.Map;
import org.kie.workbench.common.stunner.core.backend.definition.adapter.AbstractRuntimeAdapter;
import org.kie.workbench.common.stunner.core.definition.adapter.binding.BindableAdapterUtils;
import org.kie.workbench.common.stunner.core.definition.adapter.binding.BindablePropertyAdapter;
import org.kie.workbench.common.stunner.core.definition.property.PropertyType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class RuntimeBindablePropertyAdapter<T, V> extends AbstractRuntimeAdapter<T>
implements BindablePropertyAdapter<T, V> {
private static final Logger LOG = LoggerFactory.getLogger(RuntimeBindablePropertyAdapter.class);
private Map<Class, String> propertyTypeFieldNames;
private Map<Class, String> propertyCaptionFieldNames;
private Map<Class, String> propertyDescriptionFieldNames;
private Map<Class, String> propertyReadOnlyFieldNames;
private Map<Class, String> propertyOptionalFieldNames;
private Map<Class, String> propertyValueFieldNames;
private Map<Class, String> propertyDefaultValueFieldNames;
private Map<Class, String> propertyAllowedValuesFieldNames;
@Override
public void setBindings(final Map<Class, String> propertyTypeFieldNames,
final Map<Class, String> propertyCaptionFieldNames,
final Map<Class, String> propertyDescriptionFieldNames,
final Map<Class, String> propertyReadOnlyFieldNames,
final Map<Class, String> propertyOptionalFieldNames,
final Map<Class, String> propertyValueFieldNames,
final Map<Class, String> propertyDefaultValueFieldNames,
final Map<Class, String> propertyAllowedValuesFieldNames) {
this.propertyTypeFieldNames = propertyTypeFieldNames;
this.propertyCaptionFieldNames = propertyCaptionFieldNames;
this.propertyDescriptionFieldNames = propertyDescriptionFieldNames;
this.propertyReadOnlyFieldNames = propertyReadOnlyFieldNames;
this.propertyOptionalFieldNames = propertyOptionalFieldNames;
this.propertyValueFieldNames = propertyValueFieldNames;
this.propertyDefaultValueFieldNames = propertyDefaultValueFieldNames;
this.propertyAllowedValuesFieldNames = propertyAllowedValuesFieldNames;
}
@Override
public String getId(final T property) {
return BindableAdapterUtils.getPropertyId(property.getClass());
}
@Override
public PropertyType getType(final T property) {
Class<?> type = property.getClass();
try {
return getFieldValue(property,
propertyTypeFieldNames.get(type));
} catch (IllegalAccessException e) {
LOG.error("Error obtaining type for Property with id " + getId(property));
}
return null;
}
@Override
public String getCaption(final T property) {
Class<?> type = property.getClass();
try {
return getFieldValue(property,
propertyCaptionFieldNames.get(type));
} catch (IllegalAccessException e) {
LOG.error("Error obtaining caption for Property with id " + getId(property));
}
return null;
}
@Override
public String getDescription(final T property) {
Class<?> type = property.getClass();
try {
return getFieldValue(property,
propertyDescriptionFieldNames.get(type));
} catch (IllegalAccessException e) {
LOG.error("Error obtaining description for Property with id " + getId(property));
}
return null;
}
@Override
public boolean isReadOnly(final T property) {
Class<?> type = property.getClass();
try {
return getFieldValue(property,
propertyReadOnlyFieldNames.get(type));
} catch (IllegalAccessException e) {
LOG.error("Error obtaining read only flag for Property with id " + getId(property));
}
return false;
}
@Override
public boolean isOptional(final T property) {
Class<?> type = property.getClass();
try {
return getFieldValue(property,
propertyOptionalFieldNames.get(type));
} catch (IllegalAccessException e) {
LOG.error("Error obtaining optional flag for Property with id " + getId(property));
}
return false;
}
@Override
public V getValue(final T property) {
Class<?> type = property.getClass();
try {
return getFieldValue(property,
propertyValueFieldNames.get(type));
} catch (IllegalAccessException e) {
LOG.error("Error obtaining value for Property with id " + getId(property));
}
return null;
}
@Override
public V getDefaultValue(final T property) {
Class<?> type = property.getClass();
try {
return getFieldValue(property,
propertyDefaultValueFieldNames.get(type));
} catch (IllegalAccessException e) {
LOG.error("Error obtaining default value for Property with id " + getId(property));
}
return null;
}
@Override
@SuppressWarnings("unchecked")
public Map<V, String> getAllowedValues(final T property) {
Class<?> type = property.getClass();
String field = propertyAllowedValuesFieldNames.get(type);
Iterable<?> allowedValues = null;
try {
allowedValues = getFieldValue(property,
field);
} catch (IllegalAccessException e) {
LOG.error("Error obtaining allowed values for Property with id " + getId(property));
}
if (null != allowedValues && allowedValues.iterator().hasNext()) {
Map<V, String> result = new LinkedHashMap<V, String>();
for (Object v : allowedValues) {
V allowedValue = (V) v;
result.put(allowedValue,
allowedValue.toString());
}
return result;
}
return null;
}
@Override
public void setValue(final T property,
final V value) {
Class<?> type = property.getClass();
String fieldName = propertyValueFieldNames.get(type);
Field field = null;
try {
field = getField(property,
fieldName);
} catch (IllegalAccessException e) {
LOG.error("Error setting value for Property with id " + getId(property)
+ ". Field [" + fieldName + "] not found for type [" + type.getName() + "]");
}
if (null != field) {
try {
field.setAccessible(true);
field.set(property,
value);
} catch (Exception e) {
LOG.error("Error setting value for Property with id [" + getId(property) + "] " +
"and value [" + (value != null ? value.toString() : "null") + "]");
}
}
}
@Override
public boolean accepts(final Class<?> type) {
return null != propertyTypeFieldNames && propertyTypeFieldNames.containsKey(type);
}
}