View Javadoc

1   /*
2    *  
3    *  Fosstrak LLRP Commander (www.fosstrak.org)
4    * 
5    *  Copyright (C) 2008 ETH Zurich
6    *
7    *  This program is free software: you can redistribute it and/or modify
8    *  it under the terms of the GNU General Public License as published by
9    *  the Free Software Foundation, either version 3 of the License, or
10   *  (at your option) any later version.
11   *
12   *  This program is distributed in the hope that it will be useful,
13   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   *  GNU General Public License for more details.
16   *
17   *  You should have received a copy of the GNU General Public License
18   *  along with this program.  If not, see <http://www.gnu.org/licenses/> 
19   *
20   */
21  
22  package org.fosstrak.llrp.commander.util;
23  
24  import java.io.IOException;
25  import java.io.StringWriter;
26  import java.net.URL;
27  import java.util.LinkedList;
28  import java.util.List;
29  
30  import javax.xml.transform.OutputKeys;
31  import javax.xml.transform.Transformer;
32  import javax.xml.transform.TransformerException;
33  import javax.xml.transform.TransformerFactory;
34  import javax.xml.transform.dom.DOMSource;
35  import javax.xml.transform.stream.StreamResult;
36  
37  import org.eclipse.core.runtime.FileLocator;
38  import org.fosstrak.llrp.commander.LLRPPlugin;
39  import org.llrp.ltkGenerator.CodeGenerator;
40  import org.llrp.ltkGenerator.generated.*;
41  import org.w3c.dom.Element;
42  
43  /**
44   * This class can be used to get information on the LLRP protocol.
45   * For example, to learn the definition of the "ADD_ROSPEC" message, call
46   * <code>LLRP.getMessageDefinition("ADD_ROSPEC").
47   * 
48   * @author Ulrich Etter, ETHZ
49   *
50   */
51  public class LLRP {
52  	
53  	static {
54  		String jaxBPackage = "org.llrp.ltkGenerator.generated";
55  		String pluginPath = null;
56  		URL bundleRootURL = LLRPPlugin.getDefault().getBundle().getEntry("/");
57  		URL pluginURL;
58  		try {
59  			pluginURL = FileLocator.resolve(bundleRootURL);
60  			pluginPath = pluginURL.getPath();
61  		} catch (IOException e) {
62  			e.printStackTrace();
63  		}
64  		
65  		pluginPath = "file://" + pluginPath;
66  		
67  		String namespacePrefix = "llrp";
68  		String xmlPath = pluginPath + "Definitions/Core/llrp-1x0-def.xml";
69  		String xsdPath = pluginPath + "Definitions/Core/llrp-1x0.xsd";
70  		String[] extensions = {namespacePrefix + ";" + xmlPath + ";" + xsdPath};
71  		
72  		CodeGenerator cg = new CodeGenerator();
73  				
74  		llrpDefinition = cg.getLLRPDefinition(jaxBPackage, extensions);
75  	}
76  	
77  	private static LlrpDefinition llrpDefinition;
78  	
79  	/**
80  	 * Returns the LLRP definition object.
81  	 * 
82  	 * @return the LLRP definition object
83  	 */
84  	public static LlrpDefinition getLlrpDefintion(){
85  		return llrpDefinition;
86  	}
87      
88      /**
89       * Returns the definition of the message with the given name.
90       * @param messageName the name of a message
91       * @return the definition object, or <code>null</code> if no message with the given name exists
92       */
93      public static MessageDefinition getMessageDefinition(String messageName) {
94      	MessageDefinition messageDefinition = null; 
95  		List<Object> list = llrpDefinition.getMessageDefinitionOrParameterDefinitionOrChoiceDefinition();
96  		for (Object o : list){
97  			if (o instanceof MessageDefinition){
98  				if (((MessageDefinition) o).getName().equals(messageName)){
99  					messageDefinition = (MessageDefinition) o;
100 					break;
101 				}
102 			}
103 		}
104 		return messageDefinition;
105 	}
106     
107     /**
108      * Returns the definition of the parameter with the given name. 
109      * @param parameterName the name of a parameter
110      * @return the definition object, or <code>null</code> if no parameter with the given name exists
111      */
112     public static ParameterDefinition getParameterDefinition(String parameterName) {
113 		ParameterDefinition parameterDefinition = null; 
114 		List<Object> list = llrpDefinition.getMessageDefinitionOrParameterDefinitionOrChoiceDefinition();
115 		for (Object o : list){
116 			if (o instanceof ParameterDefinition){
117 				if (((ParameterDefinition) o).getName().equals(parameterName)){
118 					parameterDefinition = (ParameterDefinition) o;
119 					break;
120 				}
121 			}
122 		}
123 		return parameterDefinition;
124 	}
125     
126     /**
127      * Returns the definition of the choice with the given name. 
128      * @param choiceName the name of a choice
129      * @return the definition object, or <code>null</code> if no choice with the given name exists
130      */
131     public static ChoiceDefinition getChoiceDefinition(String choiceName) {
132 		ChoiceDefinition choiceDefinition = null; 
133 		List<Object> list = llrpDefinition.getMessageDefinitionOrParameterDefinitionOrChoiceDefinition();
134 		for (Object o : list){
135 			if (o instanceof ChoiceDefinition){
136 				if (((ChoiceDefinition) o).getName().equals(choiceName)){
137 					choiceDefinition = (ChoiceDefinition) o;
138 					break;
139 				}
140 			}
141 		}
142 		return choiceDefinition;
143 	}
144 	
145     /**
146      * Returns the definition of the field with the given name of the message/parameter with the given definition.
147      * 
148      * @param messageOrParameterDefinition either a <code> MessageDefinition</code> or a <code>ParameterDefinition</code>
149      * @param fieldName the name of a field
150      * @return the definition of the field, or <code>null</code> if no field with the given name exists 
151      * in the message/parameter with the given definition
152      */
153     public static FieldDefinition getFieldDefinition(Object messageOrParameterDefinition, String fieldName){
154     	FieldDefinition fieldDefinition = null;
155     	List<Object> fieldOrReservedList = new LinkedList<Object>();
156     	if (messageOrParameterDefinition instanceof MessageDefinition){
157     		fieldOrReservedList = ((MessageDefinition) messageOrParameterDefinition).getFieldOrReserved();
158     	}
159     	else if (messageOrParameterDefinition instanceof ParameterDefinition){
160     		fieldOrReservedList = ((ParameterDefinition) messageOrParameterDefinition).getFieldOrReserved();
161     	}
162 		for (Object o : fieldOrReservedList){
163 			if (o instanceof FieldDefinition){
164 				FieldDefinition fd = ((FieldDefinition) o);
165 				if (fd.getName().equals(fieldName)){
166 					fieldDefinition = fd;
167 					break;
168 				}
169 			}
170 		}
171     	return fieldDefinition;
172     }
173     
174     /**
175      * Returns the definitions of all fields of the message/parameter with the given name.
176      * 
177      * @param messageOrParameterDefinition either a <code> MessageDefinition</code> or a <code>ParameterDefinition</code>
178      * @return the definitions of all fields of the message/parameter with the given name
179      */
180     public static List<FieldDefinition> getFieldDefinitions(Object messageOrParameterDefinition){
181 		List<Object> fieldOrReservedList = new LinkedList<Object>();
182 		List<FieldDefinition> fieldDefinitions = new LinkedList<FieldDefinition>();
183 		if (messageOrParameterDefinition instanceof MessageDefinition){
184 			fieldOrReservedList = ((MessageDefinition) messageOrParameterDefinition).getFieldOrReserved();
185 		}
186 		else if (messageOrParameterDefinition instanceof ParameterDefinition){
187 			fieldOrReservedList = ((ParameterDefinition) messageOrParameterDefinition).getFieldOrReserved();
188 		}
189 		for (int i = 0; i < fieldOrReservedList.size(); i++){
190 			if (fieldOrReservedList.get(i) instanceof FieldDefinition){
191 				fieldDefinitions.add((FieldDefinition) fieldOrReservedList.get(i));
192 			}
193 		}
194 		return fieldDefinitions;
195     }
196     
197     /**
198      * Returns the definition of the enumeration with the given name.
199      * @param enumerationName the name of an enumeration
200      * @return the definition of the enumeration, or <code>null</code> if no enumeration with the given name exists
201      */
202     public static EnumerationDefinition getEnumerationDefinition(String enumerationName){
203     	List<Object> list = llrpDefinition.getMessageDefinitionOrParameterDefinitionOrChoiceDefinition();
204 		for (Object o : list){
205 			if (o instanceof EnumerationDefinition){
206 				if (((EnumerationDefinition) o).getName().equals(enumerationName)){
207 					return (EnumerationDefinition) o;
208 				}
209 			}
210 		}
211 		return null;
212     }
213 	
214 	/**
215 	 * Returns the description of the message/parameter with the given definition as a HTML string.
216 	 * 
217 	 * @param messageOrParameterDefinition either a <code> MessageDefinition</code> or a <code>ParameterDefinition</code>
218 	 * @return the description of the message/parameter with the given definition as a HTML string
219 	 */
220 	public static String getDescription(Object messageOrParameterDefinition){
221 		String descriptionString = "";
222 		java.util.List<Annotation> annotations = getAnnotation(messageOrParameterDefinition);
223 		if (!annotations.isEmpty()){
224 			// just use the first annotation
225 			Annotation firstAnnotation = annotations.get(0);
226 			if (firstAnnotation != null){
227 				java.util.List<Object> documentationOrDescription = firstAnnotation.getDocumentationOrDescription();
228 				Description description = null;
229 				for (Object o : documentationOrDescription){
230 					if (o instanceof Description){
231 						// just use the first description
232 						description = (Description) o;
233 						break;
234 					}
235 				}
236 				if (description != null){
237 					java.util.List<Object> content = description.getContent();
238 					for (Object o : content){
239 						if (o instanceof Element){
240 							Element element = (Element) o;
241 							
242 							try{
243 						      // Set up the output transformer
244 						      TransformerFactory transfac = TransformerFactory.newInstance();
245 						      Transformer trans = transfac.newTransformer();
246 						      trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
247 						      trans.setOutputProperty(OutputKeys.INDENT, "no");
248 
249 						      // Print the DOM node
250 						      StringWriter sw = new StringWriter();
251 						      StreamResult result = new StreamResult(sw);
252 						      DOMSource source = new DOMSource(element);
253 						      trans.transform(source, result);
254 						      String xmlString = sw.toString();
255 						      final String NAMESPACE_PREFIX = "h:";
256 						      xmlString = xmlString.replace(NAMESPACE_PREFIX, "");
257 						      descriptionString = descriptionString + xmlString;
258 							}
259 							catch (TransformerException e){
260 							      e.printStackTrace();
261 							}
262 						}
263 						else if (o instanceof String){
264 							descriptionString = descriptionString + ((String) o).trim();
265 						}
266 					}
267 
268 				}
269 			}
270 		}
271 		return descriptionString;
272 	}
273 	
274 	private static List<Annotation> getAnnotation(Object messageOrParameterDefinition){
275 		List<Annotation> annotations = new LinkedList<Annotation>();
276 		if (messageOrParameterDefinition instanceof MessageDefinition){
277 			annotations = ((MessageDefinition) messageOrParameterDefinition).getAnnotation();
278 		}
279 		else if (messageOrParameterDefinition instanceof ParameterDefinition){
280 			annotations = ((ParameterDefinition) messageOrParameterDefinition).getAnnotation();
281 		}
282 		return annotations;
283 	}
284 	
285     /**
286      * Returns the names of all parameters and choices of the message/parameter with the given definition.
287      * @param messageOrParameterDefinition either a <code> MessageDefinition</code> or a <code>ParameterDefinition</code>
288      * @return the names of all parameters and choices of the message/parameter with the given definition
289      */
290     public static List<String> getParameterAndChoiceNames(Object messageOrParameterDefinition) {
291     	List<String> childrenNames = new LinkedList<String>();
292 
293 		List<Object> parameterOrChoiceList = new LinkedList<Object>();
294 		if (messageOrParameterDefinition instanceof MessageDefinition){
295 			parameterOrChoiceList = ((MessageDefinition) messageOrParameterDefinition).getParameterOrChoice();
296 		}
297 		else if (messageOrParameterDefinition instanceof ParameterDefinition){
298 			parameterOrChoiceList = ((ParameterDefinition) messageOrParameterDefinition).getParameterOrChoice();
299 		}
300 		for (int i = 0; i < parameterOrChoiceList.size(); i++){
301 			Object o = parameterOrChoiceList.get(i);
302 			String name = "";
303 			if (o instanceof ParameterReference){
304 				ParameterReference parameterReference = (ParameterReference) o;
305 				name = parameterReference.getType();
306 			}
307 			else if (o instanceof ChoiceReference){
308 				ChoiceReference choiceReference = (ChoiceReference) o;
309 				name = choiceReference.getType();
310 			}
311 			childrenNames.add(name);
312 		}
313 		return childrenNames;
314 	}
315     
316 	/**
317 	 * Returns the type of the field with the given definition.
318 	 * @param fieldDefinition the definition of the field
319 	 * @return the type of the field with the given definition
320 	 */
321 	public static String getFieldType(FieldDefinition fieldDefinition) {
322 		String result;
323 		org.llrp.ltkGenerator.Utility utility = new org.llrp.ltkGenerator.Utility(null);
324 		String baseType = utility.convertType(fieldDefinition.getType().value());
325 		
326 		if (fieldDefinition.getFormat() != null){
327 			String format = fieldDefinition.getFormat().value();
328 			result = baseType + "_" + format.toUpperCase();
329 		}
330 		else{
331 			result = baseType;
332 		}
333 		return result;
334 	}
335     
336     /**
337      * Returns <code>true</code> if the field with the given definition is an enumeration, 
338      * and <code>false</code> otherwise.
339      * 
340      * @param fieldDefinition the definition of the field
341      * @return true if the field is an enumeration, false otherwise.
342      */
343     public static boolean isEnumeration(FieldDefinition fieldDefinition){
344     	return fieldDefinition.getEnumeration() != null;
345     }
346     
347     /**
348      * Returns <code>true</code> if the parameter/choice with the given name can occur multiple times in 
349      * the message/parameter with the given definition, 
350      * and <code>false</code> otherwise.
351      * 
352      * @param messageOrParameterDefinition either a <code> MessageDefinition</code> or a <code>ParameterDefinition</code>
353      * @param parameterOrChoiceName the name of a parameter/choice
354      * @return true if a parameter can occur multiple times, false otherwise.
355      */
356     public static boolean canOccurMultipleTimes(Object messageOrParameterDefinition, String parameterOrChoiceName){
357     	boolean result = false;
358     	String repeat = getRepeat(messageOrParameterDefinition, parameterOrChoiceName);
359     	if (repeat.equals("0-N") || repeat.equals("1-N")){
360 			result = true;
361 		}
362 		return result;
363     }
364 
365 	/**
366 	 * Returns <code>true</code> if the parameter/choice with the given name must occur at least once in 
367      * the message/parameter with the given definition, 
368      * and <code>false</code> otherwise.
369 	 * 
370 	 * @param messageOrParameterDefinition either a <code> MessageDefinition</code> or a <code>ParameterDefinition</code>
371 	 * @param parameterOrChoiceName the name of a parameter/choice
372 	 * @return true if parameter must occur at least once, false otherwise.
373 	 */
374 	public static boolean mustOccurAtLeastOnce(Object messageOrParameterDefinition, String parameterOrChoiceName) {
375 		boolean result = false;
376     	String repeat = getRepeat(messageOrParameterDefinition, parameterOrChoiceName);
377     	if (repeat.equals("1") || repeat.equals("1-N")){
378 			result = true;
379 		}
380 		return result;
381 	}
382 	
383 	private static String getRepeat(Object messageOrParameterDefinition, String childName){
384 		String result = "";
385 		List<Object> parameterOrChoiceList = new LinkedList<Object>();
386 		if (messageOrParameterDefinition instanceof MessageDefinition){
387 			parameterOrChoiceList = ((MessageDefinition) messageOrParameterDefinition).getParameterOrChoice();
388 		}
389 		else if (messageOrParameterDefinition instanceof ParameterDefinition){
390 			parameterOrChoiceList = ((ParameterDefinition) messageOrParameterDefinition).getParameterOrChoice();
391 		}
392 		for (int i = 0; i < parameterOrChoiceList.size(); i++){
393 			Object o = parameterOrChoiceList.get(i);
394 			String name = "";
395 			String repeat = "";
396 			if (o instanceof ParameterReference){
397 				ParameterReference parameterReference = (ParameterReference) o;
398 				name = parameterReference.getType();
399 				repeat = parameterReference.getRepeat();
400 			}
401 			else if (o instanceof ChoiceReference){
402 				ChoiceReference choiceReference = (ChoiceReference) o;
403 				name = choiceReference.getType();
404 				repeat = choiceReference.getRepeat();
405 			}
406 			if (name.equals(childName)){
407 				result = repeat;
408 				break;
409 			}
410 		}
411 		return result;
412 	}
413 
414 	/**
415 	 * Returns <code>true</code> if the parameter/choice with the given name, defined in the 
416 	 * message/parameter with the given definition, is a choice, 
417      * and <code>false</code> otherwise.
418 	 * 
419 	 * @param messageOrParameterDefinition either a <code> MessageDefinition</code> or a <code>ParameterDefinition</code>
420 	 * @param parameterOrChoiceName the name of a parameter/choice
421 	 * @return true if the parameter is a choise parameter, false otherwise.
422 	 */
423 	public static boolean isChoice(Object messageOrParameterDefinition, String parameterOrChoiceName) {
424 		boolean result = false;
425 		List<Object> parameterOrChoiceList = new LinkedList<Object>();
426 		if (messageOrParameterDefinition instanceof MessageDefinition){
427 			parameterOrChoiceList = ((MessageDefinition) messageOrParameterDefinition).getParameterOrChoice();
428 		}
429 		else if (messageOrParameterDefinition instanceof ParameterDefinition){
430 			parameterOrChoiceList = ((ParameterDefinition) messageOrParameterDefinition).getParameterOrChoice();
431 		}
432 		for (Object o : parameterOrChoiceList){
433 			String name = "";
434 			if (o instanceof ChoiceReference){
435 				ChoiceReference choiceReference = (ChoiceReference) o;
436 				name = choiceReference.getType();
437 				result = true;
438 			}
439 			else if (o instanceof ParameterReference){
440 				ParameterReference parameterReference = (ParameterReference) o;
441 				name = parameterReference.getType();
442 				result = false;
443 			}
444 			if (name.equals(parameterOrChoiceName)){
445 				break;
446 			}
447 		}
448 		return result;
449 	}
450 }