View Javadoc

1   package gov.nasa.pds.ltdt.gui.util;
2   
3   import gov.nasa.pds.ltdt.gui.KeywordMap;
4   import gov.nasa.pds.ltdt.gui.KeywordProperty;
5   import gov.nasa.pds.ltdt.gui.MainWindow;
6   import gov.nasa.pds.ltdt.gui.configuration.LTDTKeys;
7   import gov.nasa.pds.tools.dict.Definition;
8   import gov.nasa.pds.tools.dict.Dictionary;
9   import gov.nasa.pds.tools.dict.DictionaryWriter;
10  import gov.nasa.pds.tools.dict.ElementDefinition;
11  import gov.nasa.pds.tools.dict.GroupDefinition;
12  import gov.nasa.pds.tools.dict.ObjectDefinition;
13  import gov.nasa.pds.tools.dict.parser.DictionaryParser;
14  import gov.nasa.pds.tools.label.parser.ParseException;
15  
16  import java.io.File;
17  import java.io.IOException;
18  import java.net.MalformedURLException;
19  import java.net.URL;
20  import java.text.DateFormat;
21  import java.text.SimpleDateFormat;
22  import java.util.ArrayList;
23  import java.util.Date;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.Set;
28  
29  
30  
31  
32  /***
33   * Utility class to store data dictionary related handling.
34   * @author jwang
35   *
36   */
37  public class DictionaryUtility {
38  	
39  	private static KeywordMap km = null;
40  	private static KeywordProperty kp = null;
41  	
42  	private static Dictionary mDictionary = null;
43  	
44  	private static StringBuffer errElement = null;
45  	private static StringBuffer errObject = null;
46  	
47  	/***
48  	 * Splits a concatenated string of dictionary names into an array of individual names. 
49  	 * @param dict A string of dictionary names delimited by ';'
50  	 * @return A String array of dictionary names, returns null if no dictionary info received
51  	 */
52  	public static String[]  getDictionaryNameArray (String dict) {
53  		
54  		List tempArray = new ArrayList();	
55  		if (dict!=null) {
56  			String[] dictListArray=dict.split(LTDTKeys.DICTIONARY_DELIMITER);
57  			int t=0;
58  
59  			for (int i=0; i<dictListArray.length; i++) {
60  				dictListArray[i] = dictListArray[i].trim();
61  				
62  				if (dictListArray[i]==null || dictListArray[i].equals("null") || dictListArray[i].length()==0) {
63  					// do nothing
64  					continue;
65  				} 				
66  				else {
67  					//tempArray.add(dictListArray[i]+LTDTKeys.DICTIONARY_DELIMITER);
68  					tempArray.add(dictListArray[i]);
69  				}			
70  			}			
71  		}
72  		
73  		String[] st=null;
74  		if (tempArray.size() >0) {
75  			st = new String[tempArray.size()];
76  			for (int n=0; n<tempArray.size(); n++)
77  				st[n]=(String)tempArray.get(n);
78  			tempArray.clear();
79  		}
80  		
81  		
82  		return st;
83  	}
84  	
85  	/***
86  	 * Splits a concatenated string of dictionary names into a list of individual names.
87  	 * @param dict
88  	 * @return An array of individual dictionary names
89  	 */
90  	public static ArrayList  getDictionaryNameList (String dict) {
91  		List tempArray = new ArrayList();
92  		
93  		if (dict!=null) {
94  			String[] dictListArray=dict.split(LTDTKeys.DICTIONARY_DELIMITER);
95  			int t=0;
96  
97  			for (int i=0; i<dictListArray.length; i++) {
98  				
99  				dictListArray[i] = dictListArray[i].trim();
100 				
101 				if (dictListArray[i]==null || dictListArray[i].equals("null") || dictListArray[i].length()==0) {
102 					// do nothing
103 					continue;
104 				} 				
105 				else {
106 					//tempArray.add(dictListArray[i]+":");
107 					tempArray.add(dictListArray[i]);
108 				}
109 				
110 			}
111 			
112 			
113 		}
114 				
115 		return (ArrayList)tempArray;
116 	}
117 	
118 	/***
119 	 * Input a list of dictionary names, combined the non-null names into a
120 	 * text string with ':' as delimiter
121 	 * @param dictList
122 	 * @return A string of dictionary names concatenated by ":"
123 	 */
124 	public static String getDictionaryNameString (List dictList) throws IOException {
125 		String dictionaryStr = "";	
126 		
127 		if (dictList!=null) {
128 			for (int i=0; i<dictList.size(); i++) {
129 				if (!"null".equals(dictList.get(i))) {
130 					//dictionaryStr= dictionaryStr + dictList.get(i)+LTDTKeys.DICTIONARY_DELIMITER;
131 					File fn = new File((String)dictList.get(i));
132 					dictionaryStr= dictionaryStr + fn.getCanonicalPath() +LTDTKeys.DICTIONARY_DELIMITER;
133 				}
134 			}
135 		}
136 		
137 		return dictionaryStr;
138 	}
139 
140 	/***
141 	 * Special formatting. Swap strings on either side of :  It's assumed that the input 
142 	 * string has the input format <A>:<B>   or <A>:<B>--<C> The output would be
143 	 * <B>:<A> or <B>:<A>--<C>
144 	 * @param in Input string
145 	 * @return Reformatted string
146 	 */
147 	public static String swap (String in) {
148 		String[] str1, str2;
149 		String tmpStr ="";
150 		String swappedString = "";	
151 
152 		// input format: <A>:<B>--<C> 
153 		// output format: <B>:<A>--<C>
154 		if (in.indexOf("--")!=-1) {
155 			str1 = in.split("--");
156 			tmpStr = str1[1];
157 			
158 			str2 = str1[0].split(":");
159 		
160 			if (str2.length<2) { 
161 				swappedString = str2[0]+"--"+tmpStr;
162 			}
163 			else {
164 				swappedString = str2[1]+":"+str2[0]+"--"+tmpStr;
165 			}
166 		}
167 		
168 		// input format: <A>:<B>
169 		// output format: <B>:<A>
170 		else {
171 			
172 			str2 = in.split(":");
173 			
174 			if (str2.length<2) { 
175 				swappedString = str2[0];
176 			}
177 			else {
178 				swappedString = str2[1]+":"+str2[0];			
179 			}
180 		}
181 		
182 		return swappedString;
183 	}
184 
185 
186 	/***
187 	 * Based on a keyword map to populate the full keyword listing window
188 	 * @param window
189 	 */
190 	public static void populateDictionaryFullListingPane (MainWindow window) {
191 		
192 		List all = (ArrayList)window.dictionaryMap.getTreeEntryIDList();
193 		
194 		if (all!=null) {
195 			int mapSize=all.size();
196 			List listS = new ArrayList(); // to hold the list to be displayed in the list window
197 			
198 			for (int i=0; i<mapSize; i++) {
199 				
200 				listS.add (i, (DictionaryUtility.swap((String)all.get(i))).split("--")[0]);
201 			}
202 
203 
204 			window.keywordFullLong=null;
205 			window.keywordFullShort = null;
206 			window.keywordSubLong = null;
207 			window.keywordSubShort = null;
208 			window.keywordDisplayLong=null;
209 			window.keywordDisplayShort=null;
210 
211 			
212 			window.keywordFullLong = (String[])all.toArray(new String[0]);
213 			window.keywordSubLong = (String[])all.toArray(new String[0]);
214 			window.keywordDisplayLong = (String[])all.toArray(new String[0]);
215 			
216 			window.keywordFullShort = (String[])listS.toArray(new String[0]);
217 			window.keywordSubShort = (String[])listS.toArray(new String[0]);
218 			window.keywordDisplayShort = (String[])listS.toArray(new String[0]);
219 			
220 	
221 		
222 			all.clear();
223 			listS.clear();
224 		}
225 	}
226 	
227 	/***
228 	 * Building a new object/element definition
229 	 * 
230 	 * @param kwdDef  An instance of a definition
231 	 * @return        List of attributes for a definition
232 	 */
233 	public static ArrayList buildKeywordDefinitionList (Definition kwdDef) {
234 		List klist = null;
235 		List dlist = null;
236 		String defStr=null;
237 		ObjectDefinition oDef;
238 		ElementDefinition eDef;
239 		GroupDefinition gDef;
240 		String tempstr = null;
241 		
242 		
243 		if (kwdDef instanceof ObjectDefinition) {
244 			
245 			klist = new ArrayList();			
246 			oDef = (ObjectDefinition)kwdDef;
247 			
248 			tempstr = oDef.getObjectType().trim();
249 			if (tempstr.length()>0 ) {
250 				klist.add("OBJECT_TYPE = "+tempstr);
251 				klist.add("");
252 			}
253 			
254 			dlist = oDef.getRequiredObjects();
255 			if (dlist.size()>0) {
256 				defStr = "{"+Utility.list2stringLF(dlist)+"}";
257 				klist.add("REQUIRED_OBJECT_SET = "+defStr);
258 				klist.add("");
259 			}				
260 						
261 			dlist= oDef.getRequiredElements();
262 			if (dlist.size()>0) {
263 				defStr = "{"+Utility.list2stringLF(dlist)+"}";
264 				klist.add("REQUIRED_ELEMENT_SET = "+defStr);
265 				klist.add("");
266 			}			
267 						
268 			dlist= oDef.getOptionalObjects();
269 			if (dlist.size()>0) {
270 				defStr = "{"+Utility.list2stringLF(dlist)+"}";
271 				klist.add("OPTIONAL_OBJECT_SET = "+defStr);
272 				klist.add("");
273 			}
274 		
275 			dlist= oDef.getOptionalElements();
276 			if (dlist.size()>0) {
277 				defStr = "{"+Utility.list2stringLF(dlist)+"}";
278 				klist.add("OPTIONAL_ELEMENT_SET = "+defStr);
279 				klist.add("");
280 			}		
281 		}
282 		else if (kwdDef instanceof ElementDefinition) {
283 			eDef = (ElementDefinition)kwdDef;
284 
285 			klist = collectElementDefinitionList(eDef);
286 			
287 
288 		}
289 		else if (kwdDef instanceof GroupDefinition) {
290 			gDef = (GroupDefinition)kwdDef;
291 			
292 			klist = new ArrayList();
293 		}
294 				
295 		//if (dlist!=null) dlist.clear();
296 		
297 		return (ArrayList) klist;
298 	}
299 	
300 	/***
301 	 * Collects detailed definitions for an Element
302 	 * @param eDef
303 	 * @return
304 	 */
305 	private static ArrayList collectElementDefinitionList(ElementDefinition eDef) {
306 		List definitionArray = new ArrayList();
307 
308 
309 			
310 		if (eDef.getValueType()!= null) {
311 			definitionArray.add("STANDARD_VALUE_TYPE = "+eDef.getValueType());
312 			definitionArray.add("");
313 		}
314 		
315 		if (eDef.hasValidValues()) {
316 
317 				definitionArray.add("STANDARD_VALUE_SET = {"+System.getProperty("line.separator")+Utility.list2quotedSet((List)eDef.getValues())+"}");
318 				definitionArray.add("");
319 		}
320 		
321 		if (eDef.hasMinimum()) {
322 			definitionArray.add("MINIMUM = "+eDef.getMinimum().toString());
323 			definitionArray.add("");
324 		}
325 		
326 		if (eDef.hasMaximum()) {
327 			definitionArray.add("MAXIMUM = "+eDef.getMaximum().toString());
328 			definitionArray.add("");
329 		}
330 		
331 		definitionArray.add("MINIMUM_LENGTH = "+eDef.getMinLength());
332 		definitionArray.add("");
333 		
334 		definitionArray.add("MAXIMUM_LENGTH = "+eDef.getMaxLength());
335 		definitionArray.add("");
336 		
337 		if (eDef.getDataType()!=null) {
338 			definitionArray.add("GENERAL_DATA_TYPE = "+ eDef.getDataType());
339 			definitionArray.add("");
340 		}
341 					
342 		if (eDef.getUnitId()!=null) {
343 			definitionArray.add("UNIT_ID = "+eDef.getUnitId());
344 			definitionArray.add("");
345 		}
346 		
347 		return (ArrayList)definitionArray;
348 	}
349 
350 	
351 	/***
352 	 * generates a block of structured text based on 'keyword'
353 	 * if the keyword is an object, add the start and end of an object block
354 	 *  and required elements within the block.
355 	 *   e.g. OBJECT = <keyword>
356 	 *        END_OBJECT = <keyword>
357 	 * if the keyword is an element, return it with "=" appended with a substitution variable
358 	 *   e.g. <NEW> = ${NEW}
359 	 * 
360 	 * An empty string is returned if the keyword is not found.
361 	 * 
362 	 * @param window
363 	 * @param keyword
364 	 * @return keyword text block
365 	 */
366 	public static String list2editblock(MainWindow window, String keyword, StringBuffer message) {	
367 
368 		StringBuffer buffer = new StringBuffer();
369 		errObject = new StringBuffer();
370 		errElement = new StringBuffer();
371 		//StringBuffer message = new StringBuffer();
372 		
373 		mDictionary = window.mDictionary;
374 		Definition def = window.mDictionary.getDefinition(keyword);
375 		
376 		String formattedText=null;
377 		
378 		if (def instanceof ElementDefinition) {
379 			formattedText = formatElementLine((ElementDefinition)def);
380 		}
381 		else if (def instanceof ObjectDefinition) {		
382 			formattedText = formatObjectBlock ((ObjectDefinition)def, buffer, def.getIdentifier()).toString();
383 		}
384 		
385 		if (errObject.length()>0 || errElement.length()>0) {
386 			message.append ("Please define the following keywords before validating template ..."+System.getProperty("line.separator"));
387 			if (errObject.length()>0 ) {			
388 				message.append(System.getProperty("line.separator")+"Undefined objects: "+System.getProperty("line.separator"));
389 				message.append(errObject);
390 			}
391 			if (errElement.length()>0) {
392 				message.append(System.getProperty("line.separator")+"Undefined elements: "+System.getProperty("line.separator"));
393 				message.append(errElement);			
394 			}
395 			
396 			
397 		}
398 		
399 		if (formattedText.length()>0) return formattedText;
400 		else return keyword;
401 	}
402 	
403 	/***
404 	 * Format an element to a valid template format. 
405 	 * It's assumed the element exists in a dictionary
406 	 * 
407 	 * @param def
408 	 * @return formatted element line
409 	 */
410 	static String formatElementLine (ElementDefinition def) {
411 		String elementLine = null;
412 		boolean quoted = false;
413 		String generalDataType = def.getDataType();
414 		String quoteSymbol = null; 
415 		List quotedDataTypeList = new ArrayList();
416 		
417 		for (int i=0; i<LTDTKeys.QUOTEDTYPEARRAY.length; i++) {
418 			quotedDataTypeList.add(LTDTKeys.QUOTEDTYPEARRAY[i]);
419 		}
420 		
421 		if (quotedDataTypeList.contains(generalDataType)) {
422 			quoteSymbol = LTDTKeys.QUOTEDTYPESYMBOL;
423 		}
424 		else quoteSymbol = "";
425 		
426 		String str = def.getIdentifier();
427 		
428 		elementLine = System.getProperty("line.separator")+def.getIdentifier()+" = "+
429 			quoteSymbol+"${"+def.getIdentifier()+"}"+quoteSymbol;
430 			
431 		return elementLine;
432 	}
433 	
434 	/***
435 	 * Format an element line space holder line in a template. No data type checking is done, 
436 	 * therefore, element values are not quoted.  The format is always
437 	 *        <ELEMENTNAME> = ${<ELEMENTNAME>}
438 	 * @param elementName
439 	 * @return  formatted line with variable name filled in
440 	 */
441 	static String formatElementLineSpaceholder (String elementName) {
442 		String elementLine = null;
443 		
444 		elementLine = System.getProperty("line.separator")+elementName+" = ${"+elementName+"}";
445 		return elementLine;
446 		
447 	}
448 	
449 	
450 	/***
451 	 * Format an Object block
452 	 * @param def
453 	 * @param buf
454 	 * @param objectName
455 	 * @return formatted Object block
456 	 */
457 	static StringBuffer formatObjectBlock (ObjectDefinition def, StringBuffer buf, String objectName) {
458 		
459 		String objectKeyword = objectName;
460 		
461 		if (def!=null) {
462 			buf.append(System.getProperty("line.separator")+"OBJECT = "+def.getIdentifier());	
463 			
464 			List reqElement = def.getRequiredElements();
465 			
466 			for (Iterator it=reqElement.iterator(); it.hasNext();) {
467 				
468 				String elementKeyword = (String)it.next();
469 				ElementDefinition elementDefinition = (ElementDefinition)mDictionary.getDefinition(elementKeyword);
470 				
471 				// if element definition exist, add it in. Otherwise, put a space holder and give a warning
472 				if (elementDefinition!=null) {
473 					buf.append(formatElementLine(elementDefinition));
474 				}			
475 				else {
476 					errElement.append(elementKeyword+" ");
477 					buf.append(formatElementLineSpaceholder(elementKeyword));
478 					
479 				}		
480 	
481 			}
482 			
483 			List reqObject = def.getRequiredObjects();
484 			
485 			for (Iterator it=reqObject.iterator(); it.hasNext();) {
486 	
487 				String keyword=(String)it.next();
488 				ObjectDefinition objectDefinition = (ObjectDefinition)mDictionary.getDefinition(keyword);				
489 				
490 				buf = formatObjectBlock(objectDefinition, buf, keyword);				
491 				
492 			}
493 			
494 			buf.append(System.getProperty("line.separator")+"END_OBJECT = "+def.getIdentifier());
495 
496 			
497 		}
498 		else   {
499 			errObject.append(objectKeyword+" ");
500 			buf.append(System.getProperty("line.separator")+"OBJECT = "+objectName);
501 			
502 			buf.append(System.getProperty("line.separator")+"END_OBJECT = "+objectName);
503 
504 		}
505 		
506 
507 		
508 		return buf;
509 	}
510 	
511 	
512 	
513 	/***
514 	 * Merge a list of dictionary into the original one 
515 	 * @param originalDictionary
516 	 * @param dictList
517 	 * @return Merged dictionary
518 	 * @throws MalformedURLException
519 	 * @throws ParseException
520 	 * @throws IOException
521 	 */
522 	public static Dictionary MergeDictionaryList (Dictionary originalDictionary, List dictList) 
523 		throws MalformedURLException, ParseException, IOException {
524 		
525 		Dictionary vDictionary = originalDictionary;
526 		boolean started = false;
527 		if (dictList.size() >0) {
528 			if (vDictionary != null) {
529 				for (int i=0; i<dictList.size(); i++) {
530 					vDictionary.merge(DictionaryParser.parse((URL)dictList.get(i)), true);
531 				}
532 			}
533 			else {
534 				for (int i=0; i<dictList.size(); i++) {
535 					if (!started) {
536 						vDictionary = DictionaryParser.parse((URL)dictList.get(i));
537 						started = true;
538 					}
539 					else {
540 						vDictionary.merge(DictionaryParser.parse((URL)dictList.get(i)), true);
541 					}
542 				
543 				}
544 			}
545 		
546 		
547 		}
548 		return vDictionary;
549 	}
550 	
551 	/***
552 	 * Merge a new dictionary into an existing one
553 	 * @param originalDictionary
554 	 * @param newDictionary
555 	 * @return merged dictionary
556 	 */
557 	public static Dictionary MergeDictionary (Dictionary originalDictionary, Dictionary newDictionary) {
558 		
559 		Dictionary vDictionary = originalDictionary;
560 		
561 		if (newDictionary != null ) {
562 			if (vDictionary != null) {
563 				vDictionary.merge(newDictionary, true);	
564 			}
565 			else {
566 				vDictionary = newDictionary;
567 			}
568 		}
569 		
570 		return vDictionary;
571 	}
572 	
573 	/***
574 	 * Merge a dictionary at a location into an existing one
575 	 * @param originalDictionary
576 	 * @param location
577 	 * @return merged dictionary
578 	 * @throws ParseException
579 	 * @throws IOException
580 	 */
581 	public static Dictionary MergeDictionary (Dictionary originalDictionary, URL location) 
582 			throws ParseException, IOException {
583 		Dictionary vDictionary = originalDictionary;
584 		Dictionary newDictionary = DictionaryParser.parse(location);
585 		
586 		if (newDictionary != null ) {
587 			if (vDictionary != null) {
588 				vDictionary.merge(newDictionary, true);	
589 			}
590 			else {
591 				vDictionary = newDictionary;
592 			}
593 		}
594 		
595 		return vDictionary;
596 	}
597 	
598 	/***
599 	 * Output WDD to a file.
600 	 * @param window
601 	 * @param wddFileName
602 	 * @throws IOException
603 	 */
604 	public static void writeWDD (MainWindow window, String wddFileName) throws IOException {
605 		
606 		
607 		StringBuffer wddHeader = new StringBuffer();
608 		
609 		setWDDSpecificValues (window, wddHeader);
610 		
611 		File wddFile = new File(wddFileName);
612 		wddFile.createNewFile();
613 		window.WDD.setInformation(wddHeader.toString());
614 		DictionaryWriter.writeDictionary(window.WDD, wddFile);		
615 	}
616 	
617 	/***
618 	 * Set values for attributes for specifically for WDD only
619 	 * Such as status_type, dictionary header, etc
620 	 * @param window
621 	 * @param wddHeader
622 	 */
623 	private static void setWDDSpecificValues (MainWindow window, StringBuffer wddHeader) {
624 		
625 		Date today = new Date();
626 		DateFormat df = new SimpleDateFormat("MMM dd yyyy");
627 		
628 		wddHeader.append("/* Working Data Dictionary */\n");
629 		wddHeader.append("/* Generated by: Label Template Design Tool */\n");
630 		wddHeader.append("/* Generated on: "+df.format(today)+" */\n\n");
631 		
632 		// WDD entries are in PROPOSED status type
633 		setStatusType (window.WDD, LTDTKeys.WDDFINALSTATUSTYPE);
634 	}
635 	
636 	/***
637 	 * Set status type to WDDSTATUSTYPE to each definition within a dictionary
638 	 * @param dictionary
639 	 * @param statusType
640 	 */
641 	public static void setStatusType (Dictionary dictionary, String statusType) {
642 		
643 		Map dMap = dictionary.getDefinitions();
644 		Set keys = dMap.keySet();
645 		
646 		for (Iterator it=keys.iterator(); it.hasNext();) {
647 			Definition def = (Definition)dMap.get(it.next());
648 			def.setStatusType(statusType);
649 
650 		}
651 		
652 	}
653 }