Package com.eteks.sweethome3d.plugin

Source Code of com.eteks.sweethome3d.plugin.PluginAction

/*
* PluginAction.java 26 oct. 2008
*
* Sweet Home 3D, Copyright (c) 2008 Emmanuel PUYBARET / eTeks <info@eteks.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
package com.eteks.sweethome3d.plugin;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import com.eteks.sweethome3d.tools.ResourceURLContent;

/**
* An action made available to application users through a plugin.
* @author Emmanuel Puybaret
*/
public abstract class PluginAction {
  /**
   * Enumeration of the various properties this action may define.
   */
  public enum Property {
    /**
     * The key of the property of <code>String</code> type that specifies
     * the name of an action, used for a menu or button.
     */
    NAME,
    /**
     * The key of the property of <code>String</code> type that specifies
     * a short description of an action, used for tool tip text.
     */
    SHORT_DESCRIPTION,
    /**
     * The key of the property of <code>Content</code> type that specifies
     * an image content of an action, used for tool bar buttons. 
     */
    SMALL_ICON,
    /**
     * The key of the property of <code>Character</code> type that specifies
     * the ASCII character used as the mnemonic of an action.
     */
    MNEMONIC,
    /**
     * The key of the property of <code>Boolean</code> type that specifies
     * if an action will appear in the main tool bar.
     */
    TOOL_BAR,
    /**
     * The key of the property of <code>String</code> type that specifies
     * in which menu of the main menu bar an action should appear.
     */
    MENU,
    /**
     * The key of the property of <code>Boolean</code> type that specifies
     * if an action is enabled or not.
     */
    ENABLED,
  }
 
  private final Map<Property, Object> propertyValues        = new HashMap<Property, Object>();
  private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
 
  /**
   * Creates a disabled plug-in action.
   */
  public PluginAction() {
  }

  /**
   * Creates a disabled plug-in action with properties retrieved from a resource bundle
   * in which key starts with <code>actionPrefix</code>.
   * <br>For example, a plug-in action created by the call
   * <code>new PluginAction("com.mycompany.mypackage.MyResources", "EXPORT", plugin.getPluginClassLoader())</code>
   * will retrieve its property values from the <code>/com/mycompany/mypackage/MyResources.properties</code> file
   * bundled with the plug-in class, and this file may describe the action <code>EXPORT</code>
   * with the following keys:
   * <pre> EXPORT.NAME=Export
   * EXPORT.SHORT_DESCRIPTION=Export home data
   * EXPORT.SMALL_ICON=/com/mycompany/mypackage/resources/export.png
   * EXPORT.MNEMONIC=X
   * EXPORT.IN_TOOL_BAR=true
   * EXPORT.MENU=File</pre>
   * @param resourceBaseName the base name of a resource bundle 
   * @param actionPrefix  prefix used in resource bundle to search action properties
   * @param pluginClassLoader the class loader that will be used to search the resource bundle  
   * @throws MissingResourceException if no resource bundle could be found from
   *    <code>resourceBaseName</code>.
   */
  public PluginAction(String resourceBaseName,
                      String actionPrefix,
                      ClassLoader pluginClassLoader) {
    this(resourceBaseName, actionPrefix, pluginClassLoader, false);
  }
 
  /**
   * Creates an action with properties retrieved from a resource bundle
   * in which key starts with <code>actionPrefix</code>.
   * @param resourceBaseName the base name of a resource bundle
   * @param actionPrefix  prefix used in resource bundle to search action properties
   * @param pluginClassLoader the class loader that will be used to search the resource bundle  
   * @param enabled <code>true</code> if the action should be enabled at creation.
   * @throws MissingResourceException if no resource bundle could be found from
   *    <code>resourceBaseName</code>.
   */
  public PluginAction(String resourceBaseName,
                      String actionPrefix,
                      ClassLoader pluginClassLoader,
                      boolean enabled) {
    readActionPropertyValues(resourceBaseName, actionPrefix, pluginClassLoader);   
    setEnabled(enabled);
  }
   
