Subversion Repositories SmartDukaan

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
17 naveen 1
/**
2
 * 
3
 */
4
package in.shop2020.metamodel.util;
5
 
18 naveen 6
import java.io.BufferedReader;
7
import java.io.FileReader;
19 naveen 8
import java.io.IOException;
18 naveen 9
import java.io.LineNumberReader;
10
import java.util.ArrayList;
19 naveen 11
import java.util.Collection;
18 naveen 12
import java.util.HashMap;
13
import java.util.Iterator;
14
import java.util.List;
15
import java.util.Map;
19 naveen 16
import java.util.TreeMap;
18 naveen 17
import java.util.logging.Level;
18
 
20 naveen 19
import in.shop2020.metamodel.core.Bullet;
20
import in.shop2020.metamodel.core.BulletDataObject;
21
import in.shop2020.metamodel.core.CompositeDataObject;
22
import in.shop2020.metamodel.core.EnumDataObject;
23
import in.shop2020.metamodel.core.PrimitiveDataObject;
19 naveen 24
import in.shop2020.metamodel.definitions.BulletDefinition;
17 naveen 25
import in.shop2020.metamodel.definitions.Catalog;
26
import in.shop2020.metamodel.definitions.Category;
19 naveen 27
import in.shop2020.metamodel.definitions.CompositeDefinition;
20 naveen 28
import in.shop2020.metamodel.definitions.CompositePartDefinition;
18 naveen 29
import in.shop2020.metamodel.definitions.DatatypeDefinition;
17 naveen 30
import in.shop2020.metamodel.definitions.DefinitionsContainer;
18 naveen 31
import in.shop2020.metamodel.definitions.EditorialImportance;
19 naveen 32
import in.shop2020.metamodel.definitions.EnumDefinition;
18 naveen 33
import in.shop2020.metamodel.definitions.FeatureDefinition;
34
import in.shop2020.metamodel.definitions.SlideDefinition;
35
import in.shop2020.metamodel.definitions.Unit;
36
import in.shop2020.util.Utils;
17 naveen 37
 
38
import org.apache.commons.lang.ArrayUtils;
39
import org.apache.commons.lang.StringUtils;
40
 
41
/**
42
 * CN - Content Tool
43
 * Imports and exports content. Validates against content model
44
 * 
45
 * @author naveen
46
 *
47
 */
