View Javadoc

1   /**
2    * 
3    */
4   package org.ximtec.igesture.core.composite;
5   
6   import java.util.HashSet;
7   import java.util.Iterator;
8   import java.util.List;
9   import java.util.Map;
10  import java.util.Set;
11  import java.util.logging.Level;
12  import java.util.logging.Logger;
13  
14  import org.ximtec.igesture.core.Gesture;
15  import org.ximtec.igesture.io.GestureDevice;
16  import org.ximtec.igesture.io.IDeviceManager;
17  
18  /**
19   * This class represents a cardinality constraint. A certain gesture has to be performed between a mimimum and a maximum number 
20   * of times within a certain time interval. The main example for this kind of constraint is defining a majority. 
21   * Each device has only one vote.
22   * 
23   * @author Bjorn Puype, bpuype@gmail.com
24   *
25   */
26  public class CardinalityDeviceConstraint extends IntervalConstraint {
27  
28  	private static final Logger LOGGER = Logger.getLogger(CardinalityUserConstraint.class.getName());
29  	private static final String ERROR_MESSAGE = "A cardinality based constraint can only contain one gesture class.\n" +
30  										"Please remove the existing gesture class from the constraint before adding a new one.";
31  	private static final String LOGGER_MESSAGE = "A cardinality based constraint can only contain one gesture class. " +
32  										"The gesture class was not added.";
33  	private static final String ERROR_MESSAGE_USER = "The user cannot be specified for a cardinality based constraint.\n" +
34  			"The user field was not saved";
35  	private static final String LOGGER_MESSAGE_USER = "The user cannot be specified for a cardinality based constraint.\n" +
36  			"The gesture class was added without the user field.";
37  	
38  	public enum Config{
39  		MIN_GESTURES, MAX_GESTURES
40  	}
41  	
42  	private static final String MIN_GESTURES = "2";
43  	private static final String MAX_GESTURES = "2";
44  	
45  	private int minGestures;
46  	private int maxGestures;
47  
48  	public CardinalityDeviceConstraint() {
49  		super();
50  		DEFAULT_CONFIGURATION.put(Config.MIN_GESTURES.name(), MIN_GESTURES);
51  		DEFAULT_CONFIGURATION.put(Config.MAX_GESTURES.name(), MAX_GESTURES);
52  		setterMapping.put(Config.MIN_GESTURES.name(), "setMinimumGestures");
53  		setterMapping.put(Config.MAX_GESTURES.name(), "setMaximumGestures");
54  		setMinimumGestures(MIN_GESTURES);
55  		setMaximumGestures(MAX_GESTURES);
56  	}
57  	
58  	/* (non-Javadoc)
59  	 * @see org.ximtec.igesture.core.composite.Constraint#addGestureClass(java.lang.String)
60  	 */
61  	@Override
62  	public void addGestureClass(String gestureClass) {
63  		if(gestures.isEmpty())
64  		{
65  			DefaultConstraintEntry entry = new DefaultConstraintEntry(gestureClass); 
66  			gestures.add(entry);
67  			propertyChangeSupport.fireIndexedPropertyChange(PROPERTY_GESTURES, gestures.indexOf(entry), null, entry);
68  		}
69  		else
70  		{
71  			IllegalArgumentException e = new IllegalArgumentException(ERROR_MESSAGE);
72  			LOGGER.log(Level.SEVERE,LOGGER_MESSAGE,e);
73  			throw e;
74  		}
75  	}
76  
77  	/* (non-Javadoc)
78  	 * @see org.ximtec.igesture.core.composite.Constraint#addGestureClass(java.lang.String, int)
79  	 */
80  	@Override
81  	public void addGestureClass(String gestureClass, int user) {
82  		if(gestures.isEmpty())
83  		{
84  			DefaultConstraintEntry entry = new DefaultConstraintEntry(gestureClass);
85  			gestures.add(entry);
86  			propertyChangeSupport.fireIndexedPropertyChange(PROPERTY_GESTURES, gestures.indexOf(entry), null, entry);
87  			IllegalArgumentException e = new IllegalArgumentException(ERROR_MESSAGE_USER);
88  			LOGGER.log(Level.WARNING,LOGGER_MESSAGE_USER,e);
89  			throw e;
90  		}
91  		else
92  		{
93  			IllegalArgumentException e = new IllegalArgumentException(ERROR_MESSAGE);
94  			LOGGER.log(Level.SEVERE,LOGGER_MESSAGE,e);
95  			throw e;
96  		}
97  	}
98  
99  	/* (non-Javadoc)
100 	 * @see org.ximtec.igesture.core.composite.Constraint#addGestureClass(java.lang.String, java.lang.String, java.util.Set<String>)
101 	 */
102 	@Override
103 	public void addGestureClass(String gestureClass, String deviceType, Set<String> devices) {
104 		if(gestures.isEmpty())
105 		{
106 			DefaultConstraintEntry entry = new DefaultConstraintEntry(gestureClass, deviceType, devices); 
107 			gestures.add(entry);
108 			propertyChangeSupport.fireIndexedPropertyChange(PROPERTY_GESTURES, gestures.indexOf(entry), null, entry);
109 			IllegalArgumentException e = new IllegalArgumentException(ERROR_MESSAGE_USER);
110 			LOGGER.log(Level.WARNING,LOGGER_MESSAGE_USER,e);
111 			throw e;
112 		}
113 		else
114 		{
115 			IllegalArgumentException e = new IllegalArgumentException(ERROR_MESSAGE);
116 			LOGGER.log(Level.SEVERE,LOGGER_MESSAGE,e);
117 			throw e;
118 		}
119 	}
120 
121 	/* (non-Javadoc)
122 	 * @see org.ximtec.igesture.core.composite.Constraint#addGestureClass(java.lang.String, int, java.lang.String, java.util.Set<String>)
123 	 */
124 	@Override
125 	public void addGestureClass(String gestureClass, int user, String deviceType, Set<String> devices) {
126 		if(gestures.isEmpty())
127 		{
128 			DefaultConstraintEntry entry = new DefaultConstraintEntry(gestureClass, deviceType, devices);
129 			gestures.add(entry);
130 			propertyChangeSupport.fireIndexedPropertyChange(PROPERTY_GESTURES, gestures.indexOf(entry), null, entry);
131 		}
132 		else
133 		{
134 			IllegalArgumentException e = new IllegalArgumentException(ERROR_MESSAGE);
135 			LOGGER.log(Level.SEVERE,LOGGER_MESSAGE,e);
136 			throw e;
137 		}
138 	}
139 
140 	/**
141 	 * Set the minimum number of gestures to perform
142 	 */
143 	public void setMinimumGestures(String min) throws NumberFormatException
144 	{
145 		minGestures = Integer.parseInt(min);
146 	}
147 	
148 	/**
149 	 * Get the minimum number of gestures that has to be performed
150 	 */
151 	public int getMinimumGestures()
152 	{
153 		return minGestures;
154 	}
155 	
156 	/**
157 	 * Set the maximum number of gestures to perform
158 	 */
159 	public void setMaximumGestures(String max) throws NumberFormatException
160 	{
161 		maxGestures = Integer.parseInt(max);
162 	}
163 	
164 	/**
165 	 * Get the maximum number of gestures that has to be performed
166 	 */
167 	public int getMaximumGestures()
168 	{
169 		return maxGestures;
170 	}
171 	
172 	/* (non-Javadoc)
173 	 * @see org.ximtec.igesture.core.composite.DefaultConstraint#generatePatterns(java.util.Map)
174 	 */
175 	@Override
176 	public Set<String> generatePatterns(Map<String, String> charMapping) {
177 		Set<String> patterns = new HashSet<String>();
178 		
179 		String key = gestures.get(0).getGesture();
180 		
181 		for (int i = minGestures; i <= maxGestures; i++) {
182 			StringBuilder builder = new StringBuilder();
183 			for(int j = 0; j < i; j++)
184 			{
185 				builder.append(charMapping.get(key));
186 			}
187 			patterns.add(builder.toString());
188 		}
189 		
190 		return patterns;
191 	}
192 	
193 	/* (non-Javadoc)
194 	 * @see org.ximtec.igesture.core.composite.DefaultConstraint#validateConditions(java.util.List)
195 	 */
196 	@Override
197 	public boolean validateConditions(List<Gesture<?>> gestures, IDeviceManager manager) {
198 		boolean conditionsValid = super.validateConditions(gestures, manager);
199 		
200 		if(conditionsValid) // if previous conditions hold
201 		{
202 			
203 			Set<GestureDevice<?,?>> devs = new HashSet<GestureDevice<?,?>>();
204 			
205 			//check if all gestures were created by different devices
206 			for (Iterator iterator = gestures.iterator(); iterator.hasNext();) {
207 				Gesture<?> gesture = (Gesture<?>) iterator.next();
208 				GestureDevice<?,?> dev = gesture.getSource();
209 				devs.add(dev);
210 			}
211 			
212 			if(devs.size() != gestures.size())
213 				conditionsValid = false;
214 		}
215 		
216 		return conditionsValid;
217 	}
218 
219 	public String toString()
220 	{
221 		return CardinalityDeviceConstraint.class.getSimpleName();
222 	}
223 }