  /**
   * Reads the properties of this action from a resource bundle of given base name.
   * @throws MissingResourceException if no resource bundle could be found from
   *    <code>resourceBaseName</code>.
   */
  private void readActionPropertyValues(String resourceBaseName,
                                        String actionPrefix,
                                        ClassLoader pluginClassLoader) {
    ResourceBundle resource;
    if (pluginClassLoader != null) {
      resource = ResourceBundle.getBundle(resourceBaseName, Locale.getDefault(),
        pluginClassLoader);
    } else {
      resource = ResourceBundle.getBundle(resourceBaseName, Locale.getDefault());
    }
    String propertyPrefix = actionPrefix + ".";
    putPropertyValue(Property.NAME,
        getOptionalString(resource, propertyPrefix + Property.NAME));
    putPropertyValue(Property.SHORT_DESCRIPTION,
        getOptionalString(resource, propertyPrefix + Property.SHORT_DESCRIPTION));
    String smallIcon = getOptionalString(resource, propertyPrefix + Property.SMALL_ICON);
    if (smallIcon != null) {
      if (smallIcon.startsWith("/")) {
        smallIcon = smallIcon.substring(1);
      }
      putPropertyValue(Property.SMALL_ICON,
          new ResourceURLContent(pluginClassLoader, smallIcon));
    }
    String mnemonicKey = getOptionalString(resource, propertyPrefix + Property.MNEMONIC);
    if (mnemonicKey != null) {
      putPropertyValue(Property.MNEMONIC, Character.valueOf(mnemonicKey.charAt(0)));
    }
    String toolBar = getOptionalString(resource, propertyPrefix + Property.TOOL_BAR);
    if (toolBar != null) {
      putPropertyValue(Property.TOOL_BAR, Boolean.valueOf(toolBar));
    }
    putPropertyValue(Property.MENU,
        getOptionalString(resource, propertyPrefix + Property.MENU));
  }

  /**
   * Returns the value of <code>propertyKey</code> in <code>resource</code>,
   * or <code>null</code> if the property doesn't exist.
   */
  private String getOptionalString(ResourceBundle resource, String propertyKey) {
    try {
      return resource.getString(propertyKey);
    } catch (MissingResourceException ex) {
      return null;
    }
  }
 
  /**
   * Adds the property change <code>listener</code> in parameter to this plugin action.
   */
  public void addPropertyChangeListener(PropertyChangeListener listener) {
    this.propertyChangeSupport.addPropertyChangeListener(listener);
  }

  /**
   * Removes the property change <code>listener</code> in parameter from this plugin action.
   */
  public void removePropertyChangeListener(PropertyChangeListener listener) {
    this.propertyChangeSupport.removePropertyChangeListener(listener);
  }
 
  /**
   * Returns a property value of this action.
   */
  public Object getPropertyValue(Property property) {
    return this.propertyValues.get(property);
  }
 
  /**
   * Sets a property value of this action, and fires a <code>PropertyChangeEvent</code>
   * if the value changed.
   */
  public void putPropertyValue(Property property, Object value) {
    Object oldValue = this.propertyValues.get(property);
    if (value != oldValue
        || (value != null && !value.equals(oldValue))) {
      this.propertyValues.put(property, value);
      this.propertyChangeSupport.firePropertyChange(property.name(), oldValue, value);
    }
   
  }

  /**
   * Sets the enabled state of this action. When enabled, any menu item or tool bar button
   * associated with this object is enabled and able to call the <code>execute</code> method.
   * If the value has changed, a <code>PropertyChangeEvent</code> is sent
   * to listeners. By default, an action is disabled.
   */
  public void setEnabled(boolean enabled) {
    putPropertyValue(Property.ENABLED, enabled);
  }
 
  /**
   * Returns the enabled state of this action.
   * @return <code>true</code> if this action is enabled.
   */
  public boolean isEnabled() {
    Boolean enabled = (Boolean)getPropertyValue(Property.ENABLED);
    return enabled != null && enabled.booleanValue();
  }
 
  /**
   * Executes this action. This method will be called by application when the user
   * wants to execute this action.
   */
  public abstract void execute();
}
TOP

Related Classes of com.eteks.sweethome3d.plugin.PluginAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.