diff --git a/.gitignore b/.gitignore index b64eccb..832ff84 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,7 @@ *.tli vc90.idb vc90.pdb +**/.project +**/.classpath +**/.settings/ +**/target/ \ No newline at end of file diff --git a/runtime/src/main/java/com4j/DISPNAME.java b/runtime/src/main/java/com4j/DISPNAME.java new file mode 100644 index 0000000..180cded --- /dev/null +++ b/runtime/src/main/java/com4j/DISPNAME.java @@ -0,0 +1,29 @@ +package com4j; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Dispatch NAME of the method. + * + *

+ * Java method naming convention is to use mixed case with the first letter + * lowercase, with the first letter of each internal word capitalized. The com4j + * type library importer tool therefore camelize method names if necessary. The + * information of original method name is required for COM event handling to + * find correct Java side method. So we have to annotate that information + * explicitly. + * + * @author Maximilian Gerhard (mgerhard@gk-software.com) + */ +@Retention(RUNTIME) +@Target(METHOD) +public @interface DISPNAME { + /** + * DISPNAME used by {@code EventProxy}. + */ + String value(); +} diff --git a/runtime/src/main/java/com4j/EventProxy.java b/runtime/src/main/java/com4j/EventProxy.java index a4cb08e..1859f2b 100755 --- a/runtime/src/main/java/com4j/EventProxy.java +++ b/runtime/src/main/java/com4j/EventProxy.java @@ -122,7 +122,9 @@ private static class EventInterfaceDescriptor { for (Method m : eventInterface.getDeclaredMethods()) { EventMethod em = new EventMethod(m); - methodsByName.put(m.getName(),em); + + String name = em.dispname != null ? em.dispname : m.getName(); + methodsByName.put(name, em); methodsByID.put(em.dispid,em); } } @@ -142,14 +144,19 @@ public EventMethod get(int id) { private static class EventMethod { private final int dispid; + private final String dispname; private final Method method; private final Class[] params; public EventMethod(Method m) { DISPID a = m.getAnnotation(DISPID.class); + DISPNAME b = m.getAnnotation(DISPNAME.class); if(a==null) throw new IllegalAnnotationException(m+" needs to have @DISPID"); + if (b == null) + logger.log(Level.WARNING, m + " should have @DISPNAME annotation"); dispid = a.value(); + dispname = b != null ? b.value() : null; method = m; params = m.getParameterTypes(); } @@ -163,8 +170,14 @@ public Object invoke(Object o, int flag, Variant[] args) throws Throwable { throw new ComException("Argument length mismatch. Expected "+params.length+" but found "+args.length,DISP_E_BADPARAMCOUNT); Object[] oargs = new Object[args.length]; - for( int i=0; i