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
64 continue;
65 }
66 else {
67
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
103 continue;
104 }
105 else {
106
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
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
153
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
169
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();
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
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
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
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
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 }