All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.asteriskjava.manager.util.EventAttributesHelper Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2004-2022 Asterisk-Java contributors
 *
 * 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.asteriskjava.manager.util;

import org.asteriskjava.manager.event.CdrEvent;
import org.asteriskjava.manager.event.UserEvent;
import org.asteriskjava.manager.response.ManagerResponse;
import org.asteriskjava.util.AstUtil;
import org.asteriskjava.util.Log;
import org.asteriskjava.util.LogFactory;
import org.asteriskjava.util.ReflectionUtil;

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;

/**
 * @author Piotr Olaszewski 
 */
public class EventAttributesHelper {
    private static final Log logger = LogFactory.getLog(EventAttributesHelper.class);

    private EventAttributesHelper() {
    }

    public static 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";
            }

            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) && !target.getClass().equals(ManagerResponse.class)) {

                //CDR has dynamic properties
                if (target instanceof CdrEvent) {
                    try {
                        Method addproperty= CdrEvent.class.getMethod("addDynamicProperties", String.class, String.class);
                        addproperty.invoke(target, entry.getKey(), entry.getValue().toString());
                    } catch (Exception e) {
                        logger.error("Unable to set Dynamic CDR Property '" + entry.getKey() + "' to '" + entry.getValue(), e);
                        continue;
                    }

                } else {
                    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");

                    for (Map.Entry entry2 : attributes.entrySet()) {
                        logger.debug("Key: " + entry2.getKey() + " Value: " + entry2.getValue());
                    }
                }
            }

            if (setter == null) {
                continue;
            }

            try {
                dataType = setter.getParameterTypes()[0];

                if (dataType == Boolean.class) {
                    value = AstUtil.isTrue(entry.getValue());
                } else if (dataType.isAssignableFrom(String.class)) {
                    value = parseString(entry);
                } else if (dataType.isAssignableFrom(Map.class)) {
                    value = parseMap(entry);
                } else if (dataType.isAssignableFrom(double.class) || dataType.isAssignableFrom(Double.class)) {
                    value = parseDouble(entry);
                } else if (dataType.isAssignableFrom(long.class) || dataType.isAssignableFrom(Long.class)) {
                    value = parseLong(entry);
                } else if (dataType.isAssignableFrom(int.class) || dataType.isAssignableFrom(Integer.class)) {
                    value = parseInteger(entry);
                } else {
                    try {
                        Constructor constructor = dataType.getConstructor(String.class);
                        // Asterisk sometimes uses yes/no instead of True/False for boolean.  java.lang.Boolean(String) doesn't handle this.
                        if (dataType.isAssignableFrom(Boolean.class)) {
                            value = constructor.newInstance(AstUtil.convertAsteriskBooleanStringToStandardBooleanString((String) entry.getValue()));
                        } else 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;
                    }
                }

                setter.invoke(target, value);
            } catch (Exception e) {
                logger.error("Unable to set property '" + entry.getKey() + "' to '" + entry.getValue() + "' on "
                    + target.getClass().getName() + " " + e.getMessage(), e);
            }
        }
    }

    private static Integer parseInteger(Map.Entry entry) {
        Integer value;
        String stringValue = (String) entry.getValue();
        if (stringValue != null && stringValue.length() > 0) {
            value = Integer.parseInt(stringValue);
        } else {
            value = null;
        }
        return value;
    }

    @SuppressWarnings("unchecked")
    private static Map parseMap(Map.Entry entry) {
        Map value;
        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;
        }
        return value;
    }

    @SuppressWarnings("unchecked")
    private static Object parseString(Map.Entry entry) {
        Object value;
        value = entry.getValue();
        if (AstUtil.isNull(value)) {

            value = null;
        }
        if (value instanceof List) {
            StringBuilder strBuff = new StringBuilder();
            for (String tmp : (List) value) {
                if (tmp != null && tmp.length() != 0) {
                    strBuff.append(tmp).append('\n');
                }
            }
            value = strBuff.toString();
        }
        return value;
    }

    private static Double parseDouble(Map.Entry entry) {
        Double value;
        String stringValue = (String) entry.getValue();
        if (stringValue != null && stringValue.length() > 0) {
            value = Double.parseDouble(stringValue);
        } else {
            value = null;
        }
        return value;
    }

    private static Long parseLong(Map.Entry entry) {
        Long value;
        String stringValue = (String) entry.getValue();
        if (stringValue != null && stringValue.length() > 0) {
            value = Long.parseLong(stringValue);
        } else {
            value = null;
        }
        return value;
    }

    private static 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 - 2024 Weber Informatics LLC | Privacy Policy