1 package org.xvsm.remote;
2
3 import java.net.URI;
4 import java.util.HashMap;
5 import java.util.StringTokenizer;
6
7 import org.xvsm.configuration.ConfigurationManager;
8 import org.xvsm.core.Entry;
9 import org.xvsm.core.VirtualAnswerContainer;
10 import org.xvsm.internal.EventProcessingPool;
11 import org.xvsm.internal.exceptions.FatalException;
12 import org.xvsm.internal.exceptions.XCoreRemoteException;
13 import org.xvsm.internal.tasks.OperationTask;
14 import org.xvsm.internal.tasks.Task;
15 import org.xvsm.remote.interfaces.IMarshaller;
16 import org.xvsm.remote.interfaces.ITransportListener;
17 import org.xvsm.remote.interfaces.ITransportSender;
18
19 /***
20 * @author Christian Schreiber, Michael Proestler
21 *
22 */
23 public final class TransportHandler {
24
25 /***
26 * A HashMap containing an ITransportSender for a given protocol String.
27 */
28 private HashMap<String, ITransportSender<?>> senders = new HashMap<String, ITransportSender<?>>();
29
30 /***
31 * Contains all currently running listener.
32 */
33 private HashMap<String, ITransportListener<?>> listeners = new HashMap<String, ITransportListener<?>>();
34
35 /***
36 * Indicates if the TransportHandler has already been initialized.
37 */
38 private boolean initialized = false;
39
40 /***
41 * /** Instance of the TransportHandler.
42 */
43 private static TransportHandler handlerInstance = null;
44
45 /***
46 * Get the singleton instance of the TransportHandler.
47 *
48 * @return an instance of the TransportHandler.
49 */
50 public synchronized static TransportHandler getInstance() {
51 if (handlerInstance == null) {
52 handlerInstance = new TransportHandler();
53 }
54 return handlerInstance;
55 }
56
57 /***
58 * Default constructor.
59 *
60 */
61 private TransportHandler() {
62
63 }
64
65 /***
66 * Calls {@link ITransportListener#stop()} on all running TransportListener.
67 *
68 */
69 public void shutdown() {
70 for (ITransportListener<?> listener : this.listeners.values()) {
71 listener.stop();
72 }
73 this.listeners.clear();
74 this.initialized = false;
75 handlerInstance = null;
76 }
77
78 /***
79 * Initialize the TransportHandler if needed.
80 */
81 @SuppressWarnings("unchecked")
82 public synchronized void init() {
83 if (this.initialized) {
84 return;
85 }
86 ConfigurationManager cm = ConfigurationManager.getInstance();
87 if (!cm.getBooleanSetting("EnableRemoteAccess")) {
88 this.initialized = true;
89 } else {
90 String protocols = cm.getStringSetting("RemoteProtocols");
91 StringTokenizer tokenizer = new StringTokenizer(protocols, "|");
92 while (tokenizer.hasMoreTokens()) {
93 String protocol = tokenizer.nextToken();
94
95 String uriString = cm.getStringSetting(protocol + ".uri");
96 String senderclass = cm.getStringSetting(protocol + ".sender");
97 String listenerclass = cm.getStringSetting(protocol
98 + ".listener");
99 String marshallerclass = cm.getStringSetting(protocol
100 + ".marshaller");
101
102 try {
103 ITransportListener listener = (ITransportListener) Class
104 .forName(listenerclass).newInstance();
105
106 ITransportSender sender = null;
107 if (listener instanceof ITransportSender) {
108 sender = (ITransportSender) listener;
109 } else {
110 sender = (ITransportSender) Class.forName(senderclass)
111 .newInstance();
112 }
113
114 IMarshaller marshaller = (IMarshaller) Class.forName(
115 marshallerclass).newInstance();
116
117 listener.setURI(new URI(uriString));
118
119 listener.setMarshaller(marshaller);
120 sender.setMarshaller(marshaller);
121 this.senders.put(protocol.toLowerCase(), sender);
122 this.startListener(protocol.toLowerCase(), listener);
123 } catch (Exception e) {
124 throw new FatalException(e);
125 }
126 }
127 this.initialized = true;
128 }
129 }
130
131 /***
132 * Starts a ITransportListener.
133 *
134 * @param listener
135 * the listener that should be started.
136 */
137 private void startListener(String protocol, ITransportListener<?> listener) {
138 this.listeners.put(protocol.toLowerCase(), listener);
139 new Thread(listener).start();
140 }
141
142 /***
143 * Processes a new Task.
144 *
145 * @param task
146 * the task, which should be fulfilled.
147 */
148 public void processTask(Task task) {
149 if (task instanceof OperationTask) {
150 URI answerToContainer = ((OperationTask) task).getCref().asURI();
151
152 VirtualAnswerContainer c = null;
153 if ((c = VirtualAnswerContainer.getInstance(answerToContainer)) != null) {
154 c.writeAnswer(((OperationTask) task).getEntries().toArray(
155 new Entry[0]), answerToContainer);
156 return;
157 }
158 }
159 EventProcessingPool.getInstance().execute(task);
160 }
161
162 /***
163 * Sends a task to an uri.
164 *
165 * @param uri
166 * the uri to send the task to.
167 * @param task
168 * the task, which should be send.
169 * @throws XCoreRemoteException
170 */
171 @SuppressWarnings("unchecked")
172 public void send(URI uri, Task task) throws XCoreRemoteException {
173 ITransportSender sender = this.getSender(uri);
174 if (sender == null) {
175 throw new FatalException("Can't find a sender for: "
176 + uri.getScheme().toLowerCase());
177 }
178 sender.sendRequest(uri, task);
179 }
180
181 /***
182 * Get the ITransportSender that is registered to the given URI.
183 *
184 * @param uri
185 * the URI where the Sender belongs to.
186 * @return the ITransportSender that is registered to the URI.
187 */
188 @SuppressWarnings("unchecked")
189 public ITransportSender getSender(URI uri) {
190 return this.senders.get(uri.getScheme().toLowerCase());
191 }
192
193 /***
194 * Get the ITransportListener that is registered to the given URI.
195 *
196 * @param protocol
197 * the protocol where the Listener belongs to.
198 * @return the ITransportSender that is registered to the URI.
199 */
200 @SuppressWarnings("unchecked")
201 public ITransportListener getListener(String protocol) {
202 return this.listeners.get(protocol.toLowerCase());
203 }
204 }