48
public class CN {
49
	public static final String CONTENT_SRC_TXT_PATH = 
50
		"/home/naveen/workspace/eclipse/webapp/src/content/txt/";
51
	public static final String CONTENT_SRC_HTML_PATH = 
52
		"/home/naveen/workspace/eclipse/webapp/src/content/html/";
53
	public static final String CONTENT_SRC_XML_PATH = 
54
		"/home/naveen/workspace/eclipse/webapp/src/content/xml/";
55
	public static final String CONTENT_DB_PATH =  
56
		"/home/naveen/workspace/eclipse/webapp/db/entities/";
18 naveen 57
 
17 naveen 58
	// Known patterns
59
	public static final String PATTERN_LEVEL_1 = "* ";
60
	public static final String PATTERN_LEVEL_2 = "   * ";
61
	public static final String PATTERN_LEVEL_3 = "      * ";
62
	public static final String PATTERN_LEVEL_4 = "         * ";
63
 
64
	private long categoryID;
65
	private String srcFile;
66
	private String dbFile;
67
 
19 naveen 68
	private Map<String, Long> slideNameToSlideDefID = 
69
		new HashMap<String, Long>();
70
 
71
	private Map<String, Long> slideNameFeatureNameToFeatureDefID =
72
		new HashMap<String, Long>();
73
 
20 naveen 74
	private Map<String, List<Bullet>> slideNameFeatureNameToBullets =
75
		new HashMap<String, List<Bullet>>();
19 naveen 76
 
17 naveen 77
	/**
78
	 * @param args
79
	 */
80
	public static void main(String[] args) throws Exception {
81
		String[] commands = new String[] {"show", "import"};
82
 
83
		String usage = "Usage: CN ["+ StringUtils.join(commands, "|") +
84
			"] {Category ID} {Content file name}\n" + 
85
			"Note:Only text files for now";
86
 
87
		if(args.length < 3) {
88
			System.out.println(usage);
89
			System.exit(-1);
90
		}
18 naveen 91
		Utils.logger.info("CN "+ args[0] + " " + args[1]+ " " + args[2]);
92
 
17 naveen 93
		String inputCommand = args[0];
94
		String inputCategoryID = args[1];
95
		String inputFilename = args[2];
96
 
97
		if(!ArrayUtils.contains(commands, inputCommand)) {
98
			System.out.println(usage);
99
			System.exit(-1);
100
		}
101
 
102
		long categoryID = new Long(inputCategoryID).longValue();
103
		CN cn = new CN(categoryID, inputFilename);
104
		if(inputCommand.equals("import")) {
105
			cn.importEntity();
106
		}
107
		else if(inputCommand.equals("show")) {
108
			cn.showEntity();
109
		}
110
	}
111
 
112
	/**
113
	 * 
114
	 * @param categoryID
115
	 * @param fileName
116
	 */
117
	public CN(long categoryID, String fileName) {
118
		this.categoryID = categoryID;
119
 
120
		this.srcFile = CONTENT_SRC_TXT_PATH + fileName + ".txt";
121
		this.dbFile = CONTENT_DB_PATH + "entities" + ".ser";
122
	}
123
 
124
	/**
125
	 * 
126
	 * @throws Exception
127
	 */
18 naveen 128
	public void importEntity() throws Exception {		
129
		//this.test();
130
		Utils.logger.info(this.srcFile);
17 naveen 131
 
18 naveen 132
		FileReader fileReader = new FileReader(this.srcFile);
133
		BufferedReader lineReader = new BufferedReader(fileReader);
134
		LineNumberReader reader = new LineNumberReader(lineReader);
17 naveen 135
 
19 naveen 136
		List<String> allLines = new ArrayList<String>();
137
 
18 naveen 138
		// 1 Collect all candidate slide names
19 naveen 139
		// Order of keys need to be restored
140
		Map<Integer, String> candidateSlideNames = 
141
			new TreeMap<Integer, String>();
142
 
143
		int lineCount = 0;
18 naveen 144
		while(true) {
19 naveen 145
			String line = reader.readLine();			
18 naveen 146
			if(line == null) {
147
				break;
148
			}
149
 
19 naveen 150
			allLines.add(line);
151
			lineCount++;
152
 
18 naveen 153
			if(line.isEmpty()) {
154
				continue;
155
			}
156
 
157
			int lineNumber = reader.getLineNumber();
158
 
159
			//Utils.logger.info(line);
160
			//Utils.logger.info("lineNumber="+lineNumber);
161
 
162
			// RE-VISIT
163
			// 1.1 Slide names starting with Alpha
164
			//Utils.logger.info(line.substring(0, 1));
165
			if(StringUtils.isAlpha((line.substring(0, 1)))) {
166
				//Utils.logger.info(line);
167
				//Utils.logger.info("Level 0");
168
 
169
				candidateSlideNames.put(new Integer(lineNumber), line);
170
			}
171
		}
19 naveen 172
 
173
		lineReader.close();
174
 
175
		Utils.logger.info("lineCount=" + lineCount);
18 naveen 176
		Utils.logger.info(candidateSlideNames.toString());
17 naveen 177
 
18 naveen 178
		// 2 Filter and validate parent slide names
179
		Map<Integer, String> slideNames = 
180
			this.processSlides(candidateSlideNames);
181
 
182
		Utils.logger.info(slideNames.toString());
183
 
19 naveen 184
		// 3 Collect all children slides
185
		// 4 Filter and validate children slide names
18 naveen 186
		// TODO
187
 
19 naveen 188
		// 5 Collect all Features for a slide
189
		// 5.1 Find line number range between which content for feature is found
190
		Map<String, int[]> featureLineNumberRangePerSlide = 
191
			new HashMap<String, int[]>();
192
 
193
		Utils.logger.info("slideNames.keySet=" + 
194
				slideNames.keySet().toString());
18 naveen 195
 
19 naveen 196
		Integer[] slideLineNumbers = slideNames.keySet().toArray(
197
				new Integer[0]);
18 naveen 198
 
19 naveen 199
		for(int i=0; i<slideLineNumbers.length-1; i++) {
200
			int from = slideLineNumbers[i]+1;
201
			int to = slideLineNumbers[i+1]-1;
202
			Utils.logger.info("from=" + from + " to=" + to);
203
 
204
			String tSlideName = slideNames.get(
205
					new Integer(slideLineNumbers[i]));
206
 
207
			Utils.logger.info("tSlideName=" + tSlideName);
208
 
209
			featureLineNumberRangePerSlide.put(tSlideName, 
210
					new int[] {from, to});
211
		}
212
 
213
		// For last slide
214
		Utils.logger.info("tSlideName=" + 
215
				slideNames.get(new Integer(
216
						slideLineNumbers[slideLineNumbers.length-1])));
217
 
218
		Utils.logger.info("lineNumbers[lineNumbers.length-1]=" + 
219
				slideLineNumbers[slideLineNumbers.length-1]);
220
 
221
		Utils.logger.info(
222
			"from=" + (slideLineNumbers[slideLineNumbers.length-1]+1) + " to=" +
223
			(lineCount-1));
224
 
225
		featureLineNumberRangePerSlide.put(
226
			slideNames.get(
227
				new Integer(slideLineNumbers[slideLineNumbers.length-1])), 
228
				new int[] {(slideLineNumbers[slideLineNumbers.length-1] + 1), 
229
				(lineCount-1)});
230
 
231
		Utils.logger.info("featureLineNumberRangePerSlide=" + 
232
				featureLineNumberRangePerSlide.toString());
233
 
234
		// 6 Filter and validate features
235
		DefinitionsContainer defs = 
236
			Catalog.getInstance().getDefinitionsContainer();
237
 
238
		Map<String, Map> slideFeatureLabels = 
239
			new HashMap<String, Map>();
240
 
241
		for(String slideName : slideNames.values()) {
242
			//Utils.logger.info("slideName=" + slideName);
243
			List<SlideDefinition> slideDefs = 
244
				defs.getSlideDefinition(slideName);
245
 
246
			if(slideDefs == null) {
247
				continue;
248
			}
249
 
250
			if (slideDefs.isEmpty()) {
251
				continue;
252
			} 
253
 
254
			// RE-VISIT
255
			// Pick the first
256
			Utils.logger.info("slideDef=" + slideDefs.get(0));
257
			Long slideID = slideDefs.get(0).getID();
258
			this.slideNameToSlideDefID.put(slideName, slideID);
259
 
260
			Map<Integer, String> featureLabels = 
261
				this.processFeature(allLines, slideDefs.get(0), 
262
					featureLineNumberRangePerSlide.get(slideName));
263
 
264
			// Find feature definition IDs
265
			for(String featureLabel : featureLabels.values()) {
266
				FeatureDefinition featureDef = defs.getFeatureDefinition(
267
						slideID.longValue(), featureLabel);
268
 
269
				this.slideNameFeatureNameToFeatureDefID.put(
270
						(slideName + "_" + featureLabel), 
271
						new Long(featureDef.getID()));
272
			}
273
 
274
			slideFeatureLabels.put(slideName, featureLabels);
275
		}
276
 
277
		Utils.logger.info("slideFeatureLabels=" + slideFeatureLabels);
278
 
279
		Utils.logger.info("slideNameToSlideDefID=" + 
280
				this.slideNameToSlideDefID);
281
 
282
		Utils.logger.info("slideNameFeatureNameToFeatureDefID=" + 
283
				this.slideNameFeatureNameToFeatureDefID);
284
 
285
		// 7 Bullets
286
		// Collect all bullets
287
		for(String slideName : slideFeatureLabels.keySet()) {
288
			Map<Integer, String> featureLabels = 
289
				slideFeatureLabels.get(slideName);
290
 
291
			// 7.1 Find line number range between which content for bullets 
292
			// is found (per feature on this slide)
293
			Map<String, int[]> bulletLineNumberRangePerFeature = 
294
				this.getBulletLineRange(allLines, featureLabels);
295
 
296
			for(String featureLabel : bulletLineNumberRangePerFeature.keySet()){
297
 
298
				String key = slideName + "_" + featureLabel;
299
				Long featureDefID = 
300
					this.slideNameFeatureNameToFeatureDefID.get(key);
301
				FeatureDefinition featureDef = 
302
					defs.getFeatureDefinition(featureDefID.longValue());
303
 
304
				Long slideDefID = this.slideNameToSlideDefID.get(slideName);
305
				SlideDefinition slideDef = defs.getSlideDefinition(slideDefID);
306
 
307
				this.processBullets(allLines, 
308
						bulletLineNumberRangePerFeature.get(featureLabel), 
309
						featureDef, slideDef);
310
			}
311
		}
312
 
17 naveen 313
	}
314
 
315
	/**
316
	 * 
317
	 * @throws Exception
318
	 */
319
	public void showEntity() throws Exception {
320
	}
19 naveen 321
 
322
	/**
323
	 * 
324
	 * @param allLines
325
	 * @param bulletLineNumberRange
326
	 * @param featureDef
327
	 * @throws Exception 
328
	 */
329
	private void processBullets(List<String> allLines, 
330
			int[] bulletLineNumberRange, FeatureDefinition featureDef, 
331
			SlideDefinition slideDef) throws Exception {
332
 
333
		int from = bulletLineNumberRange[0];
334
		int to = bulletLineNumberRange[1];
335
 
336
		BulletDefinition bulletDef = featureDef.getBulletDefinition();
337
		Utils.logger.info("bulletDefinition=" + bulletDef);
338
 
339
		DefinitionsContainer defs = 
340
			Catalog.getInstance().getDefinitionsContainer();
341
 
342
		String crumb = "\"" + slideDef.getLabel() + "\" > \"" + 
343
			featureDef.getLabel() + "\"";
344
 
345
		// Enforce isMultivalue
346
		if(!bulletDef.isMultivalue() && (from != to)) {
347
			Utils.logger.severe("Only one bullet is allowed for " + crumb);
348
			return;
349
		}
18 naveen 350
 
19 naveen 351
		// If unit is defined
352
		Unit unitDef =  null;
353
		if(bulletDef.getUnitID() != 0L) {
354
			long unitID = bulletDef.getUnitID();
355
			unitDef = defs.getUnit(unitID);
356
			Utils.logger.info("unitDef=" + unitDef);
357
		}
358
 
359
		long datatypeDefID = bulletDef.getDatatypeDefinitionID();
360
		DatatypeDefinition datatypeDef = 
361
			defs.getDatatypeDefinition(datatypeDefID);
362
		Utils.logger.info("datatypeDef=" + datatypeDef);
363
 
20 naveen 364
 
365
		String key = slideDef.getLabel() + "_" + featureDef.getLabel();
366
		List<Bullet> bullets = 
367
			this.slideNameFeatureNameToBullets.get(key);
368
 
369
		if(bullets == null) {
370
			bullets = new ArrayList<Bullet>();
371
			this.slideNameFeatureNameToBullets.put(key, bullets);
372
		}
373
 
19 naveen 374
		// If primitive
375
		boolean isEnum = false;
376
		boolean isComposite = false;
377
		boolean isPrimitive = false;
378
		if(datatypeDef instanceof EnumDefinition) {
379
			isEnum = true;
380
		}
381
		else if(datatypeDef instanceof CompositeDefinition) {
382
			isComposite = true;
383
		}
384
		else {
385
			isPrimitive = true;
386
		}
387
 
388
		Utils.logger.info("isEnum=" + isEnum + " isComposite=" + isComposite +
389
				" isPrimitive=" + isPrimitive);
390
 
391
		for(int i=from; i<to+1; i++) {
392
			String line = allLines.get(i);
393
 
394
			if(!StringUtils.startsWith(line, CN.PATTERN_LEVEL_2)) {
395
				continue;
396
			}
397
 
398
			String bulletText = StringUtils.strip(StringUtils.stripStart(line, 
399
					CN.PATTERN_LEVEL_2));
400
			Utils.logger.info("bulletText=" + bulletText);
401
 
402
			// if no unit is defined for this bullet whole is treated as value
403
			String bulletValue = bulletText;
404
 
405
			// If unit is defined
406
			if(bulletDef.getUnitID() != 0L) {
407
 
408
				// Validate unit
409
				String[] parts = StringUtils.split(bulletText, " ");
410
				if(parts.length < 2) {
411
					Utils.logger.severe("Unit is missing, " + crumb + " = " + 
412
							bulletText);
413
 
414
					continue;
415
				}
416
 
417
				if(parts.length > 2) {
418
					Utils.logger.severe("Invalid value, " + crumb + " = " + 
419
							bulletText);
420
 
421
					continue;
422
				}
423
 
424
				bulletValue = parts[0];
425
				String unitValue = parts[1];
426
				Utils.logger.info("unitValue="+unitValue);
427
 
428
				if(!(unitValue.equalsIgnoreCase(unitDef.getShortForm()) ||
429
						unitValue.equalsIgnoreCase(unitDef.getFullForm()))) {
430
					Utils.logger.severe("Invalid unit, " + crumb + " = " + 
431
							bulletText);
432
 
433
					continue;
434
				}
435
			}
436
 
437
			// Validate bullet value
438
			Utils.logger.info("bulletValue=" + bulletValue);
439
			if(isPrimitive) {
20 naveen 440
				if(!this.validatePrimitive(bulletValue, datatypeDef, crumb)) {
441
					continue;
19 naveen 442
				}
443
 
20 naveen 444
				bullets.add(new Bullet(new PrimitiveDataObject(bulletValue)));
19 naveen 445
			}
446
 
447
			// Enum and fixed
448
			else if(isEnum && !bulletDef.isLearned()) {
449
				long enumValueID = defs.getEnumValueID(datatypeDef.getID(), 
450
						bulletValue);
451
 
452
				if(enumValueID == -1L) {
453
					Utils.logger.severe("Invalid value, " + crumb + " = " + 
454
							bulletValue);
455
 
456
					continue;
457
				}
458
 
20 naveen 459
				EnumDataObject enumDataObject = new EnumDataObject(enumValueID);
460
				bullets.add(new Bullet(enumDataObject));
19 naveen 461
			}
462
 
463
			// Composite
464
			else if(isComposite) {
20 naveen 465
				CompositeDefinition compositeDef = 
466
					(CompositeDefinition)datatypeDef;
19 naveen 467
 
20 naveen 468
				String separator = compositeDef.getSeparator();
469
				String[] compositeParts = 
470
					StringUtils.split(bulletValue, separator);
471
 
472
				List<CompositePartDefinition> compositePartDefs = 
473
					compositeDef.getCompositePartDefinitions();
474
 
475
				// Validate number of parts
476
				if(compositeParts.length != compositePartDefs.size()) {
477
					Utils.logger.severe("Invalid value, " + crumb + " = " + 
478
							bulletValue);
479
 
480
					continue;
481
				}
482
 
483
				// Remove spurious whitespaces
484
				boolean validPart = true;
485
				for(int j=0;j<compositeParts.length;j++) {
486
					compositeParts[j] = StringUtils.strip(compositeParts[j]);
487
					Utils.logger.info("compositeParts[j]=" + compositeParts[j]);
488
 
489
					// Validate each part
490
					// Each part can be enum or composite in itself
491
					// We will stick to primitive for now
492
					long partDatatypeDefID = 
493
						compositePartDefs.get(j).getDatatypeDefinitionID();
494
 
495
					DatatypeDefinition partDatatypeDef = 
496
						defs.getDatatypeDefinition(partDatatypeDefID);
497
					Utils.logger.info("partDatatypeDef=" + partDatatypeDef);
498
 
499
					if(!this.validatePrimitive(compositeParts[j], 
500
							partDatatypeDef, crumb)) {
501
						validPart = false;
502
						break;
503
					}
504
				}
505
 
506
				if(!validPart) {
507
					continue;
508
				}
509
 
510
				CompositeDataObject compositeDataObject = 
511
					new CompositeDataObject();
512
 
513
				for(int j=0;j<compositeParts.length;j++) {
514
					compositeDataObject.addPrimitiveDataObject(
515
							new PrimitiveDataObject(compositeParts[j]));
516
				}
517
 
518
				bullets.add(new Bullet(compositeDataObject));
19 naveen 519
			}
520
		}
521
 
20 naveen 522
		Utils.logger.info("slideNameFeatureNameToBullets=" + 
523
				this.slideNameFeatureNameToBullets);
19 naveen 524
	}
525
 
18 naveen 526
	/**
19 naveen 527
	 * 
20 naveen 528
	 * @param bulletValue
529
	 * @param datatypeDef
530
	 * @param crumb
531
	 */
532
	private boolean validatePrimitive(String bulletValue, 
533
			DatatypeDefinition datatypeDef, String crumb) {
534
		String dt = datatypeDef.getName();
535
		boolean valid = true;
536
 
537
		// integer
538
		if(dt.equals("integer")) {
539
			try {
540
				Integer.parseInt(bulletValue);
541
			}
542
			catch(NumberFormatException nfe) {
543
				Utils.logger.severe("Invalid integer value, " + crumb +
544
						" = " + bulletValue);
545
				valid = false;
546
			}
547
		}
548
 
549
		// decimal
550
		else if(dt.endsWith("decimal")) {
551
			try {
552
				Float.parseFloat(bulletValue);
553
			}
554
			catch(NumberFormatException nfe) {
555
				Utils.logger.severe("Invalid decimal value, " + crumb +
556
						" = " + bulletValue);
557
				valid = false;
558
			}
559
		}
560
 
561
		return valid;
562
	}
563
 
564
	// string
565
	// any thing goes
566
	/**
567
	 * 
19 naveen 568
	 * @param allLines
569
	 * @param featureLabels
570
	 * @return
571
	 */
572
	private Map<String, int[]> getBulletLineRange(List<String> allLines, 
573
			Map<Integer, String> featureLabels) {
574
		Utils.logger.info("allLines=" + allLines);
575
		Utils.logger.info("featureLabels=" + featureLabels);
576
 
577
		// 5.1 Find line number range between which content for feature is found
578
		Map<String, int[]> bulletLineNumberRangePerFeature = 
579
			new HashMap<String, int[]>();
580
 
581
		Utils.logger.info("featureLabels.keySet=" + 
582
				featureLabels.keySet().toString());
583
 
584
		Integer[] featureLineNumbers = featureLabels.keySet().toArray(
585
				new Integer[0]);
586
 
587
		for(int i=0; i<featureLineNumbers.length-1; i++) {
588
			String tFeatureLabel = featureLabels.get(
589
					new Integer(featureLineNumbers[i]));
590
 
591
			Utils.logger.info("tFeatureLabel=" + tFeatureLabel);
592
 
593
			int from = featureLineNumbers[i]+1;
594
			int to = featureLineNumbers[i+1]-1;
595
			Utils.logger.info("from=" + from + " to=" + to);
596
 
597
			bulletLineNumberRangePerFeature.put(tFeatureLabel, 
598
					new int[] {from, to});
599
		}
600
 
601
		// For last feature
602
		String lastFeatureLabel = featureLabels.get(
603
			new Integer(featureLineNumbers[featureLineNumbers.length-1]));
604
		Utils.logger.info("lastFeatureLabel=" + lastFeatureLabel);
605
 
606
		int lastFrom = featureLineNumbers[featureLineNumbers.length-1] + 1;
607
		Utils.logger.info("lastFrom=" + lastFrom);
608
 
609
		// First empty line from "lastFrom"
610
		int lastTo = lastFrom;
611
		while(true) {
612
			if(lastTo == (allLines.size() - 1)) {
613
				break;
614
			}
615
 
616
			String tLastLine = allLines.get(lastTo + 1);
617
			Utils.logger.info("tLastLine=" + tLastLine);
618
			if(tLastLine == null) {
619
				break;
620
			}
621
 
622
			if(!StringUtils.startsWith(tLastLine, CN.PATTERN_LEVEL_2)) {
623
				break;
624
			}
625
			lastTo++;
626
			Utils.logger.info("running lastTo=" + lastTo);
627
		}
628
 
629
		Utils.logger.info("lastFrom=" + lastFrom + " lastTo=" + lastTo);
630
 
631
		bulletLineNumberRangePerFeature.put(lastFeatureLabel, 
632
				new int[] {lastFrom, lastTo});
633
 
634
		Utils.logger.info("featureLineNumberRangePerSlide=" + 
635
				bulletLineNumberRangePerFeature.toString());		
636
 
637
		return bulletLineNumberRangePerFeature;
638
	}
639
 
640
 
641
	/**
642
	 * 
643
	 * @param allLines
644
	 * @param slideDef
645
	 * @param lineNumberRange
646
	 * @throws Exception
647
	 */
648
	private Map<Integer, String> processFeature(List<String> allLines, 
649
			SlideDefinition slideDef, 
650
			int[] lineNumberRange) throws Exception {
651
 
652
		int from = lineNumberRange[0];
653
		int to = lineNumberRange[1];
654
 
655
		Utils.logger.info("from=" + from + " to=" + to);
656
 
657
		int numberOfLines = (to - from);
658
		Utils.logger.info("numberOfLines=" + numberOfLines);
659
 
660
		Map<Integer, String> candidateFeatures = new TreeMap<Integer, String>();
661
		for(int i=from; i<(to+1); i++) {
662
			String line = allLines.get(i);
663
 
664
			if(StringUtils.startsWith(line, CN.PATTERN_LEVEL_1)) {
665
				//Utils.logger.info(line);
666
				//Utils.logger.info("Level 1");
667
				candidateFeatures.put(new Integer(i), 
668
						StringUtils.strip(StringUtils.strip(line, 
669
								CN.PATTERN_LEVEL_1)));
670
			}
671
		}
672
 
673
		Utils.logger.info("candidateFeatures=" + candidateFeatures);
674
 
675
		// Get all feature definitions for the slide
676
		DefinitionsContainer defs = 
677
			Catalog.getInstance().getDefinitionsContainer();
678
 
679
		List<FeatureDefinition> featureDefs = 
680
			defs.getFeatureDefinitions(slideDef.getID());
681
		Utils.logger.info("featureDefs=" + featureDefs);
682
 
683
		List<String> validFeatureLabels = new ArrayList<String>();
684
		for(int i=0; i<featureDefs.size(); i++) {
685
			validFeatureLabels.add(featureDefs.get(i).getLabel());
686
		}
687
		Utils.logger.info("validFeatureLabels=" + validFeatureLabels);
688
 
689
		// Filter valid features
690
		Map<Integer, String> featureLabels = new TreeMap<Integer, String>();
691
 
692
		// Discard if feature is not one of the valids
693
		// RE-VISIT
694
		for(Integer lineNumber : candidateFeatures.keySet()) {
695
			if(validFeatureLabels.contains(candidateFeatures.get(lineNumber))) {
696
				featureLabels.put(lineNumber, 
697
						candidateFeatures.get(lineNumber));
698
			}
699
		}
700
		Utils.logger.info("featureLabels=" + featureLabels);
701
 
702
		// Fetch all mandatory features
703
		List<FeatureDefinition> mandatoryFeatureDefs = 
704
			defs.getFeatureDefinitions(slideDef.getID(),
705
			EditorialImportance.MANDATORY);
706
 
707
		Utils.logger.info("mandatoryFeatureDefs=" + mandatoryFeatureDefs);
708
 
709
		// Severe error if mandatory features are not included
710
		for(FeatureDefinition featureDef : mandatoryFeatureDefs) {
711
			if(!featureLabels.values().contains(featureDef.getLabel())) {
712
				Utils.logger.severe("Mandatory feature \"" + 
713
						featureDef.getLabel() + "\" is missing");
714
			}
715
		}
716
 
717
		// Fetch all recommended features
718
		List<FeatureDefinition> recommendedFeatureDefs = 
719
			defs.getFeatureDefinitions(slideDef.getID(),
720
			EditorialImportance.RECOMMENDED);
721
 
722
		Utils.logger.info("recommendedFeatureDefs=" + recommendedFeatureDefs);
723
 
724
		// Warn if recommended features are not included
725
		for(FeatureDefinition featureDef : recommendedFeatureDefs) {
726
			if(!featureLabels.values().contains(featureDef.getLabel())) {
727
				Utils.logger.warning("Recommended feature \"" + 
728
						featureDef.getLabel() + "\" is missing");
729
			}
730
		}
731
 
732
		return featureLabels;
733
	}
734
 
735
	/**
18 naveen 736
	 * Filter and validate parent slide names
737
	 * 
738
	 * @param candidateSlideNames
739
	 * @return List<LineInfo>
740
	 * @throws Exception 
741
	 */
742
	private Map<Integer, String> processSlides(
743
			Map<Integer, String> candidateSlideLines) throws Exception {
744
 
19 naveen 745
		// Order of keys need to be restored
18 naveen 746
		Map<Integer, String> processedSlideLines = 
19 naveen 747
			new TreeMap<Integer, String>();
18 naveen 748
 
749
		// 1 Retrieve meta-data
750
		// 1.1 Retrieve all valid slide names in the content model
751
		DefinitionsContainer defs = 
752
			Catalog.getInstance().getDefinitionsContainer();
753
 
754
		Map<Long, SlideDefinition> slideDefs = defs.getSlideDefinitions();
755
		Iterator<SlideDefinition> itSlideDefs = slideDefs.values().iterator();
756
 
757
		List<String> validSlideNames = new ArrayList<String>();
758
		while(itSlideDefs.hasNext()) {
759
			SlideDefinition slideDef = itSlideDefs.next();
760
 
761
			// To avoid Introduction slide
762
			if(!slideDef.getLabel().isEmpty()) {
763
				validSlideNames.add(slideDef.getLabel());
764
			}
765
		}
766
		Utils.logger.info("validSlideNames=" + validSlideNames.toString());
767
 
768
		// 2 Rules
769
		// 2.1 Discard if slide is not one of the valids
770
		// REVISIT
771
		for(Integer lineNumber : candidateSlideLines.keySet()) {
772
			if(validSlideNames.contains(candidateSlideLines.get(lineNumber))) {
773
				processedSlideLines.put(lineNumber, 
774
						candidateSlideLines.get(lineNumber));
775
			}
776
		}
777
 
778
		Utils.logger.info("processedSlideLines=" + 
779
				processedSlideLines.toString());
780
 
781
		// 3 Retrieve "Mandatory" slide names for the category
782
		List<SlideDefinition> mandatorySlideDefs = 
783
			defs.getSlides(this.categoryID, EditorialImportance.MANDATORY);
784
 
785
		Utils.logger.info("mandatorySlideDefs=" + 
786
				mandatorySlideDefs.toString());
787
 
788
		// 3.1 All mandatory slides exist - Severe
789
		for(SlideDefinition mandatorySlideDef : mandatorySlideDefs) {
790
 
791
			// Avoid introduction slide
792
			if(mandatorySlideDef.getLabel().isEmpty()) {
793
				continue;
794
			}
795
 
796
			if(!processedSlideLines.values().contains(
797
					mandatorySlideDef.getLabel())) {
798
				Utils.logger.severe("Mandatory slide \"" + 
799
						mandatorySlideDef.getLabel() + "\" is missing");
800
			}
801
		}
802
 
803
		// 4 Retrieve "Recommended" slide names for the category
804
		List<SlideDefinition> recommendedSlideDefs = 
805
			defs.getSlides(this.categoryID, EditorialImportance.RECOMMENDED);
806
 
807
		Utils.logger.info("recommendedSlideDefs=" + 
808
				recommendedSlideDefs.toString());
809
 
810
		// 4.1 All recommended slides exist - Warn	
811
		for(SlideDefinition recommendedSlideDef : recommendedSlideDefs) {
812
			if(!processedSlideLines.values().contains(
813
					recommendedSlideDef.getLabel())) {
814
				Utils.logger.warning("Recommended slide \"" + 
815
						recommendedSlideDef.getLabel() + "\" is missing");
816
			}
817
		}
818
 
819
		return processedSlideLines;
820
	}
821
 
822
	/**
823
	 * @throws Exception 
824
	 * 
825
	 */
826
	@SuppressWarnings("unused")
827
	private void test() throws Exception {
828
		// test category
829
		DefinitionsContainer allDefs = 
830
			Catalog.getInstance().getDefinitionsContainer();
831
 
832
		Category category = allDefs.getCategory(this.categoryID);
833
		Utils.logger.info(category.toString());
834
 
835
		// test data type defs
836
		DatatypeDefinition datatypeDef = allDefs.getDatatypeDefinition(70004L);
837
		Utils.logger.info(datatypeDef.toString());
838
 
839
		// test units
840
		Unit unit = allDefs.getUnit(50004L);
841
		Utils.logger.info(unit.toString());
842
 
843
		// test slide defs
844
		SlideDefinition slideDef = allDefs.getSlideDefinition(130002L);
845
		Utils.logger.info(slideDef.toString());
846
 
847
		// test feature defs
848
		FeatureDefinition featureDef = allDefs.getFeatureDefinition(120002L);
849
		Utils.logger.info(featureDef.toString());
850
	}
17 naveen 851
}