1   package org.votech.plastic.managers;
2   
3   import java.io.DataInputStream;
4   import java.io.IOException;
5   import java.net.URI;
6   import java.net.URL;
7   import java.util.Collection;
8   import java.util.Iterator;
9   import java.util.List;
10  import java.util.Map;
11  
12  import org.votech.plastic.incoming.handlers.ExtendableHandler;
13  import org.votech.plastic.incoming.handlers.StandardHandler;
14  import org.votech.plastic.incoming.messages.votable.VOTableLoader;
15  import org.votech.plastic.incoming.messages.votable.VotableLoadFromUrlMessageInvoker;
16  import org.votech.plastic.managers.AbstractObservableManager.ManagerObserver;
17  import org.votech.plastic.outgoing.messages.info.EchoMessage;
18  import org.votech.plastic.outgoing.messages.info.GetDescriptionMessage;
19  
20  
21  
22  /**
23   * This class is an example application that uses the {@link org.votech.plastic.managers.PlasticConnectionManager} class
24   * to handle all things to do with Plastic.
25   * It responds only to the core Plastic Messages to do with returning name, description etc. and the loadVOTable message.
26   * When you run the main method it will attempt to connect the PlasticHub, and then execute a method
27   * that lists the currently connected Plastic applications.  Finally it will send an ECHO message to each
28   * application in turn.   The class implements two interfaces that allow it to register as a listener for Hub starting/stopping
29   * and application registering/unregistering events.  To see a simpler example see {@link org.votech.plastic.managers.SimplestExampleApplication}.
30   * @author jdt
31   * @see #sendSomeMessages()
32   * @see org.votech.plastic.managers.AbstractObservableManager.ManagerObserver
33   * @see org.votech.plastic.managers.PlasticRegistryListener
34   *
35   */
36  public class ExampleApplication implements ManagerObserver, PlasticRegistryListener {
37  
38      private static final String NAME = "Example";
39      private static final String DESCRIPTION = "An example Plastic app showing the use of the PlasticManager";
40      private static final String IVORN = "ivo://roe.ac.uk/plastic/jdt/example";
41      private static final String LOGOURL = "";
42      private PlasticConnectionManager manager;
43      private PlasticRegistry registry;
44  
45      public ExampleApplication() {
46          initPlastic();
47      }
48      /**
49       * Set up the {@link PlasticConnectionManager} that is responsible for housekeeping tasks
50       * such as keeping track of whether the hub is up or down, registering us, and responding
51       * to common informational messages.
52       *
53       */
54      private void initPlastic() {
55          //Create a message handler for the core informational messages
56          StandardHandler handler = new StandardHandler(NAME, DESCRIPTION, IVORN, LOGOURL);
57          //Create another message handler for the loadVOTable message.  This type of handler can 
58          //handle any number of different messages.
59          ExtendableHandler exhandler = new ExtendableHandler();
60          exhandler.addMessageInvoker(new VotableLoadFromUrlMessageInvoker(new VOTableLoader() {
61              //A VOTable loader is something capable of loading a votable!  In this case, our
62              //anon inner class just has a dummy method.
63              public void loadVOTable(URI sender, String id, URL url) throws Exception {
64                  System.out.println("Application "+sender+" has asked us to load a table from "+url+" and give it ID "+id);
65              }
66              
67          }));
68          //Handlers can be then chained together.  Some handlers "absorb" messages that they have dealt with, while
69          //other types of handlers such as the LoggingHandler, deal with them and pass them on to the next handler.
70          handler.appendHandler(exhandler);
71          
72          //Create the Plastic manager, tell it your name, the handler at the beginning of the chain, the fact
73          //that we don't want to connect immediately, and that should we lose the hub we want to retry to
74          //connect every 10 seconds.
75          manager = new PlasticConnectionManagerImpl(NAME, handler, false, 10000 );
76          
77          //Register ourselves as being interested in the hub starting and stopping
78          //See ManagerObserver interface
79          manager.addObserver(this);
80          
81          //Instruct the manager to connect to the hub.
82          manager.connect(); // Blocks waiting for connection.  See also manager.connectWhenReady()
83          
84          //While a PlasticConnectionManager keeps track of the hub, a PlasticRegistry keeps track of
85          //other plastic applications.
86          registry = new PlasticRegistry(manager);
87          // Register ourselves as being interested in knowing when applications register and deregister
88          registry.addListener(this);
89          
90      }
91  
92      
93      /**
94       * See who else is registered and get their metadata, if any.  
95       * Send the ECHO message to each.
96       * List all applications that understand the "getDescription" message.
97       *
98       */
99      public void sendSomeMessages() {
100         Collection apps =  registry.getPlasticApplications();
101         Iterator it = apps.iterator();
102         System.out.println("Registered applications-------");
103         while (it.hasNext()) {
104             PlasticApplication app = (PlasticApplication) it.next();
105             System.out.println("Name: "+app.getName());
106             System.out.println("Description: "+app.getDescription());
107             System.out.println("Plastic version: "+app.getPlasticVersion());
108             System.out.println("Icon URL: "+app.getIconUrl());
109             System.out.println("IVORN: "+app.getIvorn());
110             System.out.println("Plastic ID: "+app.getPlid());
111             System.out.println("Supported messages:");
112             List msgs = app.getSupportedMessageIds();
113             for (int i=0;i<msgs.size();++i) {
114                 System.out.println("\t"+msgs.get(i));
115             }
116             
117             //Send an EchoMessage to the application, and convert the returned object to the correct class.
118             //If you prefer to work with the raw message IDs, there's a method for that too.
119             final Object rawResponse = app.sendMessage(new EchoMessage("Hello World"));
120             //Most Message objects have a static convertReturn method that knows how to convert the returned Object
121             //to something more appropriate.
122             String response = EchoMessage.convertReturn(rawResponse);
123             
124             System.out.println("Sent an echo message, application returned: "+response);
125             System.out.println();
126         }
127 
128         //Broadcast a message to everyone.
129         System.out.println("Broadcasting an echo message to everyone");
130         Map responses = registry.broadcast(new EchoMessage("Goodbye cruel world"));
131         Iterator respondingappsIt = responses.keySet().iterator();
132         while (respondingappsIt.hasNext()) {
133             PlasticApplication rApp = (PlasticApplication) respondingappsIt.next();
134             System.out.println("Application "+rApp.getName()+" responded "+responses.get(rApp));
135             
136         }
137         
138         //The registry can also be used to get all the applications that support a particular message, for example
139         //the getDescription message.
140         Collection appsWithDescription = registry.getPlasticApplications(new GetDescriptionMessage().getURI());
141         Iterator it2 = appsWithDescription.iterator();
142         System.out.println("The following applications support the getDescription message");
143         while (it2.hasNext()) {
144             PlasticApplication app = (PlasticApplication) it2.next();
145             System.out.println(app.getName());
146         }
147     }
148 
149     
150     /**
151      * Called when the hub goes down
152      * @see org.votech.plastic.managers.AbstractObservableManager.ManagerObserver
153      */
154     public void down() {
155         System.out.println("The hub has gone down - exiting");
156         System.exit(0);
157     }
158     /**
159      * Called when the hub comes up
160      * @see org.votech.plastic.managers.AbstractObservableManager.ManagerObserver
161      */
162     public void up() {
163         System.out.println("The hub is up");
164         System.out.println("This hub's ID is "+manager.getHub().getHubId());
165         System.out.println("My ID is "+ manager.getId());
166     }
167 
168     /**
169      * Called when an application registers or unregisters.
170      * @see PlasticRegistryListener
171      */
172     public void applicationsChanged() {
173         System.out.println("An application has registered/deregistered");
174         
175     }
176 
177     /**
178      * Run me.
179      * @param args
180      * @throws IOException
181      */
182     public static void main(String[] args) throws IOException {
183         
184         ExampleApplication app = new ExampleApplication();
185         
186         
187         //Wait for the user to hit return
188         final DataInputStream dataInputStream = new DataInputStream(System.in);
189         while (true) {
190             app.sendSomeMessages();
191             System.out.println("Hit return to go again, type q to exit");
192             String stop = dataInputStream.readLine();
193             if ("q".equalsIgnoreCase(stop)) System.exit(0);
194         }
195     }
196 }