/******************************************************************************* * Copyright (c) 2007, 2014 compeople AG and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * compeople AG - initial API and implementation *******************************************************************************/ package org.eclipse.riena.ui.ridgets.uibinding; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; import org.apache.commons.beanutils.PropertyUtils; import org.osgi.service.log.LogService; import org.eclipse.equinox.log.Logger; import org.eclipse.riena.beans.common.BeanPropertyUtils; import org.eclipse.riena.core.Log4r; import org.eclipse.riena.core.util.ReflectionFailure; import org.eclipse.riena.internal.ui.ridgets.Activator; import org.eclipse.riena.ui.ridgets.IRidget; import org.eclipse.riena.ui.ridgets.IRidgetContainer; import org.eclipse.riena.ui.ridgets.UIBindingFailure; /** * This class manages the binding between UI-control and ridget. */ public class InjectBindingManager extends DefaultBindingManager { // cache for PropertyDescriptors private final Map<String, PropertyDescriptor> binding2PropertyDesc; private static final Logger LOGGER = Log4r.getLogger(Activator.getDefault(), InjectBindingManager.class); /** * Creates the managers of all bindings of a view. * * @param propertyStrategy * strategy to get the property for the binding from the * UI-control. * @param mapper * mapping for UI control-classes to ridget-classes */ public InjectBindingManager(final IBindingPropertyLocator propertyStrategy, final IControlRidgetMapper<Object> mapper) { super(propertyStrategy, mapper); binding2PropertyDesc = new HashMap<String, PropertyDescriptor>(); } /** * @see org.eclipse.riena.ui.internal.ridgets.uibinding.DefaultBindingManager#injectRidget(org.eclipse.riena.ui.internal.ridgets.IRidgetContainer, * java.lang.String, org.eclipse.riena.ui.internal.ridgets.IRidget) */ @Override protected void injectRidget(final IRidgetContainer ridgetContainer, final String bindingProperty, final IRidget ridget) { super.injectRidget(ridgetContainer, bindingProperty, ridget); try { injectIntoController(ridget, ridgetContainer, bindingProperty); } catch (final ReflectionFailure e) { final UIBindingFailure ee = new UIBindingFailure("Cannot create ridget for ridget property '" //$NON-NLS-1$ + bindingProperty + "' of ridget container " + ridgetContainer, e); //$NON-NLS-1$ LOGGER.log(LogService.LOG_ERROR, ee.getMessage(), ee); throw ee; } } private void injectIntoController(final IRidget ridget, final IRidgetContainer controller, final String bindingProperty) { final PropertyDescriptor desc = getPropertyDescriptor(bindingProperty, controller); if (desc == null) { final String msg = String.format( "No method '%s' on %s", bindingProperty, controller.getClass().getSimpleName()); //$NON-NLS-1$ throw new UnsupportedOperationException(msg); } BeanPropertyUtils.setPropertyValue(controller, desc, ridget); } private PropertyDescriptor getPropertyDescriptor(final String bindingProperty, final IRidgetContainer ridgetContainer) { final PropertyDescriptor desc = binding2PropertyDesc.get(bindingProperty); if (desc != null) { return desc; } return createPropertyDescriptor(bindingProperty, ridgetContainer); } private PropertyDescriptor createPropertyDescriptor(final String bindingProperty, final IRidgetContainer ridgetContainer) { try { final PropertyDescriptor desc = PropertyUtils.getPropertyDescriptor(ridgetContainer, bindingProperty); binding2PropertyDesc.put(bindingProperty, desc); return desc; } catch (final IllegalAccessException e) { final UIBindingFailure bindingFailure = new UIBindingFailure( "Cannot access ridget property '" + bindingProperty //$NON-NLS-1$ + "' of ridget container " + ridgetContainer, e); //$NON-NLS-1$ LOGGER.log(LogService.LOG_ERROR, bindingFailure.getMessage(), bindingFailure); } catch (final InvocationTargetException e) { final UIBindingFailure bindingFailure = new UIBindingFailure( "Cannot access ridget property '" + bindingProperty //$NON-NLS-1$ + "' of ridget container " + ridgetContainer, e); //$NON-NLS-1$ LOGGER.log(LogService.LOG_ERROR, bindingFailure.getMessage(), bindingFailure); } catch (final NoSuchMethodException e) { final UIBindingFailure bindingFailure = new UIBindingFailure( "Cannot access ridget property '" + bindingProperty //$NON-NLS-1$ + "' of ridget container " + ridgetContainer, e); //$NON-NLS-1$ LOGGER.log(LogService.LOG_ERROR, bindingFailure.getMessage(), bindingFailure); } return null; } /** * @see org.eclipse.riena.ui.internal.ridgets.uibinding.DefaultBindingManager#getRidget(java.lang.String, * org.eclipse.riena.ui.internal.ridgets.IRidgetContainer) */ @Override protected IRidget getRidget(final String bindingProperty, final IRidgetContainer controller) { final PropertyDescriptor desc = getPropertyDescriptor(bindingProperty, controller); return (IRidget) BeanPropertyUtils.getPropertyValue(controller, desc); } }