View Javadoc

1   package org.ximtec.igesture.tool.view.devicemanager.discoveryservice;
2   
3   import java.io.IOException;
4   import java.lang.reflect.Constructor;
5   import java.lang.reflect.InvocationTargetException;
6   import java.util.ArrayList;
7   import java.util.HashMap;
8   import java.util.Map;
9   import java.util.logging.Level;
10  import java.util.logging.Logger;
11  
12  import javax.bluetooth.DeviceClass;
13  import javax.bluetooth.RemoteDevice;
14  
15  import org.w3c.dom.Node;
16  import org.w3c.dom.NodeList;
17  import org.ximtec.igesture.io.AbstractGestureDevice;
18  import org.ximtec.igesture.tool.GestureConstants;
19  import org.ximtec.igesture.tool.view.devicemanager.BlueToothReader;
20  import org.ximtec.igesture.util.XMLParser;
21  
22  /**
23   * This class converts a found Bluetooth device to a {@link org.ximtec.igesture.io.AbstractGestureDevice}
24   * @author Bjorn Puype, bpuype@gmail.com
25   *
26   */
27  public class BluetoothDeviceConverter {
28  	
29  	private static final Logger LOGGER = Logger.getLogger(BluetoothDeviceDiscoveryService.class.getName());
30  	
31  	/**
32  	 * Mapping between the device numbers and the appropriate {@link org.ximtec.igesture.io.AbstractGestureDevice} to instantiate.
33  	 */
34  	private final Map<BTDeviceClass,Class<?>> map;
35  	private XMLParser parser;
36  	
37  	public BluetoothDeviceConverter()
38  	{
39  		//load the mapping between bluetooth devices and their classes
40  		
41  		map = new HashMap<BTDeviceClass, Class<?>>();
42  		//create a parser
43  		parser = new XMLParser(){
44  
45  			@Override
46  			public void execute(ArrayList<NodeList> nodeLists) {
47  				
48  				try {
49  					// read the device numbers
50  					int minor = Integer.parseInt(((Node)nodeLists.get(0).item(0)).getNodeValue());
51  					int major = Integer.parseInt(((Node)nodeLists.get(1).item(0)).getNodeValue());
52  					// read the friendly name
53  					String deviceName = ((Node)nodeLists.get(2).item(0)).getNodeValue();
54  					// read the class name
55  					String className = ((Node)nodeLists.get(3).item(0)).getNodeValue();
56  					// load the class
57  					Class<?> c = Class.forName(className);
58  					// put it in the map
59  					map.put(new BTDeviceClass(minor,major,deviceName), c);
60  					
61  					LOGGER.log(Level.INFO,"Added new registered BlueTooth device type: "+deviceName);
62  					
63  				} catch (ClassNotFoundException e) {
64  					LOGGER.log(Level.WARNING, "Device Class not found. The corresponding BlueTooth device type was not added.",e);
65  				} catch (NumberFormatException e) {
66  					LOGGER.log(Level.WARNING, "One or more of the Device Class numbers is not a number. The corresponding BlueTooth device type was not added.",e);
67  				} catch (NullPointerException e) {
68  					LOGGER.log(Level.WARNING, "An empty node was encountered. The corresponding BlueTooth device type was not added.",e);
69  				}
70  			}
71  			
72  		};
73  		// the text nodes to read
74  		ArrayList<String> nodes = new ArrayList<String>();
75  		nodes.add("minor");
76  		nodes.add("major");
77  		nodes.add("name");
78  		nodes.add("class");
79  		//parse the XML file
80  		try {
81  			parser.parse(System.getProperty("user.dir")+System.getProperty("file.separator")+GestureConstants.XML_BLUETOOTH, "device", nodes);
82  		} catch (IOException e) {
83  			LOGGER.log(Level.SEVERE,"Could not find "+GestureConstants.XML_BLUETOOTH+". Falling back to default BlueTooth devices.",e);//TODO
84  		} catch (Exception e){
85  			LOGGER.log(Level.SEVERE,"Could not parse "+GestureConstants.XML_BLUETOOTH+". Falling back to default BlueTooth devices.",e);//TODO
86  		}
87  	}
88  
89  	/**
90  	 * Create a {@link org.ximtec.igesture.io.AbstractGestureDevice} from a found BlueTooth device.
91  	 * @param device	The found device.
92  	 * @param clazz		The device class (+ numbers)
93  	 * @return	The created device.
94  	 */
95  	public AbstractGestureDevice<?,?> createDevice(RemoteDevice device, DeviceClass clazz)
96  	{
97  		boolean registeredDeviceTypeFound = false;
98  		Object obj = null;
99  		
100 		int major = clazz.getMajorDeviceClass();
101 		int minor = clazz.getMinorDeviceClass();
102 		String friendlyName = null;
103 		try {
104 			friendlyName = device.getFriendlyName(false);
105 		} catch (IOException e1) {
106 			e1.printStackTrace();
107 		}
108 		
109 		
110 		for(BTDeviceClass btdc : map.keySet())//registered bluetooth devices types
111 		{
112 			//if device class numbers match
113 			//or
114 			//if uncategorized device, if friendly name matches
115 			if((btdc.getMajor() == major && btdc.getMinor() == minor)
116 					||
117 				(btdc.getMajor() == 0 && btdc.getMinor() == 0 && btdc.getFriendlyName().equals(friendlyName))
118 			)
119 			{
120 				// get the class
121 				Class<?> cl = map.get(btdc);
122 				// instantiate it
123 				try {
124 					Constructor<?> constructor = cl.getConstructor(new Class<?>[]{String.class, String.class, RemoteDevice.class});
125 					obj = constructor.newInstance(new Object[]{device.getBluetoothAddress(),device.getFriendlyName(false),device});
126 					
127 				} catch (SecurityException e) {
128 					e.printStackTrace();
129 				} catch (NoSuchMethodException e) {
130 					e.printStackTrace();
131 				} catch (IllegalArgumentException e) {
132 					e.printStackTrace();
133 				} catch (InstantiationException e) {
134 					e.printStackTrace();
135 				} catch (IllegalAccessException e) {
136 					e.printStackTrace();
137 				} catch (InvocationTargetException e) {
138 					e.printStackTrace();
139 				} catch (IOException e) {
140 					e.printStackTrace();
141 				}
142 				registeredDeviceTypeFound = true;
143 				break;
144 			}
145 		}
146 		if(!registeredDeviceTypeFound)//random bluetooth device
147 		{
148 			Class<?> cl = BlueToothReader.class;
149 			try {
150 				Constructor<?> constructor = cl.getConstructor(new Class<?>[]{String.class, String.class, RemoteDevice.class});
151 				obj = constructor.newInstance(new Object[]{device.getBluetoothAddress(),device.getFriendlyName(false),device});
152 				
153 			} catch (SecurityException e) {
154 				e.printStackTrace();
155 			} catch (NoSuchMethodException e) {
156 				e.printStackTrace();
157 			} catch (IllegalArgumentException e) {
158 				e.printStackTrace();
159 			} catch (InstantiationException e) {
160 				e.printStackTrace();
161 			} catch (IllegalAccessException e) {
162 				e.printStackTrace();
163 			} catch (InvocationTargetException e) {
164 				e.printStackTrace();
165 			} catch (IOException e) {
166 				e.printStackTrace();
167 			}
168 		}
169 		
170 		return (AbstractGestureDevice<?, ?>) obj;
171 	}
172 	
173 	/**
174 	 * This class is an encapsulation of the device class numbers of a particular type of device and a friendly name.
175 	 * @author Bj�n�ype, bpuype@gmail.com
176 	 *
177 	 */
178 	class BTDeviceClass
179 	{
180 		private int major; //e.g. computer, imaging, audio/video, peripheral, phone
181 		private int minor; //e.g. computer: laptop, desktop, ...
182 		private String deviceName;
183 		
184 		public BTDeviceClass(int minor, int major, String deviceName)
185 		{
186 			this.major = major;
187 			this.minor = minor;
188 			this.deviceName = deviceName;
189 		}
190 		
191 		public int getMinor(){ return minor; }
192 		public int getMajor(){ return major; }
193 		public String getFriendlyName() { return deviceName; }
194 	}
195 }