View Javadoc

1   /*
2    * Copyright (c) 2014. Peter Crossley (xley.com)
3    *  Licensed to the Apache Software Foundation (ASF) under one
4    *  or more contributor license agreements.  See the NOTICE file
5    *  distributed with this work for additional information
6    *  regarding copyright ownership.  The ASF licenses this file
7    *  to you under the Apache License, Version 2.0 (the
8    *  "License"); you may not use this file except in compliance
9    *  with the License.  You may obtain a copy of the License at
10   *
11   *    http://www.apache.org/licenses/LICENSE-2.0
12   *
13   *  Unless required by applicable law or agreed to in writing,
14   *  software distributed under the License is distributed on an
15   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   *  KIND, either express or implied.  See the License for the
17   *  specific language governing permissions and limitations
18   *  under the License.
19   */
20  
21  package com.xley.lfosc.impl;
22  
23  import com.illposed.osc.OSCMessage;
24  import com.xley.lfosc.util.LogUtil;
25  
26  import java.io.BufferedReader;
27  import java.io.DataOutputStream;
28  import java.io.IOException;
29  import java.io.InputStreamReader;
30  import java.net.Socket;
31  import java.nio.charset.Charset;
32  import java.text.MessageFormat;
33  import java.util.Locale;
34  import java.util.ResourceBundle;
35  
36  /**
37   * The type OSC event protocol.
38   */
39  public class OSCProtocol implements Runnable {
40      /**
41       * The constant resources.
42       */
43      public static final ResourceBundle resources = ResourceBundle.getBundle(OSCProtocol.class.getSimpleName(),
44              Locale.getDefault());
45  
46      /**
47       * The address part of the osc event.
48       */
49      private static final int PART_ADDRESS = 2;
50      /**
51       * The command part of the osc event.
52       */
53      private static final int PART_CMD = 3;
54  
55  
56      /**
57       * THe message to process
58       */
59      private OSCMessage message;
60  
61      public OSCProtocol(OSCMessage message) {
62          this.message = message;
63      }
64  
65      @Override
66      public void run() {
67          process(this.message);
68      }
69  
70      /**
71       * Process an incoming OSC event.
72       * <br><b>Example OSC message:</b> <i>/lf/&lt;ipaddress:port&gt;/&lt;cmd&gt; arguments</i>
73       *
74       * @param message the message to be processed
75       */
76      private void process(final OSCMessage message) {
77          /**
78           * 1. parse message syntax
79           *   /lf/<ipaddress:port/<cmd> arguments
80           */
81  
82          try {
83              String[] parts = message.getAddress().split("/");
84              String[] address = parts[PART_ADDRESS].split(":");
85              String cmd = parts[PART_CMD];
86  
87              Socket clientSocket = null;
88              try {
89                  LogUtil.debug(this.getClass(), MessageFormat.format(resources.getString("osc.lf.port.connect"), address[0],
90                          address[1]));
91                  clientSocket = new Socket(address[0], Integer.parseInt(address[1]));
92                  DataOutputStream outToLF = new DataOutputStream(clientSocket.getOutputStream());
93                  BufferedReader inFromLF = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(),
94                          Charset.defaultCharset()));
95  
96                  StringBuilder send = new StringBuilder(cmd);
97                  for (Object arg : message.getArguments()) {
98                      send.append(" ").append(arg);
99                  }
100 
101                 String inputLine = null;
102                 if (clientSocket.isConnected()) {
103                     while ((inputLine = inFromLF.readLine()) != null && !inputLine.equals(">")) {
104                         LogUtil.trace(this.getClass(), " << [" + clientSocket.toString() + "] - " + inputLine);
105                     }
106 
107                     if (inputLine != null && inputLine.equals(">")) {
108                         LogUtil.trace(this.getClass(), " << [" + clientSocket.toString() + "] - " + inputLine);
109                         LogUtil.trace(this.getClass(), " >> [" + clientSocket.toString() + "] - " + send);
110                         outToLF.writeBytes(send + "\n");
111                     }
112 
113                     while ((inputLine = inFromLF.readLine()) != null) {
114                         LogUtil.trace(this.getClass(), " << [" + clientSocket.toString() + "] - " + inputLine);
115                     }
116                 }
117 
118             } catch (IOException e) {
119                 LogUtil.error(this.getClass(), resources.getString("osc.lf.error"), e);
120             } finally {
121                 if (clientSocket != null) {
122                     try {
123                         LogUtil.debug(this.getClass(), MessageFormat.format(resources.getString("osc.lf.port.close"),
124                                 address[0], address[1]));
125                         clientSocket.close();
126                     } catch (IOException e) {
127                         LogUtil.trace(this.getClass(), e);
128                     }
129                 }
130             }
131         } catch (Throwable throwable) {
132             LogUtil.error(this.getClass(), resources.getString("osc.lf.error"), throwable);
133         }
134     }
135 }