Package dk.brics.jwig

Source Code of dk.brics.jwig.EventHandler

package dk.brics.jwig;

import dk.brics.jwig.server.ParamNameGetter;
import dk.brics.xact.XML;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;

/**
* Handler for HTML events.
* <p>
* A plain handler has a void <code>run</code> method that is invoked when the event occurs.
* <p>
* The <code>run</code> method for a handler that has been constructed with a session argument returns
* an XML value. This XML value can be obtained from an XML producer via {@link #getProducer()}.
* <p>
* The <code>run</code> methods may take parameters corresponding to form field values.
*/
@Regenerable
abstract public class EventHandler extends AbstractHandler {

    private static ParamNameGetter paramnamegetter = new ParamNameGetter();

    private String[] fields;

    private final boolean value;

    private XMLProducer producer;

    /**
     * Stores results for event handlers that return XML.
     * Uses a static map and event handler hash codes to allow regeneration of the handler objects.
     */
    private static Map<Session, Map<Integer, XML>> return_values = new WeakHashMap<Session, Map<Integer, XML>>();

    private Session ses;

    /**
     * Constructs a new event handler.
     */
    public EventHandler(Object... dependencies) {
        this(false, dependencies);
    }

    /**
     * Constructs a new event handler with a JavaScript boolean value.
     */
    public EventHandler(boolean value,Object... dependencies) {
        this(value, null,dependencies);
    }

    /**
     * Constructs a new event handler with a JavaScript boolean value and a session.
     */
    public EventHandler(boolean value, Session ses,Object... dependencies) {
        super(dependencies);
        setFields();
        this.value = value;
        this.ses = ses;
    }

    /**
     * Constructs a new event handler with a session.
     */
    public EventHandler(Session ses) {
        this(false, ses, new Object[0]); //array argument appears to fix what seems to be a Java 7 javac bug
    }

    private void setFields() {
        for (Method m : getClass().getDeclaredMethods()) {
            if (m.getName().equals("run")) {
                fields = paramnamegetter.getParameterNames(m);
                break;
            }
        }
        if (fields == null) {
            throw new JWIGException("'run' method not found in event handler");
        }
    }

    /**
     * Returns the JavaScript instruction for running this event handler.
     * The instruction results in the boolean value set by the event handler constructor.
     */
    @Override
    public final String getHandlerIdentifier() {
        return "jwig.sendFields('" + super.getHandlerIdentifier() + "'," + toJavaScriptArray(fields) + ");return " + value;
    }

    private static String toJavaScriptArray(String[] strings) {
        StringBuilder b = new StringBuilder();
        b.append('[');
        boolean first = true;
        for (String string : strings) {
            if (first) {
                first = false;
            } else {
                b.append(',');
            }
            b.append('\'').append(string).append('\'');
        }
        b.append(']');
        return b.toString();
    }

    /**
     * Creates an XML producer for this event handler.
     */
    public XMLProducer getProducer() {
        if (producer == null) {
            producer = new XMLProducer() {
                XML run() {
                    return getXMLValue(ses);
                }
            };
        }
        return producer;
    }

    private XML getXMLValue(Session ses) {
        Map<Integer, XML> map = getMap(ses);
        XML def = XML.parseTemplate("");
    XML xml = map.get(this.hashCode());
    if (xml == null) {
        xml = def;
    }
    return xml;
    }

    private Map<Integer, XML> getMap(Session ses) {
        Map<Integer, XML> map = return_values.get(ses);
        if (map == null) {
            map = new HashMap<Integer, XML>();
            return_values.put(ses, map);
        }
        return map;
    }

    /**
     * Invoked by the runtime system after the <code>run</code> method has been invoked
     * to store the resulting XML value for the XML producer, and then notifies
     * listeners of the XML producer.
     */
    public void setLatestReturnValue(XML val) {
        if (ses == null || producer == null) {
            return;
        }
        XML latest = getXMLValue(ses);
        if (!latest.equals(val)) {
            if (val == null) {
                getMap(ses).remove(this.hashCode());
            } else {
                getMap(ses).put(this.hashCode(),val);
            }
            producer.update();
        }
    }
}
TOP

Related Classes of dk.brics.jwig.EventHandler

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.