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]

Reply via email to