Package org.jbpm.wire.binding

Source Code of org.jbpm.wire.binding.SubscribeBinding

/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jbpm.wire.binding;

import java.util.List;

import org.jbpm.util.Listener;
import org.jbpm.wire.WireContext;
import org.jbpm.wire.descriptor.ArgDescriptor;
import org.jbpm.wire.operation.SubscribeOperation;
import org.jbpm.wire.xml.WireParser;
import org.jbpm.xml.Binding;
import org.jbpm.xml.Parse;
import org.jbpm.xml.Parser;
import org.jbpm.xml.XmlUtil;
import org.w3c.dom.Element;

/**
* <p>This {@link Binding} specifies a {@link SubscribeOperation} (subscription to an Observable object).</p>
*
* <h3>XML declaration</h3>
* <p>A subscription is defined by a <b><code>{@literal <subscribe>}</code></b> xml element.</p>
*
* <h4>Context attribute</h4>
* <p>This element can have a "context" attribute.
* The value of this attribute should be the name of a {@link WireContext} in the object's environment.
* This WireContext will be used to find the Observable to listen.
* If this attribute is not present, the object's WireContext will be used.</p>
*
* <h4>Event attribute</h4>
* <p>This element can have a "event" or "events" attribute.
* The value of this attribute specifies the list of events name that should be observed.
* Other events are filtered. If this attribute if not present, all events are observed.</p>
*
* <h4>Object attribute</h4>
* <p>This element can have a "object" or "objects" attribute.
* The value of this attribute specifies the list of objects that should be observed.
* If this attribute if not present, the WireContext specified by the "context" attribute is observed.</p>
*
* <h4>To attribute</h4>
* <p>This element can have a "to" attribute. If this attribute is set to "wire-events", the object will listen to the events fired by the descriptor of the target object. Otherwise, it will listen to the events fired by the target object (which must be an instance of Observable).</p>
*
* <h4>Method attribute</h4>
* <p>This element can have a "method" attribute.</p>
* <p>If this attribute is not present, this operation must be applied to a {@link Listener} object.</p>
* <p>If this attribute is present, the specified method will be invoked each time the specified events are received.
* Arguments given to the method invocation are specified in the &lt;arg&gt; child elements of the &lt;subscribe&gt; element.
* For more information on how to declare arguments, see {@link ArgDescriptor}.</p>
*
* <h3>Examples</h3>
*
* <h4>Observing a WireContext</h4>
* <pre> &lt;objects&gt;
*   &lt;object name='o' class='Listener'&gt;
*     &lt;subscribe context='contextName' /&gt;
*   &lt;/object&gt;
* &lt;/objects&gt;</pre>
*
* In this example, the object 'o' will observe all events of the WireContext named 'contextName'.
*
* <h4>Observing objects.</h4>
* <pre> &lt;objects&gt;
*   &lt;object name='l' class='Listener'&gt;
*     &lt;subscribe objects='a, c' /&gt;
*   &lt;/object&gt;
*   &lt;object name='a' class='Observable' /&gt;
*   &lt;object name='b' class='Observable' /&gt;
*   &lt;object name='c' class='Observable' /&gt;
* &lt;/objects&gt;</pre>
*
* In this example, the object 'l' will observe all events from 'a' and 'c', but not events fired by 'b'.
*
* <h4>Observing events.</h4>
* <pre> &lt;objects&gt;
*   &lt;object name='l' class='Listener'&gt;
*     &lt;subscribe object='a' event='start'/&gt;
*   &lt;/object&gt;
*   &lt;object name='a' class='Observable' /&gt;
* &lt;/objects&gt;</pre>
*
* In this example, the object 'l' will observe the 'start' event from 'a',
* but not other events (for example a 'stop' event won't be observed).
*
* <h4>Invoking a method on event reception</h4>
*
* Consider the following class:
* <pre> public class Foo {
*   void logEvent(String name) {
*    System.out.println("Object " + name  + " sent an event.");
*   }
* }</pre>
*
* With the following definition:
* <pre> &lt;objects&gt;
*   &lt;object name='l' class='Foo'&gt;
*     &lt;subscribe object='a' method='logEvent' &gt;
*        &lt;arg&gt;
*          &lt;string value='a'/&gt;
*        &lt;/arg&gt;
*     &lt;/subscribe&gt;
*     &lt;subscribe object='b' method='logEvent' &gt;
*        &lt;arg&gt;
*          &lt;string value='b'/&gt;
*        &lt;/arg&gt;
*     &lt;/subscribe&gt;
*   &lt;/object&gt;
*   &lt;object name='a' class='Observable' /&gt;
*   &lt;object name='b' class='Observable' /&gt;
* &lt;/objects&gt;</pre>
*
* When 'a' fires an event, <code>logEvent("a")</code> will be invoked;
* when 'b' fires an event, <code>logEvent("b")</code> will be invoked.
*
* @author Tom Baeyens
* @author Guillaume Porcher (documentation)
*
*/
public class SubscribeBinding implements Binding {

  public Object parse(Element element, Parse parse, Parser parser) {
    SubscribeOperation subscribeOperation = new SubscribeOperation();

    // these are the different ways of specifying observables:
    // <subscribe [context='contextName'] [event(s)='...']... /> will use the context as the observable
    // <subscribe [context='contextName'] object(s)='objectName' [event(s)='...'] ... /> will use the object(s) with the given name in the specified context
    // <subscribe [context='contextName'] to='wire-events' event(s)='...' [object(s)='...'] ... /> will listen to wire events of a specific object in the specified context

    // context
    String contextName = XmlUtil.attribute(element, "context");
    subscribeOperation.setContextName(contextName);

    // to
    String to = XmlUtil.attribute(element, "to");
    if ("wire-events".equalsIgnoreCase(to)) {
      subscribeOperation.setWireEvents(true);
    }

    // events
    List<String> eventNames = XmlUtil.parseList(element, "event");
    subscribeOperation.setEventNames(eventNames);

    // objects
    List<String> objectNames = XmlUtil.parseList(element, "object");
    subscribeOperation.setObjectNames(objectNames);

    // method & args
    String methodName = XmlUtil.attribute(element, "method");
    subscribeOperation.setMethodName(methodName);
    List<Element> argElements = XmlUtil.elements(element, "arg");
    WireParser wireParser = (WireParser) parser;
    List<ArgDescriptor> argDescriptors = wireParser.parseArgs(argElements, parse);
    subscribeOperation.setArgDescriptors(argDescriptors);

   return subscribeOperation;
  }
}
TOP

Related Classes of org.jbpm.wire.binding.SubscribeBinding

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.