/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library 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. */ package com.liferay.portal.configuration.module.configuration.internal; import aQute.bnd.annotation.metatype.Meta; import com.liferay.portal.kernel.settings.LocalizedValuesMap; import com.liferay.portal.kernel.settings.TypedSettings; import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.ProxyUtil; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @author Iván Zaera */ public class ConfigurationInvocationHandler<S> implements InvocationHandler { public ConfigurationInvocationHandler( Class<S> clazz, Object configurationOverrideInstance, TypedSettings typedSettings) { _clazz = clazz; _configurationOverrideInstance = configurationOverrideInstance; _typedSettings = typedSettings; } public S createProxy() { return (S)ProxyUtil.newProxyInstance( _clazz.getClassLoader(), new Class<?>[] {_clazz}, this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException { if (_configurationOverrideInstance != null) { try { return _invokeConfigurationOverride(method, args); } catch (InvocationTargetException ite) { throw ite; } catch (Exception e) { } } try { return _invokeTypedSettings(method); } catch (Exception e) { throw new RuntimeException(e); } } private Object _getValue(Class<?> returnType, String key) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException { if (returnType.equals(boolean.class) || returnType.equals(double.class) || returnType.equals(float.class) || returnType.equals(int.class) || returnType.equals(long.class)) { String value = _typedSettings.getValue(key, null); if (value == null) { return value; } else if (returnType.equals(boolean.class)) { return GetterUtil.getBoolean(value); } else if (returnType.equals(double.class)) { return GetterUtil.getDouble(value); } else if (returnType.equals(float.class)) { return GetterUtil.getFloat(value); } else if (returnType.equals(int.class)) { return GetterUtil.getInteger(value); } else if (returnType.equals(long.class)) { return GetterUtil.getLong(value); } } else if (returnType.equals(LocalizedValuesMap.class)) { LocalizedValuesMap localizedValuesMap = _typedSettings.getLocalizedValuesMap(key); if (localizedValuesMap.getDefaultValue() == null) { return null; } return localizedValuesMap; } else if (returnType.equals(String.class)) { return _typedSettings.getValue(key, null); } else if (returnType.equals(String[].class)) { return _typedSettings.getValues(key, null); } else if (returnType.isEnum()) { String value = _typedSettings.getValue(key, null); if (value == null) { return value; } Method valueOfMethod = returnType.getDeclaredMethod( "valueOf", String.class); return valueOfMethod.invoke(returnType, value); } Constructor<?> constructor = returnType.getConstructor(String.class); return constructor.newInstance(_typedSettings.getValue(key, null)); } private Object _invokeConfigurationOverride(Method method, Object[] args) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException { Class<?> clazz = _configurationOverrideInstance.getClass(); method = clazz.getMethod(method.getName(), method.getParameterTypes()); return method.invoke(_configurationOverrideInstance, args); } private Object _invokeTypedSettings(Method method) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException { Class<?> returnType = method.getReturnType(); Meta.AD annotation = method.getAnnotation(Meta.AD.class); if ((annotation != null) && !Meta.NULL.equals(annotation.id())) { Object value = _getValue(returnType, annotation.id()); if (value != null) { return value; } } if (returnType.equals(boolean.class)) { return _typedSettings.getBooleanValue(method.getName()); } else if (returnType.equals(double.class)) { return _typedSettings.getDoubleValue(method.getName()); } else if (returnType.equals(float.class)) { return _typedSettings.getFloatValue(method.getName()); } else if (returnType.equals(int.class)) { return _typedSettings.getIntegerValue(method.getName()); } else if (returnType.equals(LocalizedValuesMap.class)) { return _typedSettings.getLocalizedValuesMap(method.getName()); } else if (returnType.equals(long.class)) { return _typedSettings.getLongValue(method.getName()); } else if (returnType.equals(String.class)) { return _typedSettings.getValue(method.getName()); } else if (returnType.equals(String[].class)) { return _typedSettings.getValues(method.getName()); } else if (returnType.isEnum()) { Method valueOfMethod = returnType.getDeclaredMethod( "valueOf", String.class); return valueOfMethod.invoke( returnType, _typedSettings.getValue(method.getName())); } Constructor<?> constructor = returnType.getConstructor(String.class); return constructor.newInstance( _typedSettings.getValue(method.getName())); } private final Class<S> _clazz; private final Object _configurationOverrideInstance; private final TypedSettings _typedSettings; }