
org.asteriskjava.manager.internal.AbstractBuilder Maven / Gradle / Ivy
package org.asteriskjava.manager.internal;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.asteriskjava.manager.event.UserEvent;
import org.asteriskjava.util.AstUtil;
import org.asteriskjava.util.ReflectionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Abstract base class for reflection based builders.
*/
abstract class AbstractBuilder {
private static final Logger logger = LoggerFactory.getLogger(AbstractBuilder.class);
@SuppressWarnings("unchecked")
protected void setAttributes(Object target, Map attributes,
Set ignoredAttributes) {
Map setters;
setters = ReflectionUtil.getSetters(target.getClass());
for (Map.Entry entry : attributes.entrySet()) {
Object value;
final Class> dataType;
Method setter;
String setterName;
if (ignoredAttributes != null && ignoredAttributes.contains(entry.getKey())) {
continue;
}
setterName = ReflectionUtil.stripIllegalCharacters(entry.getKey());
/*
* The source property needs special handling as it is already
* defined in java.util.EventObject (the base class of
* ManagerEvent), so we have to translate it.
*/
if ("source".equals(setterName)) {
setterName = "src";
} else if ("class".equals(setterName)) {
setterName = "clazz";
}
/*
* The class property needs to be renamed. It is used in
* MusicOnHoldEvent.
*/
if ("class".equals(setterName)) {
setterName = "classname";
}
setter = setters.get(setterName);
if (setter == null && !setterName.endsWith("s")) // no exact match
// => try plural
{
setter = setters.get(setterName + "s");
// but only for maps
if (setter != null
&& !(setter.getParameterTypes()[0].isAssignableFrom(Map.class))) {
setter = null;
}
}
// it seems silly to warn if it's a user event -- maybe it was
// intentional
if (setter == null && !(target instanceof UserEvent)) {
logger.warn("Unable to set property '" + entry.getKey() + "' to '"
+ entry.getValue() + "' on " + target.getClass()
.getName()
+ ": no setter. Please report at https://github.com/asterisk-java/asterisk-java/issues");
}
if (setter == null) {
continue;
}
dataType = setter.getParameterTypes()[0];
if (dataType == Boolean.class) {
value = AstUtil.isTrue(entry.getValue());
} else if (dataType.isAssignableFrom(String.class)) {
value = entry.getValue();
if (AstUtil.isNull(value)) {
value = null;
}
} else if (dataType.isAssignableFrom(Map.class)) {
if (entry.getValue() instanceof List) {
List list = (List) entry.getValue();
value = buildMap(list.toArray(new String[list.size()]));
} else if (entry.getValue() instanceof String) {
value = buildMap((String) entry.getValue());
} else {
value = null;
}
} else {
try {
Constructor> constructor =
dataType.getConstructor(new Class[] { String.class });
value = constructor.newInstance(entry.getValue());
} catch (Exception e) {
logger.error(
"Unable to convert value: Called the constructor of " + dataType
+ " with value '" + entry.getValue() + "' for the attribute '"
+ entry.getKey() + "'\n of event type " + target.getClass()
.getName()
+ " with resulting error: " + e.getMessage(),
e);
continue;
}
}
try {
setter.invoke(target, value);
} catch (Exception e) {
logger.error("Unable to set property '" + entry.getKey() + "' to '"
+ entry.getValue() + "' on " + target.getClass()
.getName(),
e);
}
}
}
private Map buildMap(String... lines) {
if (lines == null) {
return null;
}
final Map map = new LinkedHashMap<>();
for (String line : lines) {
final int index = line.indexOf('=');
if (index > 0) {
final String key = line.substring(0, index);
final String value = line.substring(index + 1, line.length());
map.put(key, value);
} else {
logger.warn("Malformed line '" + line + "' for a map property");
}
}
return map;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy