View Javadoc

1   /**
2    * 
3    */
4   package org.ximtec.igesture.tool.view.devicemanager.discoveryservice;
5   
6   import java.io.FileInputStream;
7   import java.io.IOException;
8   import java.lang.reflect.Constructor;
9   import java.lang.reflect.InvocationTargetException;
10  import java.util.ArrayList;
11  import java.util.HashMap;
12  import java.util.HashSet;
13  import java.util.Map;
14  import java.util.Properties;
15  import java.util.Set;
16  import java.util.logging.Level;
17  import java.util.logging.Logger;
18  
19  import org.sigtec.util.Constant;
20  import org.w3c.dom.Node;
21  import org.w3c.dom.NodeList;
22  import org.ximtec.igesture.io.AbstractGestureDevice;
23  import org.ximtec.igesture.io.DeviceDiscoveryService;
24  import org.ximtec.igesture.io.tuio.TuioConstants;
25  import org.ximtec.igesture.tool.GestureConstants;
26  import org.ximtec.igesture.tool.view.Property;
27  import org.ximtec.igesture.util.XMLParser;
28  
29  /**
30   * @author Bjorn Puype, bpuype@gmail.com
31   * 
32   */
33  public abstract class AbstractTuioDeviceDiscoveryService implements
34  		DeviceDiscoveryService {
35  
36  	private static final Logger LOGGER = Logger
37  			.getLogger(AbstractTuioDeviceDiscoveryService.class.getName());
38  
39  	/**
40  	 * First port of range to be scanned.
41  	 */
42  	private int startPort;
43  
44  	/**
45  	 * Last port of range to be scanned (inclusive)
46  	 */
47  	private int endPort;
48  
49  	/**
50  	 * List of created devices.
51  	 */
52  	private Set<AbstractGestureDevice<?, ?>> devices;
53  
54  	/**
55  	 * Mapping between port and name.
56  	 */
57  	private Map<Integer, String> map;
58  
59  	private String typeToDiscover;
60  	private Class<?> clazzToInstantiate;
61  
62  	/**
63  	 * Constructor
64  	 */
65  	public AbstractTuioDeviceDiscoveryService(String type, Class<?> clazz) {
66  		typeToDiscover = type;
67  		clazzToInstantiate = clazz;
68  
69  		// get port range to scan from the properties file
70  		Properties properties = new Properties();
71  		try {
72  			properties.loadFromXML(new FileInputStream(
73  					GestureConstants.PROPERTIES));
74  			startPort = Integer.parseInt(properties
75  					.getProperty(Property.TUIO_START_PORT));
76  			endPort = Integer.parseInt(properties
77  					.getProperty(Property.TUIO_END_PORT));
78  		} catch (Exception e) {
79  			LOGGER
80  					.log(Level.WARNING,
81  							"Could not load the TUIO port range property. Using the default port '3333'.");
82  			startPort = TuioConstants.DEFAULT_PORT;
83  			endPort = startPort;
84  		}
85  
86  		map = new HashMap<Integer, String>();
87  		devices = new HashSet<AbstractGestureDevice<?, ?>>();
88  
89  		// get the registered tuio services
90  		XMLParser parser = new XMLParser() {
91  
92  			@Override
93  			public void execute(ArrayList<NodeList> nodeLists) {
94  				try {
95  					// read the port number
96  					int port = Integer.parseInt(((Node) nodeLists.get(0)
97  							.item(0)).getNodeValue());
98  					// read the service name
99  					String deviceName = ((Node) nodeLists.get(1).item(0))
100 							.getNodeValue();
101 					// read in the types
102 					String type = ((Node) nodeLists.get(2).item(0))
103 							.getNodeValue();
104 					String[] types = type.split(Constant.COMMA);
105 					for (String s : types) {
106 						if (typeToDiscover.equals(s)) {
107 							// put it in the map
108 							map.put(port, deviceName);
109 							break;
110 						}
111 
112 					}
113 				} catch (NumberFormatException e) {
114 					LOGGER
115 							.log(Level.WARNING,
116 									"Invalid Port Number. The corresponding Tuio device type was not added.");
117 				} catch (NullPointerException e) {
118 					LOGGER
119 							.log(
120 									Level.WARNING,
121 									"An empty node was encountered. The corresponding Tuio device type was not added.");
122 				}
123 			}
124 
125 		};
126 		ArrayList<String> textNodes = new ArrayList<String>();
127 		textNodes.add("port");
128 		textNodes.add("name");
129 		textNodes.add("type");
130 		try {
131 			parser.parse(System.getProperty("user.dir")
132 					+ System.getProperty("file.separator")
133 					+ GestureConstants.XML_TUIO, "device", textNodes);
134 		} catch (IOException e) {
135 			LOGGER.log(Level.SEVERE, "Could not find "
136 					+ GestureConstants.XML_TUIO, e);// TODO
137 		} catch (Exception e) {
138 			LOGGER.log(Level.SEVERE, "Could not parse "
139 					+ GestureConstants.XML_TUIO, e);// TODO
140 		}
141 	}
142 
143 	/*
144 	 * (non-Javadoc)
145 	 * 
146 	 * @seeorg.ximtec.igesture.tool.view.devicemanager.discoveryservice.
147 	 * DeviceDiscoveryService#discover()
148 	 */
149 	@Override
150 	public Set<AbstractGestureDevice<?, ?>> discover() {
151 		LOGGER.log(Level.INFO, "Device discovery started!");
152 
153 		// for each port in the defined range
154 		for (int port = startPort; port <= endPort; port++) {
155 			if (map.containsKey(port)) {
156 
157 				try {
158 					Constructor ctor = clazzToInstantiate
159 							.getConstructor(Integer.class);
160 					AbstractGestureDevice<?, ?> device = (AbstractGestureDevice<?, ?>) ctor
161 							.newInstance(new Integer(port));
162 					String name = map.get(port);
163 					if (name != null && !name.isEmpty()) {
164 						device.setName(name);
165 					} else
166 						name = "Tuio Service";
167 					LOGGER.log(Level.INFO, "Device discovered: " + name
168 							+ " on port " + port);
169 					devices.add(device);
170 				} catch (SecurityException e) {
171 					e.printStackTrace();
172 				} catch (NoSuchMethodException e) {
173 					e.printStackTrace();
174 				} catch (IllegalArgumentException e) {
175 					e.printStackTrace();
176 				} catch (InstantiationException e) {
177 					e.printStackTrace();
178 				} catch (IllegalAccessException e) {
179 					e.printStackTrace();
180 				} catch (InvocationTargetException e) {
181 					e.printStackTrace();
182 				}
183 			}
184 		}
185 
186 		LOGGER.log(Level.INFO, "Device discovery completed!");
187 
188 		if (devices.isEmpty()) {
189 			LOGGER.log(Level.INFO, "No devices discovered.");
190 		}
191 
192 		return devices;
193 	}
194 
195 	/*
196 	 * (non-Javadoc)
197 	 * 
198 	 * @seeorg.ximtec.igesture.tool.view.devicemanager.discoveryservice.
199 	 * DeviceDiscoveryService#dispose()
200 	 */
201 	@Override
202 	public void dispose() {
203 		devices.clear();
204 	}
205 }