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

net.sf.cuf.ui.builder.NonVisualBuilderDelegate Maven / Gradle / Ivy

The newest version!
package net.sf.cuf.ui.builder;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.ResourceBundle;

import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.KeyStroke;

import org.jdom2.Attribute;
import org.jdom2.Element;

import net.sf.cuf.ui.DispatcherAction;
import net.sf.cuf.ui.SwingDecoratorFunctionality;

/**
 * The NonVisualBuilderDelegate class handles the "nonvisual" entry of
 * a xml2swing XML description.
 */
class NonVisualBuilderDelegate implements SwingXMLBuilder.BuilderDelegate
{
    /** Currently running builder. Only set while {@link #build(SwingXMLBuilder, org.jdom2.Element)} is called. */
    private SwingXMLBuilder mBuilder = null;

    /**
     * Build the specific part of the delegate.
     * @param pBuilder the builder that controls the creation process
     * @param pElement the JDOM element the delegate should handle, "nonvisual" in our case
     */
    public void build(final SwingXMLBuilder pBuilder, final Element pElement)
    {
        mBuilder = pBuilder;
        try
        {
            List objects= pElement.getChildren();
            for (final Object object1 : objects)
            {
                Element element = (Element) object1;
                String objectType = element.getName();

                // object or action or resource we create
                Object object = null;

                // get id
                Attribute idAttribute = element.getAttribute(SwingXMLBuilder.ID_ATTRIBUTE);
                if (idAttribute == null)
                {
                    if (objectType.equals(SwingXMLBuilder.RESOURCE_ELEMENT))
                    {
                        idAttribute = new Attribute(SwingXMLBuilder.ID_ATTRIBUTE, SwingXMLBuilder.DEFAULT_ID_RESOURCE);
                    }
                    else
                    {
                        throw SwingXMLBuilder.createException("a non visual element needs a " + SwingXMLBuilder.ID_ATTRIBUTE + " attribute", pElement);
                    }
                }

                // check if we need to create that object at all
                String id = idAttribute.getValue();

                if (mBuilder.getNameToNonVisual().containsKey(id))
                {
                    continue;
                }

                if (objectType.equals(SwingXMLBuilder.OBJECT_ELEMENT))
                {
                    object = createObject(element);
                }
                else if (objectType.equals(SwingXMLBuilder.ACTION_ELEMENT))
                {
                    object = createAction(element);
                    // decorate this action from the resource bundle
                    SwingDecoratorFunctionality decorator = mBuilder.getSwingDecorator();

                    if (decorator != null)
                    {
                        decorator.initialize((Action) object, id);
                    }
                }
                else if (objectType.equals(SwingXMLBuilder.RESOURCE_ELEMENT))
                {
                    object = createResource(element);
                }
                else
                {
                    // ignore unknonwn elements
                }

                // put it in our builder's map
                mBuilder.getNameToNonVisual().put(id, object);
            }
        }
        finally
        {
            mBuilder = null;
        }
    }


    /**
     * Create a new object.
     * @param pElement element describing the object
     * @throws IllegalArgumentException if we have a create problem (class not found, ...)
     * @return the new object, never null
     */
    private Object createObject(final Element pElement) throws IllegalArgumentException
    {
        Object object;
        // get class
        Attribute classAttribute= pElement.getAttribute(SwingXMLBuilder.CLASS_ATTRIBUTE);
        if (classAttribute == null)
            throw SwingXMLBuilder.createException("a non visual element needs a "+
                                                  SwingXMLBuilder.CLASS_ATTRIBUTE+" attribute", pElement);
        String constantValue = pElement.getAttributeValue(SwingXMLBuilder.CONSTANT_ATTRIBUTE);
        
        if (constantValue==null)
        {
            // create object by constructor
            String objectClassName= classAttribute.getValue();
            try
            {
                Class objectClass= Class.forName(objectClassName);
                object= objectClass.newInstance();
            }
            catch (Exception e)
            {
                throw SwingXMLBuilder.createException("could not create a object of class "+objectClassName+
                                                      " not found", e, pElement);
            }
        }
        else
        {
            // access static final attribute of class
            String objectClassName= classAttribute.getValue();
            try
            {
                Class objectClass= Class.forName(objectClassName);
                Field field = objectClass.getField( constantValue);
                if (!Modifier.isStatic( field.getModifiers()) || !Modifier.isFinal( field.getModifiers()))
                {
                    throw SwingXMLBuilder.createException("field "+field+" is not public static final", pElement);
                }
                object = field.get(null);
            }
            catch (Exception e)
            {
                throw SwingXMLBuilder.createException("could not access public static final attribute of class "+objectClassName, e, pElement);
            }
        }
        // check if we should provide a back link to ourself
        if (object instanceof SwingXMLBuilder.Backlink)
        {
            ((SwingXMLBuilder.Backlink)object).setSwingXMLBuilder(mBuilder);
        }
        return object;
    }

