Author: kmorin Date: 2009-07-22 15:09:02 +0200 (Wed, 22 Jul 2009) New Revision: 1505 Added: trunk/guix-runtime-gwt/ trunk/guix-runtime-gwt/pom.xml trunk/guix-runtime-gwt/src/ trunk/guix-runtime-gwt/src/main/ trunk/guix-runtime-gwt/src/main/java/ trunk/guix-runtime-gwt/src/main/java/org/ trunk/guix-runtime-gwt/src/main/java/org/nuiton/ trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/ trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/ trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/ trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/DataBindingListener.java trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/DataBindingUpdateListener.java trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/GuixObject.java trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/Runtime.gwt.xml trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/Util.java trunk/guix-runtime-gwt/src/main/resources/ trunk/guix-runtime-gwt/src/test/ trunk/guix-runtime-gwt/src/test/java/ trunk/guix-runtime-gwt/src/test/java/org/ trunk/guix-runtime-gwt/src/test/java/org/nuiton/ trunk/guix-runtime-gwt/src/test/java/org/nuiton/guix/ trunk/guix-runtime-gwt/src/test/java/org/nuiton/guix/AppTest.java Log: unuseful module Property changes on: trunk/guix-runtime-gwt ___________________________________________________________________ Added: svn:ignore + target Added: trunk/guix-runtime-gwt/pom.xml =================================================================== --- trunk/guix-runtime-gwt/pom.xml (rev 0) +++ trunk/guix-runtime-gwt/pom.xml 2009-07-22 13:09:02 UTC (rev 1505) @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project> + <modelVersion>4.0.0</modelVersion> + + <!-- ************************************************************* --> + <!-- *** POM Relationships *************************************** --> + <!-- ************************************************************* --> + <parent> + <groupId>org.nuiton</groupId> + <artifactId>guix</artifactId> + <version>1.0.0-SNAPSHOT</version> + </parent> + + <groupId>org.nuiton.guix</groupId> + <artifactId>guix-runtime-gwt</artifactId> + + <dependencies> + + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + + </dependencies> + + <!-- ************************************************************* --> + <!-- *** Project Information ************************************* --> + <!-- ************************************************************* --> + <name>guix-runtime-gwt</name> + <description>Guix runtime</description> + + <!-- ************************************************************* --> + <!-- *** Build Settings ****************************************** --> + <!-- ************************************************************* --> + + <packaging>jar</packaging> + + <!-- ************************************************************* --> + <!-- *** Build Environment ************************************** --> + <!-- ************************************************************* --> + +</project> Added: trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/DataBindingListener.java =================================================================== --- trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/DataBindingListener.java (rev 0) +++ trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/DataBindingListener.java 2009-07-22 13:09:02 UTC (rev 1505) @@ -0,0 +1,42 @@ +package org.nuiton.guix.runtime.gwt; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + + +/** + * A <code>PropertyChangeListener</code> which processes a data binding when it receives a + * <code>PropertyChangeEvent</code>. + */ +public class DataBindingListener implements PropertyChangeListener { + private GuixObject object; + private String dest; + + /** + * Creates a new <code>DataBindingListener</code> which will run the given data binding + * when it receives a <code>PropertyChangeEvent</code>. + * + * @param object the object in which the data binding exists + * @param dest the name of the data binding to run + */ + public DataBindingListener(GuixObject object, String dest) { + this.object = object; + this.dest = dest; + } + + + /** + * Processes the data binding in response to a <code>PropertyChangeEvent</code>. + * + * @param e the event which triggered the binding + */ + public void propertyChange(PropertyChangeEvent e) { + object.processDataBinding(dest); + + // for now, handle dependency changes by always removing & reapplying + // the binding. We should be more efficient and only do this when it's + // actually necessary + object.removeDataBinding(dest); + object.applyDataBinding(dest); + } +} \ No newline at end of file Added: trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/DataBindingUpdateListener.java =================================================================== --- trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/DataBindingUpdateListener.java (rev 0) +++ trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/DataBindingUpdateListener.java 2009-07-22 13:09:02 UTC (rev 1505) @@ -0,0 +1,46 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package org.nuiton.guix.runtime.gwt; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + + +/** + * A <code>PropertyChangeListener</code> which removes and re-applies a data binding + * when it receives a <code>PropertyChangeEvent</code>. + */ +public class DataBindingUpdateListener implements PropertyChangeListener { + private GuixObject object; + private String dest; + + /** + * Creates a new <code>DataBindingUpdateListener</code> which will remove and re-apply a + * data binding when it receives a <code>PropertyChangeEvent</code>. + * + * @param object the object in which the data binding exists + * @param dest the name of the data binding to reapply + */ + public DataBindingUpdateListener(GuixObject object, String dest) { + this.object = object; + this.dest = dest; + } + + + public String getBindingName() { + return dest; + } + + + /** + * Updates the data binding in response to a <code>PropertyChangeEvent</code>. + * + * @param e the event which triggered the binding + */ + public void propertyChange(PropertyChangeEvent e) { + object.removeDataBinding(dest); + object.applyDataBinding(dest); + } +} \ No newline at end of file Added: trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/GuixObject.java =================================================================== --- trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/GuixObject.java (rev 0) +++ trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/GuixObject.java 2009-07-22 13:09:02 UTC (rev 1505) @@ -0,0 +1,35 @@ +package org.nuiton.guix.runtime.gwt; + +/** The <code>GuixObject</code> interface is implemented by all classes produced by the Guix compiler. */ +public interface GuixObject { + /** + * Retrieves an object defined in an XML tag by its ID. + * + * @param id the id of the component to retrieve + * @return the object + */ + //public Object getObjectById(String id); + + /** + * Pretrieves the dictonary of knwon objects indexed by their ids. + * + * @return the dictonary of objects. + */ + //public java.util.Map<String, Object> get$objectMap(); + + public void applyDataBinding(String id); + + + public void removeDataBinding(String id); + + /** + * Processes a data binding by name. Data binding names are comprised of an object ID and a property name: + * for example, the data binding in the tag <code><JLabel id='label' text='{foo.getText()}'/></code> is + * named <code>"label.text"</code>. Processing a data binding causes it to reevaluate its expression, in this + * case <code>foo.getText()</code>. + * + * @param dest the name of the data binding to run + */ + public void processDataBinding(String dest); + +} \ No newline at end of file Added: trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/Runtime.gwt.xml =================================================================== --- trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/Runtime.gwt.xml (rev 0) +++ trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/Runtime.gwt.xml 2009-07-22 13:09:02 UTC (rev 1505) @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module> + <source path="org.nuiton.guix.runtime.gwt" /> +</module> \ No newline at end of file Added: trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/Util.java =================================================================== --- trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/Util.java (rev 0) +++ trunk/guix-runtime-gwt/src/main/java/org/nuiton/guix/runtime/gwt/Util.java 2009-07-22 13:09:02 UTC (rev 1505) @@ -0,0 +1,117 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package org.nuiton.guix.runtime.gwt; + +import java.awt.Event; +import java.lang.ref.WeakReference; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EventListener; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; + +/** + * + * @author kevin + */ +public class Util { + // Maps root objects to lists of event listeners + private static Map<Object, WeakReference<List<EventListenerDescriptor>>> eventListeners = new WeakHashMap<Object, WeakReference<List<EventListenerDescriptor>>>(); + + + + private static class EventListenerDescriptor { + Class listenerClass; + String listenerMethodName; + String methodName; + Object eventListener; + } + + public static Object getEventListener(Class<? extends EventListener> listenerClass, final Object methodContainer, final String methodName) { + return getEventListener(listenerClass, null, methodContainer, methodName); + } + + + public static Object getEventListener(Class<? extends EventListener> listenerClass, final String listenerMethodName, final Object methodContainer, final String methodName) { + WeakReference<List<EventListenerDescriptor>> ref = eventListeners.get(methodContainer); + List<EventListenerDescriptor> descriptors = ref != null ? ref.get() : null; + if (descriptors == null) { + descriptors = new ArrayList<EventListenerDescriptor>(); + eventListeners.put(methodContainer, new WeakReference<List<EventListenerDescriptor>>(descriptors)); + } else { + for (EventListenerDescriptor descriptor : descriptors) { + if (listenerClass == descriptor.listenerClass && + (listenerMethodName == null ? descriptor.listenerMethodName == null : listenerMethodName.equals(descriptor.listenerMethodName)) && + methodName.equals(descriptor.methodName)) { + return descriptor.eventListener; + } + } + } + + // else we need to create a new listener + final EventListenerDescriptor descriptor = new EventListenerDescriptor(); + descriptor.listenerClass = listenerClass; + descriptor.listenerMethodName = listenerMethodName; + descriptor.methodName = methodName; + try { + final List<Method> listenerMethods = Arrays.asList(listenerClass.getMethods()); + Method listenerMethod = null; + if (listenerMethodName != null) { + for (Method listenerMethod1 : listenerMethods) { + if ((listenerMethod1).getName().equals(listenerMethodName)) { + listenerMethod = listenerMethod1; + break; + } + } + } + if (listenerMethodName != null && listenerMethod == null) { + throw new IllegalArgumentException("no method named " + listenerMethodName + " found in class " + listenerClass.getName()); + } + Class[] parameterTypes = listenerMethods.get(0).getParameterTypes(); + Class<?> methodContainerClass = methodContainer.getClass(); + final Method targetMethod = methodContainerClass.getMethod(methodName, parameterTypes); + descriptor.eventListener = Proxy.newProxyInstance(listenerClass.getClassLoader(), + new Class[]{listenerClass}, + new InvocationHandler() { + public Object invoke(Object proxy, Method method, Object[] args) { + String methodName = method.getName(); + if ((listenerMethodName == null && listenerMethods.contains(method)) || methodName.equals(listenerMethodName)) { + try { + return targetMethod.invoke(methodContainer, args); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + if (methodName.equals("toString")) { + return toString(); + } + if (methodName.equals("equals")) { + return descriptor.eventListener == args[0]; + } + if (methodName.equals("hashCode")) { + return hashCode(); + } + return null; + } + }); + descriptors.add(descriptor); + return descriptor.eventListener; + } + catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + +} Added: trunk/guix-runtime-gwt/src/test/java/org/nuiton/guix/AppTest.java =================================================================== --- trunk/guix-runtime-gwt/src/test/java/org/nuiton/guix/AppTest.java (rev 0) +++ trunk/guix-runtime-gwt/src/test/java/org/nuiton/guix/AppTest.java 2009-07-22 13:09:02 UTC (rev 1505) @@ -0,0 +1,38 @@ +package org.nuiton.guix; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +}