1 | package com.example.SocketTest.client;
|
---|
2 |
|
---|
3 | import org.nbk4.gwt.action.client.ActionObject;
|
---|
4 | import org.nbk4.gwt.action.client.ActionProperty;
|
---|
5 | import org.nbk4.gwt.action.client.ActionRequest;
|
---|
6 | import org.nbk4.gwt.action.client.ActionType;
|
---|
7 |
|
---|
8 | import com.github.nmorel.gwtjackson.client.ObjectReader;
|
---|
9 | import com.github.nmorel.gwtjackson.client.ObjectWriter;
|
---|
10 | import com.google.gwt.core.client.EntryPoint;
|
---|
11 | import com.google.gwt.core.client.GWT;
|
---|
12 | import com.google.gwt.safehtml.shared.SafeHtml;
|
---|
13 | import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
|
---|
14 | import com.google.gwt.user.client.ui.RootPanel;
|
---|
15 | import com.sencha.gxt.core.client.util.Margins;
|
---|
16 | import com.sencha.gxt.widget.core.client.ContentPanel;
|
---|
17 | import com.sencha.gxt.widget.core.client.ProgressBar;
|
---|
18 | import com.sencha.gxt.widget.core.client.box.AlertMessageBox;
|
---|
19 | import com.sencha.gxt.widget.core.client.button.TextButton;
|
---|
20 | import com.sencha.gxt.widget.core.client.container.CenterLayoutContainer;
|
---|
21 | import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer;
|
---|
22 | import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData;
|
---|
23 | import com.sencha.gxt.widget.core.client.container.Viewport;
|
---|
24 | import com.sencha.gxt.widget.core.client.event.SelectEvent;
|
---|
25 | import com.sencha.gxt.widget.core.client.event.SelectEvent.SelectHandler;
|
---|
26 | import com.sencha.gxt.widget.core.client.form.FieldLabel;
|
---|
27 | import com.sencha.gxt.widget.core.client.form.IntegerField;
|
---|
28 | import com.sencha.gxt.widget.core.client.form.TextField;
|
---|
29 | import com.sksamuel.gwt.websockets.*;
|
---|
30 |
|
---|
31 | /**
|
---|
32 | * Entry point classes define <code>onModuleLoad()</code>.
|
---|
33 | */
|
---|
34 | public class TestGXTSockets implements EntryPoint {
|
---|
35 |
|
---|
36 | private ContentPanel contentPanel = new ContentPanel();
|
---|
37 | private CenterLayoutContainer centerLayout = new CenterLayoutContainer();
|
---|
38 | private VerticalLayoutContainer layoutSeperationBox = new VerticalLayoutContainer();
|
---|
39 |
|
---|
40 | private TextButton textButton = new TextButton("Process File");
|
---|
41 |
|
---|
42 | private IntegerField byteCountField = new IntegerField();
|
---|
43 | private IntegerField chunkSizeField = new IntegerField();
|
---|
44 | private TextField locationField = new TextField();
|
---|
45 |
|
---|
46 | private ProgressBar progressBar = new ProgressBar();
|
---|
47 |
|
---|
48 | private FieldLabel locationFieldLabel;
|
---|
49 | private FieldLabel byteSizeFieldLabel;
|
---|
50 | private FieldLabel chunkSizeFieldLabel;
|
---|
51 |
|
---|
52 | private Viewport viewport = new Viewport();
|
---|
53 | private Websocket socket;
|
---|
54 |
|
---|
55 | public static interface ActionRequestWriter extends ObjectWriter<ActionRequest> {}
|
---|
56 | public static interface ActionObjectReader extends ObjectReader<ActionObject> {}
|
---|
57 |
|
---|
58 | private ActionRequestWriter writer;
|
---|
59 | private ActionObjectReader reader;
|
---|
60 | /**
|
---|
61 | * This is the entry point method.
|
---|
62 | */
|
---|
63 | public void onModuleLoad() {
|
---|
64 | writer = GWT.create( ActionRequestWriter.class );
|
---|
65 | reader = GWT.create( ActionObjectReader .class );
|
---|
66 |
|
---|
67 | //DEFINE AND ADD FIELDS
|
---|
68 | locationField.setValue("/home/nbk4/Dummy Files/index.zip");
|
---|
69 | locationFieldLabel = new FieldLabel(locationField, "Copy Location");
|
---|
70 | layoutSeperationBox.add(locationFieldLabel, new VerticalLayoutData(1, -1));
|
---|
71 |
|
---|
72 | byteCountField.setValue(16);
|
---|
73 | byteSizeFieldLabel = new FieldLabel(byteCountField, "Kilobytes to Copy");
|
---|
74 | layoutSeperationBox.add(byteSizeFieldLabel , new VerticalLayoutData(1, -1));
|
---|
75 |
|
---|
76 | chunkSizeField.setValue(1024);
|
---|
77 | chunkSizeFieldLabel = new FieldLabel(chunkSizeField, "Buffer Size (bytes)");
|
---|
78 | layoutSeperationBox.add(chunkSizeFieldLabel, new VerticalLayoutData(1, -1));
|
---|
79 |
|
---|
80 | layoutSeperationBox.add(textButton, new VerticalLayoutData(1, -1));
|
---|
81 | layoutSeperationBox.add(progressBar, new VerticalLayoutData(1, -1, new Margins(3, 0, 0, 0)));
|
---|
82 |
|
---|
83 | contentPanel.add(centerLayout);
|
---|
84 | centerLayout.add(layoutSeperationBox);
|
---|
85 |
|
---|
86 | viewport.add(contentPanel);
|
---|
87 | //GXT Stuff
|
---|
88 |
|
---|
89 | RootPanel.get().add(viewport);
|
---|
90 |
|
---|
91 | //TODO: actually properly manage an address
|
---|
92 | socket = getWebSocket("ws://localhost:8080/GWTTomcatSocketServer/IOtask");
|
---|
93 |
|
---|
94 | socket.open();
|
---|
95 |
|
---|
96 | textButton.addSelectHandler(new SelectHandler() {
|
---|
97 | @Override
|
---|
98 | public void onSelect(SelectEvent event) {
|
---|
99 | getRequestMessage();
|
---|
100 | }
|
---|
101 | });
|
---|
102 | }
|
---|
103 |
|
---|
104 | private Websocket getWebSocket(String address) {
|
---|
105 | Websocket socket = new Websocket(address);
|
---|
106 | socket.addListener(new myWebSocketListener());
|
---|
107 | return socket;
|
---|
108 | }
|
---|
109 |
|
---|
110 | private class myWebSocketListener implements WebsocketListener {
|
---|
111 | @Override
|
---|
112 | public void onClose(CloseEvent event) {
|
---|
113 | }
|
---|
114 | @Override
|
---|
115 | public void onMessage(String response) {
|
---|
116 | // do something with the data transmission
|
---|
117 | handleOnMessage(response);
|
---|
118 | }
|
---|
119 | @Override
|
---|
120 | public void onOpen() {
|
---|
121 | }
|
---|
122 | }
|
---|
123 |
|
---|
124 | private void handleOnMessage(final String JSON) {
|
---|
125 | //it seems tomcat sends this string on establishing a websocket connection, can't figure out why
|
---|
126 | if(JSON.equals("Connection Established")) {
|
---|
127 | return;//do nothing
|
---|
128 | }
|
---|
129 | try {
|
---|
130 | ActionObject object = reader.read(JSON);
|
---|
131 | handleActionObject(object);
|
---|
132 | } catch (Exception e) {
|
---|
133 | alertMessage("Invalid message recieved from server", e.toString());
|
---|
134 | }
|
---|
135 | }
|
---|
136 |
|
---|
137 | long lastProgressBarUpdateId = -1;
|
---|
138 |
|
---|
139 | /**Define behaviors for actions here: expand the list of properties as needed to match additions to the framework */
|
---|
140 | private void handleActionObject(ActionObject actionObject) {
|
---|
141 |
|
---|
142 | long actionObjectID = actionObject.actionID;
|
---|
143 |
|
---|
144 | if(actionObject.actionType == ActionType.UPDATE_PROGRESSBAR && actionObject.actionID > lastProgressBarUpdateId) {
|
---|
145 | lastProgressBarUpdateId = actionObject.actionID;
|
---|
146 |
|
---|
147 | for(ActionProperty property : actionObject.properties) {
|
---|
148 | switch (property.property) {
|
---|
149 |
|
---|
150 | /**Update progress bar progress*/
|
---|
151 | case PROGRESS_BAR_PROGRESS : progressBar.setValue(Double.parseDouble(property.label)); break;
|
---|
152 |
|
---|
153 | /**Update progress bar message*/
|
---|
154 | case PROGRESS_BAR_STRING : progressBar.updateText(property.label); break;
|
---|
155 | default : {
|
---|
156 | String title = "ERROR: INVALID PROPERTY";
|
---|
157 | String text = "The supplied property '" + property.property + "' is either invalid,"
|
---|
158 | + "or is not compatible with the supplied action type ('UPDATE_PROGRESSBAR')";
|
---|
159 | alertMessage(title, text);
|
---|
160 | break;
|
---|
161 | }
|
---|
162 | }
|
---|
163 | }
|
---|
164 | }
|
---|
165 | else if (actionObject.actionType == ActionType.SHOW_DIALOG || actionObject.actionType == ActionType.SHOW_DIALOG_NORESPONSE) {
|
---|
166 | AlertMessageBox self = new AlertMessageBox("[missing resource]", "[missing resource]");
|
---|
167 | boolean sendResponse = actionObject.actionType == ActionType.SHOW_DIALOG;
|
---|
168 | self.setPredefinedButtons();
|
---|
169 |
|
---|
170 | for(ActionProperty property : actionObject.properties) {
|
---|
171 | int propertyID = property.ID;
|
---|
172 | switch (property.property) {
|
---|
173 | /**Update the messagebox window heading*/
|
---|
174 | case MESSAGE_WINDOW_TITLE : self.setHeading(property.label); break;
|
---|
175 |
|
---|
176 | /**Update the messagebox window text*/
|
---|
177 | case MESSAGE_WINDOW_TEXT : self.setMessage(property.label); break;
|
---|
178 |
|
---|
179 | /**Add a specified button to the messagebox window: sendResponse defines whether a response will be sent*/
|
---|
180 | case BUTTON : {
|
---|
181 | TextButton button =
|
---|
182 | new TextButton(property.label, new MyButtonSelectHandler(self, actionObjectID, propertyID, sendResponse));
|
---|
183 | self.addButton(button);
|
---|
184 | break;
|
---|
185 | }
|
---|
186 |
|
---|
187 | /**Update progress bar progress*/
|
---|
188 | case PROGRESS_BAR_PROGRESS : progressBar.updateProgress(Double.parseDouble(property.label), null); break;
|
---|
189 |
|
---|
190 | /**Update progress bar message*/
|
---|
191 | case PROGRESS_BAR_STRING : progressBar.updateText(property.label); break;
|
---|
192 |
|
---|
193 | default : {
|
---|
194 | String title = "ERROR: INVALID PROPERTY";
|
---|
195 | String text = "The supplied property '" + property.property + "' is either invalid,"
|
---|
196 | + "or is not compatible with the supplied action type ('SHOW_DIALOG')";
|
---|
197 | alertMessage(title, text);
|
---|
198 | break;
|
---|
199 | }
|
---|
200 | }
|
---|
201 | }
|
---|
202 |
|
---|
203 | self.setWidth(500);
|
---|
204 | self.setMinButtonWidth(40);
|
---|
205 | self.getButtonBar().forceLayout();
|
---|
206 | self.show();
|
---|
207 | self.getButtonBar().forceLayout();
|
---|
208 | }
|
---|
209 | }
|
---|
210 |
|
---|
211 | private void alertMessage(String title, String text) {
|
---|
212 | AlertMessageBox amb = new AlertMessageBox(StringToHTML(title), StringToHTML(text));
|
---|
213 | amb.show();
|
---|
214 | }
|
---|
215 |
|
---|
216 | private SafeHtml StringToHTML(String input) {
|
---|
217 | SafeHtmlBuilder builder = new SafeHtmlBuilder();
|
---|
218 | builder.appendEscapedLines(input);
|
---|
219 | return builder.toSafeHtml();
|
---|
220 | }
|
---|
221 |
|
---|
222 | private class MyButtonSelectHandler implements SelectHandler {
|
---|
223 | AlertMessageBox self;
|
---|
224 | long selfID;
|
---|
225 | int buttonID;
|
---|
226 | boolean sendResponse;
|
---|
227 | public MyButtonSelectHandler(AlertMessageBox self, long selfID, int buttonID, boolean sendResponse) {
|
---|
228 | this.self = self;
|
---|
229 | this.selfID = selfID;
|
---|
230 | this.buttonID = buttonID;
|
---|
231 | this.sendResponse = sendResponse;
|
---|
232 | }
|
---|
233 |
|
---|
234 | @Override
|
---|
235 | public void onSelect(SelectEvent event) {
|
---|
236 | self.hide();
|
---|
237 |
|
---|
238 | if(sendResponse) {
|
---|
239 | ActionRequest AR = RequestObjectBuilder.GenerateResponseRequest(buttonID, selfID);
|
---|
240 | String JSON = writer.write(AR);
|
---|
241 | socket.send(JSON);
|
---|
242 | }
|
---|
243 | }
|
---|
244 |
|
---|
245 | @SuppressWarnings("unused")
|
---|
246 | public int getButtonID() {
|
---|
247 | return buttonID;
|
---|
248 | }
|
---|
249 |
|
---|
250 |
|
---|
251 | @SuppressWarnings("unused")
|
---|
252 | public long getSelfID() {
|
---|
253 | return selfID;
|
---|
254 | }
|
---|
255 | }
|
---|
256 |
|
---|
257 | private void getRequestMessage() {
|
---|
258 | //TODO: convert chunk/totalSize to long
|
---|
259 | int chunkSize = Math.max(chunkSizeField.getValue(), 1);
|
---|
260 | String location = locationField.getValue();
|
---|
261 | int totalSize = Math.max(byteCountField.getValue() * 1024, 0); //allow zero here to emulate zero size files
|
---|
262 |
|
---|
263 | ActionRequest AR = RequestObjectBuilder.GenerateProcessFileRequest(chunkSize, totalSize, location);
|
---|
264 |
|
---|
265 | String JSON = writer.write(AR);
|
---|
266 | socket.send(JSON);
|
---|
267 | }
|
---|
268 | }
|
---|