    /**
     * Create a new Action, if no class is specified this is a DispatcherAction.
     * @param pElement element describing the action
     * @return the new action, never null
     */
    private Action createAction(final Element pElement)
    {
        // first extract typical action information
        String name       = null;
        String accelerator= null;
        String mnemonic   = null;
        String tooltip    = null;
        String iconRelName= null;

        for (final Object o5 : pElement.getChildren(SwingXMLBuilder.TEXT_ELEMENT))
        {
            Element textElement = (Element) o5;
            if (mBuilder.isSameLanguage(textElement))
                name = textElement.getTextTrim();
        }

        for (final Object o4 : pElement.getChildren(SwingXMLBuilder.ACCELERATOR_ELEMENT))
        {
            Element acceleratorElement = (Element) o4;
            if (mBuilder.isSameLanguage(acceleratorElement))
                accelerator = acceleratorElement.getTextTrim();
        }

        for (final Object o3 : pElement.getChildren(SwingXMLBuilder.MNEMONIC_ELEMENT))
        {
            Element mnemonicElement = (Element) o3;
            if (mBuilder.isSameLanguage(mnemonicElement))
                mnemonic = mnemonicElement.getTextTrim();
        }

        for (final Object o2 : pElement.getChildren(SwingXMLBuilder.TOOLTIP_ELEMENT))
        {
            Element tooltipElement = (Element) o2;
            if (mBuilder.isSameLanguage(tooltipElement))
                tooltip = tooltipElement.getTextTrim();
        }

        for (final Object o1 : pElement.getChildren(SwingXMLBuilder.ICON_ELEMENT))
        {
            Element iconRelNameElement = (Element) o1;
            if (mBuilder.isSameLanguage(iconRelNameElement))
            {
                iconRelName = iconRelNameElement.getAttributeValue(SwingXMLBuilder.NAME_ATTRIBUTE);
            }
        }
        Icon icon= mBuilder.getIconCache().getIcon(iconRelName, IconCache.ICON_MODIFIER_NORMAL);

        // create action, if no special class is defined create a DispatcherAction
        Action action;
        String className= pElement.getAttributeValue(SwingXMLBuilder.CLASS_ATTRIBUTE);
        if (className==null)
        {
            boolean isToogle= pElement.getChild(SwingXMLBuilder.IS_TOGGLE_ELEMENT)!=null;
            action= new DispatcherAction(name, accelerator, mnemonic, tooltip, icon, isToogle);
        }
        else
        {
            try
            {
                action= (Action)Class.forName(className).newInstance();
            }
            catch (Exception e)
            {
                throw SwingXMLBuilder.createException("could not create a object of class "+className,
                                                      e, pElement);
            }

            Integer mnemonicInteger= null;
            if ((mnemonic!=null) && (mnemonic.length()>0))
            {
                mnemonicInteger= (int) Character.toUpperCase(mnemonic.charAt(0));
            }
            KeyStroke keyStroke= null;
            if ((accelerator!=null) && (accelerator.length()>0))
            {
                keyStroke= KeyStroke.getKeyStroke(accelerator);
            }
            action.putValue(Action.NAME,              name);
            action.putValue(Action.ACCELERATOR_KEY,   keyStroke);
            action.putValue(Action.MNEMONIC_KEY,      mnemonicInteger);
            action.putValue(Action.SHORT_DESCRIPTION, tooltip);
            action.putValue(Action.SMALL_ICON,        icon);
        }

        // check if we should provide a back link to ourself
        if (action instanceof SwingXMLBuilder.Backlink)
        {
            ((SwingXMLBuilder.Backlink)action).setSwingXMLBuilder(mBuilder);
        }

        // now extract optional action information
        for (final Object o : pElement.getChildren(SwingXMLBuilder.PROPERTY_ELEMENT))
        {
            Element element = (Element) o;
            String key = element.getAttributeValue(SwingXMLBuilder.KEY_ATTRIBUTE);
            if (key == null)
            {
                throw SwingXMLBuilder.createException("invalid null key", element);
            }
            Object value = getValue(mBuilder, element, key);

            action.putValue(key, value);
        }

        return action;
    }

