Thanks Dan, thats what I'm doing in the proxy. In that case I've posted
the proxy below and sample usage incase anyone needs it....
cheers,
chris
package com.swisscom.sif.esb.muse.utils;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Iterator;
import javax.xml.namespace.QName;
import org.apache.muse.core.Capability;
import org.apache.muse.ws.resource.WsResourceCapability;
import org.apache.muse.ws.resource.basefaults.BaseFault;
import
org.apache.muse.ws.resource.properties.ResourcePropertyCollection;
import
org.apache.muse.ws.resource.properties.listeners.PropertyChangeListener;
import org.w3c.dom.Element;
/**
* Proxy for setters that fires off propertychange notifications.
Required for use when
* using direct set functions.
*/
public class SetNotifier implements InvocationHandler {
/**
* Factory method to create proxys.
* @param toProxy
* @param cap
* @return a proxy
*/
public static WsResourceCapability proxy(Class toProxy,
Capability cap){
if (cap == null) {
return null;
}
Object proxy =
Proxy.newProxyInstance(cap.getClass().getClassLoader(), new
Class[]{toProxy, WsResourceCapability.class}
, new SetNotifier( (WsResourceCapability) cap
));
return (WsResourceCapability) proxy;
}
private WsResourceCapability cap = null;
private HashMap map = new HashMap();
/**
*
* @param capability
*/
public SetNotifier(WsResourceCapability capability){
cap = capability;
// get the localname properties
QName[] qnames = cap.getPropertyNames();
for (int i = 0; i < qnames.length; i++) {
QName name = qnames[i];
map.put(name.getLocalPart(), name);
}
}
/**
*
*/
private static final long serialVersionUID =
-5395290132343544558L;
private final void changeCompleted(QName qname, Element
oldValue, Element newValue)
throws BaseFault
{
Iterator i = wsrp.getChangeListeners(qname);
while (i.hasNext())
{
PropertyChangeListener listener =
(PropertyChangeListener)i.next();
listener.propertyChanged(oldValue, newValue);
}
}
private ResourcePropertyCollection wsrp = null;
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if (!method.getName().startsWith("set")) {
return method.invoke(cap, args);
}
QName qname = (QName)
map.get(method.getName().substring(3));
if (qname == null) {
// could be "setup" instead of "setFred"
return method.invoke(cap, args);
}
Element[] current = cap.getProperty(qname);
method.invoke(cap, args);
Element[] valuesXML = cap.getProperty(qname);
// now do the update
int lcd = Math.min(current.length, valuesXML.length);
wsrp = cap.getWsResource().getPropertyCollection();
for (int n = 0; n < lcd; ++n)
changeCompleted(qname, current[n], valuesXML[n]);
//
// if there were more copies before the update than after,
// we need to send deletion notifications about the extras
//
for (int n = lcd; n < current.length; ++n)
changeCompleted(qname, current[n], null);
//
// the other possibility is that there are more copies after
// the update than before, so we still have some values to
// report that are not "replacements"
//
for (int n = lcd; n < valuesXML.length; ++n)
changeCompleted(qname, null, valuesXML[n]);
return null;
}
}
sample usage:
state = (State) SetNotifier.proxy(State.class,
resource.getCapability(MuwsConstants.STATE_URI));
state.setState(new SimpleStateType(new QName[]{new
QName(RuntimeInfoCapability.NAMESPACE_URI, theState, "rinf")}));
will then fire the property change notifications.
hope it helps others
-----Original Message-----
From: Daniel Jemiolo [mailto:[EMAIL PROTECTED]
Sent: Friday, August 10, 2007 6:41 PM
To: [email protected]
Subject: Re: PropertyChange notifications - capability "setters"
This is definitely a flaw in the current WSRP code. To get the
notifications due to an internal set, you have to do this:
QName propertyName = ...
Collection<PropertyChangeListener> listeners = getPropertyCollection
().getChangeListeners(propertyName);
for (PropertyChangeListener listener : listeners)
listener.propertyChanged(propertyName, oldValue, newValue);
The wsdl2java code gen should be updated to include this code (I believe
there's a method in AbstractWsResourceCapability that could be invoked)
in all setter methods.
Dan
<[EMAIL PROTECTED]> wrote on 08/01/2007 04:58:13 PM:
> Hi All,
>
> Is there a simple way, when using a capabilities set function, to fire
> property change notifications?
>
> Currently I'm using a Proxy to wrap the actual set with notifying all
> changelisteners for a resource (on that QName). While it removes
> duplication of code I'm concerned I'm missing something simpler.
>
> cheers,
> Chris
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]