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