    /**
     * Small helper to get the value for a key.
     * @param pBuilder the builder that controls the creation process
     * @param pElement the parsed element
     * @param pKey the key name
     * @return the value for the key
     * @throws IllegalArgumentException if we don't know the key
     */
    static Object getValue(final SwingXMLBuilder pBuilder, final Element pElement, final String pKey)
    {
        Object value;
        if (pElement.getAttribute(SwingXMLBuilder.VALUE_ATTRIBUTE) != null)
        {
            value= pElement.getAttributeValue(SwingXMLBuilder.VALUE_ATTRIBUTE);
        }
        else if (pElement.getAttribute(SwingXMLBuilder.BOOLEAN_ATTRIBUTE) != null)
        {
            if ("true".equals(pElement.getAttributeValue(SwingXMLBuilder.BOOLEAN_ATTRIBUTE)))
                value= Boolean.TRUE;
            else
                value= Boolean.FALSE;
        }
        else if (pElement.getAttribute(SwingXMLBuilder.INT_ATTRIBUTE) != null)
        {
            String intString= pElement.getAttributeValue(SwingXMLBuilder.INT_ATTRIBUTE);
            try
            {
                value= Integer.parseInt(intString);
            }
            catch (NumberFormatException e)
            {
                throw SwingXMLBuilder.createException("invalid int value "+intString, e, pElement);
            }
        }
        else if (pElement.getAttribute(SwingXMLBuilder.REF_ATTRIBUTE) != null)
        {
            String objRef= pElement.getAttributeValue(SwingXMLBuilder.REF_ATTRIBUTE);
            value = pBuilder.getNonVisualObject(objRef);
            if (value==null)
            {
                throw SwingXMLBuilder.createException("non non-visual object found for ref " +
                                                      objRef, pElement);
            }
        }
        else
        {
            throw SwingXMLBuilder.createException("non value for key "+pKey, pElement);
        }
        return value;
    }

    /**
     * Load a {@link ResourceBundle}.
     * @param pElement element describing the action
     * @return the loaded resource bundel, never null
     */
    private ResourceBundle createResource(final Element pElement)
    {
        ResourceBundle bundle;
        // get basename
        Attribute basenameAttribute= pElement.getAttribute(SwingXMLBuilder.BASENAME_ATTRIBUTE);
        if ( basenameAttribute == null )
            throw SwingXMLBuilder.createException("a non visual element needs a "+SwingXMLBuilder.BASENAME_ATTRIBUTE+" attribute", pElement);

        // load resourcebundle
        String basename = basenameAttribute.getValue();
        try
        {
            bundle = ResourceBundle.getBundle(basename, mBuilder.getLocale());

            // check if we should provide a back link to ourself (just in case this is a very special resource bundle class)
            //noinspection InstanceofIncompatibleInterface
            if ( bundle instanceof SwingXMLBuilder.Backlink )
            {
                ((SwingXMLBuilder.Backlink)bundle).setSwingXMLBuilder(mBuilder);
            }
        }
        catch (Exception e)
        {
            throw SwingXMLBuilder.createException("could not load resource bundle with base name "+basename, e, pElement);
        }
        return bundle;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy