1
2
3
4 package org.ximtec.igesture.core.composite;
5
6 import java.lang.reflect.InvocationTargetException;
7 import java.lang.reflect.Method;
8 import java.text.ParseException;
9 import java.text.SimpleDateFormat;
10 import java.util.ArrayList;
11 import java.util.Calendar;
12 import java.util.Date;
13 import java.util.HashMap;
14 import java.util.HashSet;
15 import java.util.Iterator;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Set;
19
20 import org.sigtec.ink.Note;
21 import org.ximtec.igesture.core.DefaultDataObject;
22 import org.ximtec.igesture.core.Gesture;
23 import org.ximtec.igesture.core.GestureSample;
24 import org.ximtec.igesture.core.GestureSample3D;
25 import org.ximtec.igesture.io.GestureDevice;
26 import org.ximtec.igesture.io.IDeviceManager;
27 import org.ximtec.igesture.io.IUser;
28 import org.ximtec.igesture.util.MultiValueMap;
29 import org.ximtec.igesture.util.additions3d.RecordedGesture3D;
30
31
32
33
34
35 public abstract class DefaultConstraint extends DefaultDataObject implements Constraint {
36
37 protected Map<String, String> DEFAULT_CONFIGURATION = new HashMap<String, String>();
38 protected Map<String, String> setterMapping = new HashMap<String, String>();
39
40 protected List<DefaultConstraintEntry> gestures;
41 public static final String PROPERTY_GESTURES = "gestures";
42
43 protected SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss.SSS");
44
45 protected Calendar gestureTime;
46 protected Calendar processingTime;
47
48 public enum Config{
49 GESTURE_TIME
50 }
51
52 private static final String GESTURE_TIME = "00:00:10.000";
53
54 public DefaultConstraint()
55 {
56 DEFAULT_CONFIGURATION.put(Config.GESTURE_TIME.name(), GESTURE_TIME);
57 setterMapping.put(Config.GESTURE_TIME.name(), "setGestureTime");
58 gestures = new ArrayList<DefaultConstraintEntry>();
59 df.setLenient(false);
60 try {
61
62
63
64
65 Date d = df.parse(GESTURE_TIME);
66 gestureTime = Calendar.getInstance();
67 gestureTime.setTime(d);
68 d = df.parse("00:00:02.000");
69 processingTime = Calendar.getInstance();
70 processingTime.setTime(d);
71 } catch (ParseException e) {
72 e.printStackTrace();
73 }
74
75 }
76
77
78
79
80 @Override
81 public void addGestureClass(String gestureClass) {
82 DefaultConstraintEntry entry = new DefaultConstraintEntry(gestureClass);
83 gestures.add(entry);
84 propertyChangeSupport.fireIndexedPropertyChange(PROPERTY_GESTURES, gestures.indexOf(entry), null, entry);
85 }
86
87
88
89
90 @Override
91 public void addGestureClass(String gestureClass, int user) {
92 DefaultConstraintEntry entry = new DefaultConstraintEntry(gestureClass, user);
93 gestures.add(entry);
94 propertyChangeSupport.fireIndexedPropertyChange(PROPERTY_GESTURES, gestures.indexOf(entry), null, entry);
95 }
96
97
98
99
100 @Override
101 public void addGestureClass(String gestureClass, String deviceType, Set<String> devices) {
102 DefaultConstraintEntry entry = new DefaultConstraintEntry(gestureClass, deviceType, devices);
103 gestures.add(entry);
104 propertyChangeSupport.fireIndexedPropertyChange(PROPERTY_GESTURES, gestures.indexOf(entry), null, entry);
105 }
106
107
108
109
110 @Override
111 public void addGestureClass(String gestureClass, int user, String deviceType, Set<String> devices) {
112 DefaultConstraintEntry entry = new DefaultConstraintEntry(gestureClass, deviceType, devices);
113 gestures.add(entry);
114 propertyChangeSupport.fireIndexedPropertyChange(PROPERTY_GESTURES, gestures.indexOf(entry), null, entry);
115 }
116
117
118
119
120 @Override
121 public List<String> getGestureClasses() {
122 List<String> list = new ArrayList<String>();
123 for(DefaultConstraintEntry entry : gestures)
124 list.add(entry.getGesture());
125 return list;
126 }
127
128
129
130
131 @Override
132 public Set<String> getDistinctGestureClasses() {
133 Set<String> set = new HashSet<String>();
134 set.addAll(getGestureClasses());
135 return set;
136 }
137
138
139
140
141 @Override
142 public int getNumberOfGestures() {
143 return gestures.size();
144 }
145
146 public void setGestureTime(String time) throws ParseException
147 {
148 Date d = df.parse(time);
149 gestureTime = Calendar.getInstance();
150 gestureTime.setTime(d);
151 }
152
153 public Calendar getGestureTime()
154 {
155 return gestureTime;
156 }
157
158
159
160
161 @Override
162 public abstract Set<String> generatePatterns(Map<String, String> charMapping);
163
164
165
166
167 @Override
168 public boolean validateConditions(List<Gesture<?>> gestures, IDeviceManager manager)
169 {
170 boolean conditionsValid = true;
171 Map<Gesture<?>,GestureDevice<?,?>> map = new HashMap<Gesture<?>,GestureDevice<?,?>>();
172
173
174 boolean found = true;
175 for(Gesture<?> gesture : gestures)
176 {
177
178 String gestureClass = gesture.getName();
179
180 List<DefaultConstraintEntry> entries = new ArrayList<DefaultConstraintEntry>();
181 for(DefaultConstraintEntry entry : this.gestures)
182 {
183 if(entry.getGesture().equals(gestureClass))
184 entries.add(entry);
185 }
186
187 for (Iterator<DefaultConstraintEntry> iterator = entries.iterator(); iterator.hasNext();) {
188
189 DefaultConstraintEntry entry = iterator.next();
190 GestureDevice<?,?> device = gesture.getSource();
191
192
193 if(entry.getDeviceType() == null)
194 continue;
195
196 if(entry.getDeviceType().equals(device.getDeviceClass()))
197 {
198
199 if(entry.getDevices() != null && !entry.getDevices().isEmpty())
200 {
201
202 if(entry.getDevices().contains(device.getDeviceID()))
203 found = true;
204 else
205 found = false;
206 }
207 else
208 found = true;
209 }
210
211 if(found == true)
212 {
213 map.put(gesture, device);
214 break;
215 }
216 }
217
218 if(found == false)
219 {
220 conditionsValid = false;
221 break;
222 }
223 }
224
225
226 if(conditionsValid && manager!= null)
227 {
228 MultiValueMap<Integer, String> defined = new MultiValueMap<Integer, String>();
229 MultiValueMap<IUser, String> recognised = new MultiValueMap<IUser, String>();
230
231
232 for (Iterator<DefaultConstraintEntry> iterator = this.gestures.iterator(); iterator.hasNext();) {
233 DefaultConstraintEntry entry = iterator.next();
234 if(entry.getUser() != -1)
235 defined.add(entry.getUser(), entry.getGesture());
236 }
237
238
239 for (Iterator<Gesture<?>> iterator = gestures.iterator(); iterator.hasNext();) {
240 Gesture<?> gesture = iterator.next();
241 recognised.add(manager.getAssociatedUser(gesture.getSource()), gesture.getName());
242 }
243
244
245 Set<Integer> definedKeys = defined.keySet();
246 Set<IUser> recognisedKeys = recognised.keySet();
247
248
249
250
251 for (Iterator<Integer> iterator = definedKeys.iterator(); iterator.hasNext();) {
252 Integer integer = iterator.next();
253
254
255 Map<IUser, Integer> fittingKeys = new HashMap<IUser, Integer>();
256
257 List<String> values = defined.getValues(integer);
258 for(Iterator<IUser> iter = recognisedKeys.iterator(); iter.hasNext();)
259 {
260 IUser user = iter.next();
261 List<String> list = recognised.getValues(user);
262 if(list.containsAll(values))
263 {
264 fittingKeys.put(user, list.size());
265 }
266 }
267
268
269 if(fittingKeys.isEmpty())
270 {
271 conditionsValid = false;
272 break;
273 }
274 else
275 {
276
277 IUser shortestFittingKey = null;
278 int min = Integer.MAX_VALUE;
279 for(Iterator<IUser> iter = fittingKeys.keySet().iterator(); iter.hasNext();)
280 {
281 IUser user = iter.next();
282 if(fittingKeys.get(user).intValue() < min)
283 {
284 min = fittingKeys.get(user).intValue();
285 shortestFittingKey = user;
286 }
287 }
288
289 recognised.removeKey(shortestFittingKey);
290 }
291
292 }
293
294
295
296
297
298
299 }
300 else if(manager == null)
301 {
302 conditionsValid = false;
303 }
304
305 return conditionsValid;
306 }
307
308
309
310
311 @Override
312 public abstract Map<String, Calendar> determineTimeWindows();
313
314
315
316
317
318
319
320 protected long getTimeStamp(Gesture<?> gesture, boolean start)
321 {
322 long timestamp = 0;
323 if(gesture instanceof GestureSample)
324 {
325 Note note = ((GestureSample)gesture).getGesture();
326 if(start)
327 timestamp = note.getStartPoint().getTimestamp();
328 else
329 timestamp = note.getEndPoint().getTimestamp();
330 }
331 else if(gesture instanceof GestureSample3D)
332 {
333 RecordedGesture3D record = ((GestureSample3D)gesture).getGesture();
334 if(start)
335 timestamp = record.getStartPoint().getTimeStamp();
336 else
337 timestamp = record.getEndPoint().getTimeStamp();
338 }
339 else
340 ;
341
342 return timestamp;
343 }
344
345 public String toString()
346 {
347 return DefaultConstraint.class.getSimpleName();
348 }
349
350
351
352
353 @Override
354 public Map<String, String> getParameters() {
355 return DEFAULT_CONFIGURATION;
356 }
357
358
359
360
361 @Override
362 public String getParameter(String property)
363 {
364 return DEFAULT_CONFIGURATION.get(property);
365 }
366
367
368
369
370 @Override
371 public void setParameter(String property, String value)
372 {
373 DEFAULT_CONFIGURATION.put(property, value);
374 Class<?> clazz = this.getClass();
375 try {
376 Method m = clazz.getMethod(setterMapping.get(property), String.class);
377 m.invoke(this, value);
378 } catch (SecurityException e) {
379 e.printStackTrace();
380 } catch (NoSuchMethodException e) {
381 e.printStackTrace();
382 } catch (IllegalArgumentException e) {
383 e.printStackTrace();
384 } catch (IllegalAccessException e) {
385 e.printStackTrace();
386 } catch (InvocationTargetException e) {
387 e.printStackTrace();
388 }
389 }
390
391
392
393
394 @Override
395 public void removeAllGestureClasses() {
396 DefaultConstraintEntry entry = gestures.get(0);
397 gestures.clear();
398 propertyChangeSupport.fireIndexedPropertyChange(PROPERTY_GESTURES, 0, entry, null);
399 }
400
401
402
403
404 @Override
405 public void removeGestureClass(DefaultConstraintEntry entry)
406 {
407 gestures.remove(entry);
408 propertyChangeSupport.fireIndexedPropertyChange(PROPERTY_GESTURES, gestures.indexOf(entry), entry, null);
409 }
410
411
412
413
414 @Override
415 public List<DefaultConstraintEntry> getGestureEntries()
416 {
417 return gestures;
418 }
419
420 }