History

Added GridSolutionsFramework.sln to source control.

StephenCWills committed 14 years ago

Commit c5f7ca6No parent (first commit)915 files · +335125 −-73Browse files

Showing the changes to Source/Libraries/TSFJavaLibrary/src/org/gpa/tsf/sample/AdvancedSubscribe.java (1 of 915 files). Show all

Unified · Split

Source/Libraries/TSFJavaLibrary/src/org/gpa/tsf/sample/AdvancedSubscribe.java+453−0
@@ -0,0 +1,453 @@
1//******************************************************************************************************
2// AdvancedSubscribe.java - Gbtc
3//
4// Copyright � 2010, Grid Protection Alliance. All Rights Reserved.
5//
6// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
7// the NOTICE file distributed with this work for additional information regarding copyright ownership.
8// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
9// not use this file except in compliance with the License. You may obtain a copy of the License at:
10//
11// http://www.opensource.org/licenses/eclipse-1.0.php
12//
13// Unless agreed to in writing, the subject software distributed under the License is distributed on an
14// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
15// License for the specific language governing permissions and limitations.
16//
17// Code Modification History:
18// ----------------------------------------------------------------------------------------------------
19// 04/23/2012 - Stephen C. Wills
20// Generated original version of source code.
21//
22//******************************************************************************************************
23
24package org.gpa.tsf.sample;
25
26import java.awt.GridBagConstraints;
27import java.awt.GridBagLayout;
28import java.awt.event.ActionEvent;
29import java.awt.event.ActionListener;
30import java.io.IOException;
31import java.io.OutputStream;
32import java.io.PrintStream;
33import java.net.SocketException;
34import java.nio.ByteBuffer;
35import java.nio.charset.Charset;
36
37import javax.swing.Box;
38import javax.swing.BoxLayout;
39import javax.swing.JApplet;
40import javax.swing.JButton;
41import javax.swing.JLabel;
42import javax.swing.JScrollPane;
43import javax.swing.JTextArea;
44import javax.swing.JTextField;
45import javax.swing.SwingUtilities;
46
47import org.gpa.tsf.transport.DataSubscriber;
48import org.gpa.tsf.transport.SubscriberConnector;
49import org.gpa.tsf.transport.SubscriptionInfo;
50import org.gpa.tsf.transport.event.SubscriberConnectorListener;
51
52/**
53 * Sample applet to demonstrate the more advanced use of the subscriber API.
54 *
55 * This application accepts the hostname and port of the publisher via text
56 * fields on the applet, connects to the publisher, subscribes, and displays
57 * information about the measurements it receives. It assumes that the
58 * publisher is providing fourteen measurements (PPA:1 through PPA:14) and
59 * will retry infinitely if it has any trouble connecting. It will also
60 * automatically reconnect if the connection is terminated.
61 *
62 * Measurements are transmitted via a separate UDP data channel.
63 */
64public class AdvancedSubscribe extends JApplet
65{
66 private Object m_connectLock;
67 private ActionListener m_connectListener;
68 private ActionListener m_disconnectListener;
69
70 private JScrollPane m_outputScrollPane;
71 private JTextArea m_outputTextArea;
72 private JLabel m_hostnameLabel;
73 private JLabel m_portLabel;
74 private JTextField m_hostnameTextField;
75 private JTextField m_portTextField;
76 private JButton m_connectButton;
77 private JButton m_disconnectButton;
78 private Box m_buttonBox;
79
80 private PrintStream m_outputStream;
81 private SubscriptionInfo m_subscriptionInfo;
82 private SubscriberConnector m_connector;
83 private DataSubscriber m_subscriber;
84
85 @Override
86 public void init()
87 {
88 GridBagConstraints constraints;
89
90 super.init();
91
92 // Initialize members
93 m_connectLock = new Object();
94 m_connectListener = createConnectListener();
95 m_disconnectListener = createDisconnectListener();
96
97 m_outputTextArea = createOutputTextArea();
98 m_outputScrollPane = new JScrollPane(m_outputTextArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
99 m_hostnameLabel = new JLabel("Hostname");
100 m_portLabel = new JLabel("Port");
101 m_hostnameTextField = createHostnameTextField();
102 m_portTextField = createPortTextField();
103 m_connectButton = createConnectButton();
104 m_disconnectButton = createDisconnectButton();
105 m_buttonBox = createButtonBox();
106
107 m_outputStream = createOutputStream();
108 m_subscriptionInfo = createSubscriptionInfo();
109 m_connector = createSubscriberConnector(m_subscriptionInfo, m_outputStream);
110 m_subscriber = createSubscriber();
111
112 // Component layout
113 getContentPane().setLayout(new GridBagLayout());
114
115 constraints = new GridBagConstraints();
116 constraints.fill = GridBagConstraints.BOTH;
117 constraints.gridwidth = 2;
118 constraints.weighty = 1.0;
119 getContentPane().add(m_outputScrollPane, constraints);
120
121 constraints = new GridBagConstraints();
122 constraints.gridy = 1;
123 constraints.weightx = 0.5;
124 getContentPane().add(m_hostnameLabel, constraints);
125
126 constraints = new GridBagConstraints();
127 constraints.gridx = 1;
128 constraints.gridy = 1;
129 constraints.weightx = 0.5;
130 getContentPane().add(m_portLabel, constraints);
131
132 constraints = new GridBagConstraints();
133 constraints.fill = GridBagConstraints.HORIZONTAL;
134 constraints.gridy = 2;
135 constraints.weightx = 0.5;
136 getContentPane().add(m_hostnameTextField, constraints);
137
138 constraints = new GridBagConstraints();
139 constraints.fill = GridBagConstraints.HORIZONTAL;
140 constraints.gridx = 1;
141 constraints.gridy = 2;
142 constraints.weightx = 0.5;
143 getContentPane().add(m_portTextField, constraints);
144
145 constraints = new GridBagConstraints();
146 constraints.anchor = GridBagConstraints.CENTER;
147 constraints.gridy = 3;
148 constraints.gridwidth = 2;
149 getContentPane().add(m_buttonBox, constraints);
150 }
151
152 // Creates the action listener used to connect to the publisher.
153 private ActionListener createConnectListener()
154 {
155 return new ActionListener()
156 {
157 @Override
158 public void actionPerformed(ActionEvent arg0)
159 {
160 // Set the hostname and port before attempting to connect
161 m_connector.setHostname(m_hostnameTextField.getText());
162 m_connector.setPort(Integer.parseInt(m_portTextField.getText()));
163
164 // Connect asynchronously so we don't hog the UI thread
165 connectAsync();
166 }
167 };
168 }
169
170 // Connects and subscribes to the publisher asynchronously.
171 private void connectAsync()
172 {
173 new Thread(new Runnable()
174 {
175 @Override
176 public void run()
177 {
178 // Lock the connect lock so we don't encounter
179 // synchronization issues between calls to connectAsync
180 // and disconnectAsync
181 synchronized (m_connectLock)
182 {
183 try
184 {
185 if (m_connector.connect(m_subscriber))
186 m_subscriber.subscribe(m_subscriptionInfo);
187 }
188 catch (SocketException ex)
189 {
190 ex.printStackTrace(m_outputStream);
191 }
192 }
193 }
194 }).start();
195 }
196
197 // Creates the disconnect listener used to disconnect from the publisher.
198 private ActionListener createDisconnectListener()
199 {
200 return new ActionListener()
201 {
202 @Override
203 public void actionPerformed(ActionEvent arg0)
204 {
205 // Disconnect asynchronously so we don't hog the UI thread
206 disconnectAsync();
207 }
208 };
209 }
210
211 // Disconnects from the publisher asynchronously.
212 private void disconnectAsync()
213 {
214 new Thread(new Runnable()
215 {
216 @Override
217 public void run()
218 {
219 // Cancel the connector first so it won't try
220 // to automatically reconnect for any reason
221 m_connector.cancel();
222
223 // Lock the connect lock so we don't encounter
224 // synchronization issues between calls to connectAsync
225 // and disconnectAsync
226 synchronized (m_connectLock)
227 {
228 // Disconnect from the publisher
229 m_subscriber.disconnect();
230
231 // Create a new subscriber connector since we cancelled the old one
232 m_connector = createSubscriberConnector(m_subscriptionInfo, m_outputStream);
233 }
234 }
235 }).start();
236 }
237
238 // Creates the text area to which we send our program output.
239 private JTextArea createOutputTextArea()
240 {
241 JTextArea outputTextArea = new JTextArea();
242 outputTextArea.setEditable(false);
243 outputTextArea.setLineWrap(true);
244 outputTextArea.setWrapStyleWord(true);
245 return outputTextArea;
246 }
247
248 // Creates the text field where the user enters the hostname.
249 private JTextField createHostnameTextField()
250 {
251 JTextField hostnameTextField = new JTextField("localhost");
252 hostnameTextField.addActionListener(m_connectListener);
253 return hostnameTextField;
254 }
255
256 // Creates the text field where the user enters the port number.
257 private JTextField createPortTextField()
258 {
259 JTextField portTextField = new JTextField("6170");
260 portTextField.addActionListener(m_connectListener);
261 return portTextField;
262 }
263
264 // Creates the button used to connect to the publisher.
265 private JButton createConnectButton()
266 {
267 JButton connectButton = new JButton("Connect");
268 connectButton.addActionListener(m_connectListener);
269 return connectButton;
270 }
271
272 // Creates the button used to disconnect from the publisher.
273 private JButton createDisconnectButton()
274 {
275 JButton disconnectButton = new JButton("Disconnect");
276 disconnectButton.addActionListener(m_disconnectListener);
277 return disconnectButton;
278 }
279
280 // Creates the box that contains the connect and disconnect buttons.
281 private Box createButtonBox()
282 {
283 Box buttonBox = new Box(BoxLayout.X_AXIS);
284 buttonBox.add(m_connectButton);
285 buttonBox.add(m_disconnectButton);
286 return buttonBox;
287 }
288
289 // Creates the output stream that writes to the text area.
290 private PrintStream createOutputStream()
291 {
292 return new PrintStream(new TextAreaOutputStream(m_outputTextArea));
293 }
294
295 // SubscriptionInfo is a helper object which allows the user
296 // to set up their subscription and resuse subscription settings.
297 private SubscriptionInfo createSubscriptionInfo()
298 {
299 SubscriptionInfo info = new SubscriptionInfo();
300
301 // The following filter expression formats are also available:
302 //
303 // - Signal ID list -
304 //info.setFilterExpression("7aaf0a8f-3a4f-4c43-ab43-ed9d1e64a255;" +
305 // "93673c68-d59d-4926-b7e9-e7678f9f66b4;" +
306 // "65ac9cf6-ae33-4ece-91b6-bb79343855d5;" +
307 // "3647f729-d0ed-4f79-85ad-dae2149cd432;" +
308 // "069c5e29-f78a-46f6-9dff-c92cb4f69371;" +
309 // "25355a7b-2a9d-4ef2-99ba-4dd791461379");
310 //
311 // - Filter pattern -
312 //info.setFilterExpression("FILTER ActiveMeasurements WHERE ID LIKE 'PPA:*'");
313 //info.setFilterExpression("FILTER ActiveMeasurements WHERE Device = 'SHELBY' AND SignalType = 'FREQ'");
314
315 info.setFilterExpression("PPA:1;PPA:2;PPA:3;PPA:4;PPA:5;PPA:6;PPA:7;PPA:8;PPA:9;PPA:10;PPA:11;PPA:12;PPA:13;PPA:14");
316
317 // To set up a remotely synchronized subscription, set this flag
318 // to true and add the framesPerSecond parameter to the
319 // ExtraConnectionStringParameters. Additionally, the following
320 // example demonstrates the use of some other useful parameters
321 // when setting up remotely synchronized subscriptions.
322 //
323 //info.setRemotelySynchronized(true);
324 //info.setExtraConnectionStringParameters("framesPerSecond=30;timeResolution=10000;downsamplingMethod=Closest");
325
326 info.setRemotelySynchronized(false);
327 info.setThrottled(false);
328
329 info.setUdpDataChannel(true);
330 info.setDataChannelLocalPort(9600);
331
332 info.setTimeIncluded(true);
333 info.setLagTime(3.0);
334 info.setLeadTime(1.0);
335 info.setLocalClockAsRealTime(false);
336 info.setMillisecondResolution(true);
337
338 return info;
339 }
340
341 // SubscriberConnector is another helper object which allows the
342 // user to modify settings for auto-reconnects and retry cycles.
343 private SubscriberConnector createSubscriberConnector(SubscriptionInfo info, PrintStream outputStream)
344 {
345 SubscriberConnector connector = new SubscriberConnector();
346 SubscriberConnectorListener listener = new SampleSubscriberConnectorListener(info, outputStream);
347
348 connector.setMaxRetries(-1);
349 connector.setRetryInterval(5000);
350 connector.setAutoReconnect(true);
351 connector.addSubscriberConnectorListener(listener);
352
353 return connector;
354 }
355
356 // Creates the data subscriber.
357 private DataSubscriber createSubscriber()
358 {
359 DataSubscriber subscriber = new DataSubscriber();
360 subscriber.addSubscriberListener(new SampleSubscriberListener(m_outputStream, m_outputStream));
361 return subscriber;
362 }
363
364 private static final long serialVersionUID = -787591661184215315L;
365
366 // OutputStream that, when wrapped by a
367 // PrintStream, allows for output to a JTextArea.
368 private class TextAreaOutputStream extends OutputStream
369 {
370 private ByteBuffer m_buffer;
371 private JTextArea m_outputArea;
372
373 public TextAreaOutputStream(JTextArea outputTextArea)
374 {
375 if (outputTextArea == null)
376 throw new IllegalArgumentException("outputTextArea must not be null");
377
378 m_buffer = ByteBuffer.allocate(2000);
379 m_outputArea = outputTextArea;
380 }
381
382 @Override
383 public void flush() throws IOException
384 {
385 m_buffer.flip();
386 append(Charset.defaultCharset().decode(m_buffer).toString());
387 m_buffer = m_buffer.compact();
388 }
389
390 @Override
391 public void write(byte[] b) throws IOException
392 {
393 write(b, 0, b.length);
394 }
395
396 @Override
397 public void write(byte[] b, int off, int len) throws IOException
398 {
399 int rem = m_buffer.remaining();
400
401 if (len <= rem)
402 {
403 m_buffer.put(b, off, len);
404
405 if (m_buffer.position() >= DumpThreshold)
406 flush();
407 }
408 else
409 {
410 m_buffer.put(b, off, rem);
411 flush();
412
413 for (int i = rem; i < len; i += m_buffer.capacity())
414 {
415 rem = Math.min(m_buffer.remaining(), len - i);
416 m_buffer.put(b, off + i, rem);
417 flush();
418 }
419 }
420 }
421
422 @Override
423 public void write(int b) throws IOException
424 {
425 m_buffer.put((byte)b);
426
427 if (m_buffer.position() >= DumpThreshold)
428 flush();
429 }
430
431 private void append(final String text)
432 {
433 SwingUtilities.invokeLater(new Runnable()
434 {
435 @Override
436 public void run()
437 {
438 StringBuilder textBuilder = new StringBuilder(m_outputArea.getText());
439
440 textBuilder.append(text);
441
442 while (textBuilder.length() > CharacterLimit)
443 textBuilder.delete(0, textBuilder.indexOf(System.lineSeparator()) + 1);
444
445 m_outputArea.setText(textBuilder.toString());
446 }
447 });
448 }
449
450 private static final int DumpThreshold = 50;
451 private static final int CharacterLimit = 8192;
452 }
453}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t