BeanPropertyKnob.java

  1. // @formatter:off
  2.  /*******************************************************************************
  3.  *
  4.  * This file is part of JMad.
  5.  *
  6.  * Copyright (c) 2008-2011, CERN. All rights reserved.
  7.  *
  8.  * Licensed under the Apache License, Version 2.0 (the "License");
  9.  * you may not use this file except in compliance with the License.
  10.  * You may obtain a copy of the License at
  11.  *
  12.  *     http://www.apache.org/licenses/LICENSE-2.0
  13.  *
  14.  * Unless required by applicable law or agreed to in writing, software
  15.  * distributed under the License is distributed on an "AS IS" BASIS,
  16.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17.  * See the License for the specific language governing permissions and
  18.  * limitations under the License.
  19.  *
  20.  ******************************************************************************/
  21. // @formatter:on

  22. /*
  23.  * $Id: BeanVariationParameter.java,v 1.2 2009-01-20 19:43:09 kfuchsbe Exp $
  24.  *
  25.  * $Date: 2009-01-20 19:43:09 $ $Revision: 1.2 $ $Author: kfuchsbe $
  26.  *
  27.  * Copyright CERN, All Rights Reserved.
  28.  */
  29. package cern.accsoft.steering.jmad.domain.knob.bean;

  30. import org.apache.commons.beanutils.PropertyUtils;
  31. import org.slf4j.Logger;
  32. import org.slf4j.LoggerFactory;

  33. import cern.accsoft.steering.jmad.domain.knob.AbstractKnob;
  34. import cern.accsoft.steering.jmad.util.bean.NamedBean;

  35. /**
  36.  * this class provides a knob, which just needs a bean and a property of it.
  37.  * <p>
  38.  * <b>Be careful:</b> Remove these Knobs from all lists, when the bean shall be destroyed!
  39.  * <p>
  40.  * This class is designed to be sub classed by more dedicated knobs, that have to provide the actual bean by the
  41.  * {@link #getBean()} method.
  42.  *
  43.  * @author Kajetan Fuchsberger (kajetan.fuchsberger at cern.ch)
  44.  */
  45. public abstract class BeanPropertyKnob extends AbstractKnob {

  46.     /** the logger for the class */
  47.     private static final Logger LOGGER = LoggerFactory.getLogger(BeanPropertyKnob.class);

  48.     /** the separator between bean-name and property-name, which is used when creating keys */
  49.     public static final String NAME_PROPETY_SEPARATOR = ".";

  50.     /** the name of the property we vary */
  51.     private final String propertyName;

  52.     /**
  53.      * the constructor, which needs a property-name.
  54.      *
  55.      * @param propertyName the name of the property, which we will vary
  56.      */
  57.     public BeanPropertyKnob(String propertyName) {
  58.         this.propertyName = propertyName;
  59.     }

  60.     /*
  61.      * some simple helper methods
  62.      */

  63.     /**
  64.      * Gets a double value from a bean-property with the given name.
  65.      *
  66.      * @param bean the bean from which to get the value
  67.      * @param propertyName the name of the property
  68.      * @return the actual value of the varied property of the bean
  69.      */
  70.     private static final double getBeanValue(Object bean, String propertyName) {
  71.         try {
  72.             Double value = (Double) PropertyUtils.getSimpleProperty(bean, propertyName);
  73.             if (value != null) {
  74.                 return value.doubleValue();
  75.             }
  76.         } catch (Exception e) {
  77.             LOGGER.error("Cannot read property '" + propertyName + "' of bean '" + bean + "'.", e);
  78.         }
  79.         return 0.0;
  80.     }

  81.     /**
  82.      * @return the actual value of the property
  83.      */
  84.     private double getBeanValue() {
  85.         return getBeanValue(getBean(), this.propertyName);
  86.     }

  87.     /**
  88.      * create a key for this bean- propertyName combination
  89.      *
  90.      * @param bean the on which to use the property
  91.      * @param propertyName the name of the property
  92.      * @return a combined key
  93.      */
  94.     public static final String createKey(Object bean, String propertyName) {
  95.         String name;
  96.         if (bean instanceof NamedBean) {
  97.             name = ((NamedBean) bean).getName();
  98.         } else {
  99.             name = bean.toString();
  100.         }
  101.         return name + NAME_PROPETY_SEPARATOR + propertyName;
  102.     }

  103.     /**
  104.      * set the property to a given value
  105.      *
  106.      * @param value the value to set the property to
  107.      */
  108.     private void setBeanValue(double value) {
  109.         try {
  110.             PropertyUtils.setSimpleProperty(getBean(), this.propertyName, value);
  111.         } catch (Exception e) {
  112.             LOGGER.error("Cannot set property '" + this.propertyName + "' of bean '" + getBean() + "'.", e);
  113.         }
  114.     }

  115.     /**
  116.      * extracts the property-name from the key
  117.      *
  118.      * @param key the key from which to extract the property name
  119.      * @return the name of the property
  120.      */
  121.     public static final String getPropertyNameFromKey(String key) {
  122.         int index = key.lastIndexOf(NAME_PROPETY_SEPARATOR);
  123.         if (index >= 0) {
  124.             return key.substring(index + NAME_PROPETY_SEPARATOR.length());
  125.         }
  126.         return null;
  127.     }

  128.     @Override
  129.     protected final void doSetTotalValue(double value) {
  130.         this.setBeanValue(value);
  131.     }

  132.     @Override
  133.     public String getKey() {
  134.         return createKey(getBean(), this.propertyName);
  135.     }

  136.     @Override
  137.     public String getName() {
  138.         return this.getKey();
  139.     }

  140.     @Override
  141.     public double getTotalValue() {
  142.         return getBeanValue();
  143.     }

  144.     /**
  145.      * must be implemented by subclass in order to provide the bean instance to/from which to get/set values.
  146.      *
  147.      * @return the bean
  148.      */
  149.     protected abstract Object getBean();

  150. }