Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
36 naveen 1
/**
2
 * 
3
 */
4
package in.shop2020.metamodel.util;
5
 
6
import in.shop2020.metamodel.core.Bullet;
37 naveen 7
import in.shop2020.metamodel.core.CompositeDataObject;
38 naveen 8
import in.shop2020.metamodel.core.Entity;
37 naveen 9
import in.shop2020.metamodel.core.EnumDataObject;
38 naveen 10
import in.shop2020.metamodel.core.Feature;
11
import in.shop2020.metamodel.core.FreeformContent;
37 naveen 12
import in.shop2020.metamodel.core.PrimitiveDataObject;
13
import in.shop2020.metamodel.definitions.BulletDefinition;
14
import in.shop2020.metamodel.definitions.Catalog;
15
import in.shop2020.metamodel.definitions.CompositeDefinition;
16
import in.shop2020.metamodel.definitions.CompositePartDefinition;
17
import in.shop2020.metamodel.definitions.DatatypeDefinition;
18
import in.shop2020.metamodel.definitions.DefinitionsContainer;
19
import in.shop2020.metamodel.definitions.EditorialImportance;
20
import in.shop2020.metamodel.definitions.EntityContainer;
21
import in.shop2020.metamodel.definitions.EnumDefinition;
22
import in.shop2020.metamodel.definitions.FeatureDefinition;
23
import in.shop2020.metamodel.definitions.SlideDefinition;
24
import in.shop2020.metamodel.definitions.Unit;
25
import in.shop2020.util.Utils;
36 naveen 26
 
27
import java.util.ArrayList;
28
import java.util.HashMap;
29
import java.util.List;
30
import java.util.Map;
31
 
37 naveen 32
import org.apache.commons.lang.ArrayUtils;
36 naveen 33
import org.apache.commons.lang.StringUtils;
34
import org.apache.poi.hslf.HSLFSlideShow;
35
import org.apache.poi.hslf.extractor.PowerPointExtractor;
36
import org.apache.poi.hslf.model.Slide;
37
import org.apache.poi.hslf.model.TextRun;
38
import org.apache.poi.hslf.usermodel.RichTextRun;
39
import org.apache.poi.hslf.usermodel.SlideShow;
40
 
41
/**
51 naveen 42
 * Command line utility to convert MS PPT into shop2020 content model objects. 
43
 * It can be used to 
44
 * 
45
 * - Validate PPT file
46
 * - Import PPT file
47
 * - Show Java objects from already imported PPT
48
 * 
49
 * 
50
 * HSLF - Horrible slide show format (POI API term)
51
 * 
36 naveen 52
 * @author naveen
53
 *
54
 */
55
public class HSLF {
43 naveen 56
	// LOCAL
49 naveen 57
	/**
51 naveen 58
	 * Path to where PPT files will be picked
49 naveen 59
	 */
37 naveen 60
	public static final String CONTENT_SRC_PPT_PATH = 
61
		"/home/naveen/workspace/eclipse/content/ppt/";
43 naveen 62
 
63
	/** Validation tool
64
	public static final String CONTENT_SRC_PPT_PATH = "./ppt/";
65
	*/
66
 
49 naveen 67
	/**
51 naveen 68
	 * Path where exported HTML files are kept
49 naveen 69
	 */
37 naveen 70
	public static final String CONTENT_SRC_HTML_PATH = 
71
		"/home/naveen/workspace/eclipse/content/html/";
49 naveen 72
 
73
	/**
74
	 * 
75
	 */
37 naveen 76
	public static final String CONTENT_SRC_XML_PATH = 
77
		"/home/naveen/workspace/eclipse/content/xml/";
78
 
49 naveen 79
	/**
80
	 * 
81
	 */
82
	public static final int BLUE = -16776961;
83
 
84
	/**
85
	 * 
86
	 */
38 naveen 87
	public static final int PURPLE = -6749953;
49 naveen 88
 
89
	/**
90
	 * 
91
	 */
38 naveen 92
	public static final int GREEN = -16711936;
49 naveen 93
 
94
	/**
95
	 * 
96
	 */
38 naveen 97
	public static final int ORANGE = -26368; 
43 naveen 98
 
99
	// LOCAL
49 naveen 100
	/**
101
	 * 
102
	 */
37 naveen 103
	public static final String CONTENT_DB_PATH =  
104
		"/home/naveen/workspace/eclipse/db/entities/";
105
 
43 naveen 106
	/** Validation tool
107
	public static final String CONTENT_DB_PATH =  
108
		"./db/entities/";
109
	*/
110
 
37 naveen 111
	/** WEB
112
	public static final String CONTENT_DB_PATH =  
113
		"/var/lib/tomcat6/webapps/shop2020/db/entities/";
114
	*/
115
 
49 naveen 116
	/**
117
	 * 
118
	 */
36 naveen 119
	private List<String> slideNames = new ArrayList<String>();
49 naveen 120
 
121
	/**
122
	 * 
123
	 */
36 naveen 124
	private Map<String, List<String>> slideNameChildrenSlideNames = 
125
		new HashMap<String, List<String>>();
49 naveen 126
	/**
127
	 * 
128
	 */
36 naveen 129
	private Map<String, List<String>> slideNameFeatureNames = 
130
		new HashMap<String, List<String>>();
131
 
49 naveen 132
	/**
133
	 * 
134
	 */
37 naveen 135
	private Map<String, Long> slideNameSlideDefID = 
36 naveen 136
		new HashMap<String, Long>();
137
 
49 naveen 138
	/**
139
	 * 
140
	 */
37 naveen 141
	private Map<String, Long> slideNameFeatureNameFeatureDefID =
36 naveen 142
		new HashMap<String, Long>();
49 naveen 143
 
144
	/**
145
	 * 
146
	 */
37 naveen 147
	private Map<String, List<String>> slideNameFeatureNameBulletTexts =
148
		new HashMap<String, List<String>>();
149
 
49 naveen 150
	/**
151
	 * 
152
	 */
37 naveen 153
	private Map<String, List<Bullet>> slideNameFeatureNameBullets =
36 naveen 154
		new HashMap<String, List<Bullet>>();
155
 
49 naveen 156
	/**
157
	 * 
158
	 */
37 naveen 159
	private Map<String, List<String>> containerFCCs = 
36 naveen 160
		new HashMap<String, List<String>>();
161
 
49 naveen 162
	/**
163
	 * 
164
	 */
37 naveen 165
	private long categoryID;
49 naveen 166
 
167
	/**
168
	 * 
169
	 */
37 naveen 170
	private String srcFile;
49 naveen 171
 
172
	/**
173
	 * 
174
	 */
37 naveen 175
	private String dbFile;
49 naveen 176
 
177
	/**
178
	 * 
179
	 */
38 naveen 180
	private String introductionTitle;
49 naveen 181
 
182
	/**
183
	 * 
184
	 */
38 naveen 185
	private String introductionText;
186
 
36 naveen 187
	/**
51 naveen 188
	 * Usage: HSLF [validate|import|show] [{Entity ID}|{Category ID} {PPT file name}]
189
	 * 
36 naveen 190
	 * @param args
191
	 */
192
	public static void main(String[] args) throws Exception {
40 naveen 193
		String[] commands = new String[] {"validate", "import", "show"};
36 naveen 194
 
37 naveen 195
		String usage = "Usage: HSLF ["+ StringUtils.join(commands, "|") +
196
			"] [{Entity ID}|{Category ID} {PPT file name}]\n";
197
 
198
		if(args.length < 2) {
199
			System.out.println(usage);
200
			System.exit(-1);
201
		}
202
 
203
		String inputCommand = args[0];
204
 
205
		if(!ArrayUtils.contains(commands, inputCommand)) {
206
			System.out.println(usage);
207
			System.exit(-1);
208
		}
40 naveen 209
 
210
		if (inputCommand.equals("validate")) {
211
			String inputCategoryID = args[1];
212
			if(args.length < 3) {
213
				System.out.println(usage);
214
				System.exit(-1);
215
			}
37 naveen 216
 
40 naveen 217
			String inputFilename = args[2];
218
			long categoryID = new Long(inputCategoryID).longValue();
219
			HSLF hslf = new HSLF(categoryID, inputFilename);
220
			hslf.validateEntity();
37 naveen 221
			System.exit(0);
222
		}
223
 
224
		if (inputCommand.equals("import")) {
225
			String inputCategoryID = args[1];
226
			if(args.length < 3) {
227
				System.out.println(usage);
228
				System.exit(-1);
229
			}
230
 
231
			String inputFilename = args[2];
232
			long categoryID = new Long(inputCategoryID).longValue();
233
			HSLF hslf = new HSLF(categoryID, inputFilename);
234
			hslf.importEntity();
235
			System.exit(0);
236
		}
40 naveen 237
 
238
		if (inputCommand.equals("show")) {
239
			String entityID = args[1];
240
			HSLF hslf = new HSLF();
241
			hslf.showEntity(new Long(entityID).longValue());
242
			System.exit(0);
243
		}
37 naveen 244
 
36 naveen 245
	}
246
 
37 naveen 247
	/**
248
	 * 
249
	 */
250
	public HSLF() {
251
	}
252
 
253
	/**
254
	 * 
255
	 * @param categoryID
256
	 * @param fileName
257
	 */
258
	public HSLF(long categoryID, String fileName) {
259
		this.categoryID = categoryID;
260
 
261
		this.srcFile = CONTENT_SRC_PPT_PATH + fileName + ".ppt";
262
		this.dbFile = CONTENT_DB_PATH + "entities" + ".ser";
263
	}
49 naveen 264
 
37 naveen 265
	/**
266
	 * 
49 naveen 267
	 * @param entityID
37 naveen 268
	 * @throws Exception
269
	 */
270
	public void showEntity(long entityID) throws Exception {
271
		EntityContainer entContainer = 
272
			Catalog.getInstance().getEntityContainer();
43 naveen 273
		/*
40 naveen 274
		Entity entity = entContainer.getEntity(entityID);
41 naveen 275
		Utils.info("Entity=" + entity);
43 naveen 276
		*/
40 naveen 277
 
37 naveen 278
		ExpandedEntity expandedEntity = 
279
			entContainer.getExpandedEntity(entityID);
280
 
41 naveen 281
		Utils.info("expandedEntity=" + expandedEntity);
37 naveen 282
	}
283
 
40 naveen 284
	/**
285
	 * 
286
	 * @throws Exception
287
	 */
288
	public void validateEntity() throws Exception {
37 naveen 289
		HSLFSlideShow hslfSS = new HSLFSlideShow(this.srcFile);
36 naveen 290
		SlideShow ss = new SlideShow(hslfSS);
291
		Slide[] ssarr = ss.getSlides();
38 naveen 292
 
293
		// Introduction page
294
		this.processIntroductionSlide(ssarr[0]);
295
 
296
		// Rest of the content page
297
		for(int i=1; i < ssarr.length; i++) {
36 naveen 298
			TextRun[] trs = ssarr[i].getTextRuns();
44 naveen 299
			Utils.info("trs.length=" + trs.length);
36 naveen 300
 
44 naveen 301
			/* DEBUG ONLY
302
			for(int j=0;j<trs.length;j++) {
303
				Utils.info("trs["+ j +"].getRawText=" + trs[j].getRawText());
304
				Utils.info("trs[" + j + "].getRichTextRuns().length=" + 
305
						trs[j].getRichTextRuns().length);
306
			}
307
			*/
308
 
37 naveen 309
			String title = StringUtils.lowerCase(
310
					StringUtils.strip(StringUtils.trim(ssarr[i].getTitle())));
36 naveen 311
 
312
			this.slideNames.add(title);
44 naveen 313
			Utils.info("title=" + title);
36 naveen 314
 
40 naveen 315
			// Hack to get to TextRun where bullets are!
44 naveen 316
 
317
			// Assume second textrun will have all the content
36 naveen 318
			TextRun contentTextRun = trs[1];
44 naveen 319
 
36 naveen 320
			RichTextRun[] richTextRuns = contentTextRun.getRichTextRuns();
44 naveen 321
			//Utils.info("richTextRuns.length=" + richTextRuns.length);
322
 
323
			String rawContent = contentTextRun.getRawText();
324
			Utils.info("rawContent=" + rawContent);
325
 
326
			// richTextRuns.length == 1
327
			if(title.equalsIgnoreCase(StringUtils.strip(rawContent)) && 
328
					trs.length > 2) {
40 naveen 329
				contentTextRun = trs[2];
330
				richTextRuns = contentTextRun.getRichTextRuns();
331
			}
44 naveen 332
 
333
			Utils.info("contentTextRun.getRawText=" + 
334
					contentTextRun.getRawText());
335
 
36 naveen 336
			int startIndex = 0;
337
			int indent = 1;
338
			Map<String, Object[]> info = getContents(richTextRuns, startIndex, 
339
					indent);
340
 
41 naveen 341
			Utils.info(info);
36 naveen 342
			//System.exit(0);
343
 
344
			drilldown(richTextRuns, info, indent, title);
44 naveen 345
 
36 naveen 346
		}
44 naveen 347
		//System.exit(0);
36 naveen 348
 
41 naveen 349
		Utils.info("this.slideNames=" + this.slideNames);
350
		Utils.info("this.slideNameChildrenSlideNames=" + 
36 naveen 351
				this.slideNameChildrenSlideNames);
352
 
41 naveen 353
		Utils.info("this.slideNameFeatureNames=" + 
37 naveen 354
				this.slideNameFeatureNames);
355
 
41 naveen 356
		Utils.info("this.slideNameFeatureNameBulletTexts=" + 
37 naveen 357
				this.slideNameFeatureNameBulletTexts);
358
 
41 naveen 359
		Utils.info("this.containerFCCs=" + this.containerFCCs);
37 naveen 360
 
361
		// Start validation and import
362
 
363
		// Validate slides
364
		this.processSlides();
365
 
366
		// Collect Slide Definition IDs
367
		this.collectSlideDefinitionIDs();
41 naveen 368
		Utils.info("this.slideNameSlideDefID=" + 
37 naveen 369
				this.slideNameSlideDefID);
370
 
371
		// Validate features
372
		for(String slideName : this.slideNames) {
42 naveen 373
			this.processFeatures(slideName, slideName);
37 naveen 374
		}
375
 
376
		// Collect Feature Definition IDs
42 naveen 377
		this.collectAllFeatureDefinitionIDs();
41 naveen 378
		Utils.info("this.slideNameFeatureNameFeatureDefID=" + 
37 naveen 379
				this.slideNameFeatureNameFeatureDefID);
42 naveen 380
 
37 naveen 381
		DefinitionsContainer defs = 
382
			Catalog.getInstance().getDefinitionsContainer();
383
 
384
		// Validate bullets
385
		for(String slideName : this.slideNames) {
386
 
40 naveen 387
			Long slideDefID = this.slideNameSlideDefID.get(slideName);
388
			SlideDefinition slideDef = 
389
				defs.getSlideDefinition(slideDefID.longValue());
390
 
42 naveen 391
			this.processBullets(slideName, slideDef.getLabel());
392
		}
393
 
394
		Utils.info("this.slideNameFeatureNameBullets=" + 
395
				this.slideNameFeatureNameBullets);
396
 
397
	}
398
 
399
	/**
400
	 * 
401
	 * @param slideName
402
	 * @param displayTextPrefix
403
	 * @throws Exception
404
	 */
405
	private void processBullets(String slideName, String displayTextPrefix) 
406
		throws Exception {
407
		Utils.info("Process bullets for " + slideName);
408
 
409
		DefinitionsContainer defs = 
410
			Catalog.getInstance().getDefinitionsContainer();
411
 
412
		List<String> featureLabels = 
413
			this.slideNameFeatureNames.get(slideName);
414
 
415
		// Feature-less slide
416
		if(featureLabels != null) {
37 naveen 417
			for(String featureLabel : featureLabels) {
418
				String key = slideName + "_" + featureLabel;
44 naveen 419
				Utils.info("key=" + key);
420
 
37 naveen 421
				List<String> bulletTexts = 
422
					this.slideNameFeatureNameBulletTexts.get(key);
423
 
424
				// Bullet-less feature
425
				if(bulletTexts == null) {
426
					continue;
427
				}
428
 
429
				Long featureDefID = 
430
					this.slideNameFeatureNameFeatureDefID.get(key);
431
 
432
				FeatureDefinition featureDef = 
433
					defs.getFeatureDefinition(featureDefID.longValue());
434
 
42 naveen 435
				String crumb = displayTextPrefix + " > " + 
40 naveen 436
					featureDef.getLabel();
437
 
38 naveen 438
				String prefix = slideName + "_" + featureLabel;
37 naveen 439
				for(String bulletText : bulletTexts) {
440
					Bullet bullet = 
38 naveen 441
						this.processBulletText(bulletText, featureDef, crumb, 
442
								prefix);
37 naveen 443
 
40 naveen 444
					// Can't be imported has errors, skip
37 naveen 445
					if(bullet == null) {
446
						continue;
447
					}
448
 
449
					List<Bullet> bullets = 
450
						this.slideNameFeatureNameBullets.get(key);
451
 
452
					if(bullets == null) {
453
						bullets = new ArrayList<Bullet>();
454
						this.slideNameFeatureNameBullets.put(key, bullets);
455
					}
456
 
457
					bullets.add(bullet);
458
				}
459
			}
460
		}
461
 
42 naveen 462
		// Process bullets of children slides
463
		List<String> childrenSlideNames = 
464
			this.slideNameChildrenSlideNames.get(slideName);
465
		Utils.info("childrenSlideNames=" + childrenSlideNames);
40 naveen 466
 
42 naveen 467
		if(childrenSlideNames != null) {
468
			for(String childSlideName : childrenSlideNames) {
469
				String fullSlideName = slideName + "_" + childSlideName;
470
				Utils.info("fullSlideName=" + fullSlideName);
471
 
472
				Long slideDefID = 
473
					this.slideNameSlideDefID.get(fullSlideName);
474
				Utils.info("slideDefID=" + slideDefID);
475
 
47 naveen 476
				if(slideDefID == null) {
477
					Utils.severe("Unexpected slide " + fullSlideName);
478
					continue;
479
				}
480
 
42 naveen 481
				SlideDefinition childSlideDef = 
482
					defs.getSlideDefinition(slideDefID.longValue());
483
 
484
				String newDisplayTextPrefix = displayTextPrefix + " > " + 
485
					childSlideDef.getLabel();
486
 
487
				this.processBullets(fullSlideName, newDisplayTextPrefix);
488
			}
489
		}
40 naveen 490
	}
491
 
492
	/**
493
	 * 
494
	 * @throws Exception
495
	 */
496
	public void importEntity() throws Exception {
497
 
498
		// Parse and Validate
499
		this.validateEntity();
500
 
38 naveen 501
		// Construct Content Model
502
		Entity entity = this.contructEntityObject();
41 naveen 503
		Utils.info("entity="+entity);
38 naveen 504
 
505
		EntityContainer entContainer = 
506
			Catalog.getInstance().getEntityContainer();
507
 
508
		entContainer.addEntity(entity);
509
 
510
		// RE-VISIT
511
		// Store it back
512
		DBUtils.store(entContainer.getEntities(), this.dbFile);
513
 
514
		// Store the index separately
515
		String entitiesbycategoryDBFile = HSLF.CONTENT_DB_PATH + 
516
			"entitiesbycategory" + ".ser";
517
 
518
		DBUtils.store(entContainer.getEntitiesbyCategory(), 
519
				entitiesbycategoryDBFile);
520
 
36 naveen 521
	}
38 naveen 522
	/**
523
	 * 
524
	 * @param hslfSlide
525
	 */
526
	private void processIntroductionSlide(Slide hslfSlide) {
527
		TextRun[] trs = hslfSlide.getTextRuns();
528
		StringBuffer sbTitle = new StringBuffer();
529
		StringBuffer sbText = new StringBuffer();
530
 
531
		for(int i=0;i<trs.length;i++) {
532
			RichTextRun[] rtrs = trs[i].getRichTextRuns();
533
 
534
			for(int j=0;j<rtrs.length;j++) {
535
				int rgb = rtrs[j].getFontColor().getRGB();
536
				if(rgb == HSLF.ORANGE) {
537
					sbTitle.append(rtrs[j].getRawText());
538
				}
539
				else if(rgb == HSLF.PURPLE) {
540
					sbText.append(rtrs[j].getRawText());
541
				}
542
			}
543
		}
544
 
545
		this.introductionTitle = sbTitle.toString();
546
		this.introductionText = sbText.toString();
41 naveen 547
		Utils.info("this.introductionTitle=" + this.introductionTitle);
548
		Utils.info("this.introductionText=" + this.introductionText);
38 naveen 549
	}
36 naveen 550
 
37 naveen 551
	/**
552
	 * 
38 naveen 553
	 * @return Entity 
554
	 * @throws Exception 
555
	 */
556
	private Entity contructEntityObject() throws Exception {
557
		SequenceGenerator sg = SequenceGenerator.getInstance();
558
		long entityID = sg.getNextSequence(SequenceGenerator.ENTITY);
559
 
560
		Entity entity = new Entity(entityID, this.categoryID);
561
		String brandModel[] = StringUtils.split(this.introductionTitle, " ");
562
 
563
		if(brandModel.length == 1) {
564
			entity.setBrand(StringUtils.strip(brandModel[0]));
565
		}
566
		else if(brandModel.length == 2) {
567
			entity.setBrand(StringUtils.strip(brandModel[0]));
568
			entity.setModelName(StringUtils.strip(brandModel[1]));
569
		}
570
		else if(brandModel.length == 3) {
571
			entity.setBrand(StringUtils.strip(brandModel[0]));
572
			entity.setModelNumber(StringUtils.strip(brandModel[1]));
573
			entity.setModelName(StringUtils.strip(brandModel[2]));
574
		}
575
		else if(brandModel.length == 4) {
576
			entity.setBrand(StringUtils.strip(brandModel[0]) + " " + 
577
					StringUtils.strip(brandModel[1]));
578
 
579
			entity.setModelNumber(StringUtils.strip(brandModel[2]));
580
			entity.setModelName(StringUtils.strip(brandModel[3]));
581
		}
582
 
583
		// Add introduction slide
584
		DefinitionsContainer defs = 
585
			Catalog.getInstance().getDefinitionsContainer();
586
 
587
		List<SlideDefinition> introSlideDefs = 
40 naveen 588
			defs.getSlideDefinitions(this.categoryID, "Introduction");
38 naveen 589
 
590
		// It will only be one
591
		long introSlideDefID = introSlideDefs.get(0).getID();
41 naveen 592
		Utils.info("introSlideDefID=" + introSlideDefID);
38 naveen 593
 
594
		in.shop2020.metamodel.core.Slide introSlide = 
595
			new in.shop2020.metamodel.core.Slide(introSlideDefID);
596
 
597
		introSlide.setFreeformContent(
598
				new FreeformContent(this.introductionText));
41 naveen 599
		Utils.info("introSlide=" + introSlide);
40 naveen 600
 
601
		entity.addSlide(introSlide);
38 naveen 602
 
603
		// Add rest of the slides
604
		for(String slideName : this.slideNames) {
605
			in.shop2020.metamodel.core.Slide slide = 
43 naveen 606
				this.constructSlideObject(slideName);
38 naveen 607
 
43 naveen 608
			entity.addSlide(slide);
609
		}
610
 
611
		return entity;
612
	}
613
 
614
	/**
615
	 * 
616
	 * @param slideName
617
	 * @return
618
	 */
619
	private in.shop2020.metamodel.core.Slide constructSlideObject(
620
			String slideName) {
621
		Utils.info("Constructing slide object for " + slideName);
622
 
623
		List<String> featureNames = 
624
			this.slideNameFeatureNames.get(slideName);
625
 
626
		Long slideDefID = this.slideNameSlideDefID.get(slideName);
47 naveen 627
 
628
		if(slideDefID == null) {
629
			Utils.severe("Unexpected slide " + slideName);
630
			return null;
631
		}
632
 
43 naveen 633
		in.shop2020.metamodel.core.Slide slide = 
634
			new in.shop2020.metamodel.core.Slide(slideDefID.longValue());
635
 
636
		// Only if there are features
637
		if(featureNames != null) {
38 naveen 638
			List<Feature> features = new ArrayList<Feature>();
639
 
43 naveen 640
			for(String featureName : featureNames) {
641
				String key = slideName + "_" + featureName;
38 naveen 642
				Long featureDefID = 
643
					this.slideNameFeatureNameFeatureDefID.get(key);
644
 
645
				List<Bullet> bullets = 
646
					this.slideNameFeatureNameBullets.get(key);
647
 
648
				Feature feature = new Feature(featureDefID.longValue());
649
				feature.setBullets(bullets);
650
 
651
				// Free-form content
652
				List<String> featureFFCs = this.containerFCCs.get(key);
653
				FreeformContent featureFFC = 
654
					new FreeformContent(StringUtils.join(featureFFCs, "|"));
655
 
656
				feature.setFreeformContent(featureFFC);
657
 
658
				features.add(feature);
659
			}
660
 
661
			slide.setFeatures(features);
43 naveen 662
		}
663
 
664
		// Add children slides
665
		List<String> childrenSlideNames = 
666
			this.slideNameChildrenSlideNames.get(slideName);
667
 
668
		if(childrenSlideNames != null) {
669
			for(String childSlideName : childrenSlideNames) {
670
				in.shop2020.metamodel.core.Slide childSlide = 
671
					this.constructSlideObject(slideName + "_" + childSlideName);
672
 
47 naveen 673
				if(childSlide != null) {
674
					slide.addChild(childSlide);
675
				}
43 naveen 676
			}
677
		}
678
 
679
		// Add free-form content is collect above
680
		List<String> slideFFCs = this.containerFCCs.get(slideName);
681
		Utils.info("slideName=" + slideName + 
682
				" slideFFCs=" + slideFFCs);
683
 
684
		if(slideFFCs != null) {
38 naveen 685
			FreeformContent slideFFC = 
686
				new FreeformContent(StringUtils.join(slideFFCs, "|"));
687
 
688
			slide.setFreeformContent(slideFFC);
689
		}
690
 
43 naveen 691
		return slide;
38 naveen 692
	}
693
 
694
	/**
695
	 * 
37 naveen 696
	 * @throws Exception
697
	 */
42 naveen 698
	private void collectAllFeatureDefinitionIDs() throws Exception {
699
 
700
		for(String slideName : this.slideNames) {
701
			this.collectFeatureDefinitionIDs(slideName);
702
		}
703
	}
704
 
705
	/**
706
	 * 
707
	 * @param slideName
708
	 * @throws Exception
709
	 */
44 naveen 710
	private void collectFeatureDefinitionIDs(String slideName) 
711
		throws Exception {
712
		Utils.info("collectFeatureDefinitionIDs for " + slideName);
713
 
37 naveen 714
		DefinitionsContainer defs = 
715
			Catalog.getInstance().getDefinitionsContainer();
716
 
42 naveen 717
		Long slideDefID = this.slideNameSlideDefID.get(slideName);
718
		Utils.info("slideName=" + slideName);
719
 
47 naveen 720
		if(slideDefID == null) {
721
			Utils.severe("Unexpected slide " + slideName);
722
			return;
723
		}
724
 
42 naveen 725
		List<String> featureLabels = 
726
			this.slideNameFeatureNames.get(slideName);
727
		Utils.info("featureLabels=" + featureLabels);
728
 
729
		// Feature-less slide
44 naveen 730
		if(featureLabels != null && !featureLabels.isEmpty()) {
731
			for(String featureLabel : featureLabels) {
47 naveen 732
				Utils.info("defs=" + defs);
733
				Utils.info("slideDefID=" + slideDefID);
734
				Utils.info("featureLabel=" + featureLabel);
735
 
44 naveen 736
				FeatureDefinition featureDef = 
737
					defs.getFeatureDefinition(slideDefID, featureLabel);
738
				String key = slideName + "_" + featureLabel;
739
 
47 naveen 740
				if(featureDef == null) {
741
					Utils.severe("Unexpected feature " + key);
742
					continue;
743
				}
744
 
44 naveen 745
				this.slideNameFeatureNameFeatureDefID.put(key, 
746
						new Long(featureDef.getID()));
747
			}
42 naveen 748
		}
749
 
750
		List<String> childrenSlideNames = 
751
			this.slideNameChildrenSlideNames.get(slideName);
752
 
753
		if(childrenSlideNames != null && !childrenSlideNames.isEmpty()) {
754
			for(String childSlideName : childrenSlideNames) {
755
				String fullSlideName = slideName + "_" + childSlideName;
37 naveen 756
 
42 naveen 757
				this.collectFeatureDefinitionIDs(fullSlideName);
37 naveen 758
			}
759
		}
760
	}
761
 
762
	/**
763
	 * 
764
	 * @throws Exception
765
	 */
766
	private void collectSlideDefinitionIDs() throws Exception {
767
		for(String slideName : this.slideNames) {
42 naveen 768
			SlideDefinition slideDef = this.getSlideDefinition(slideName);
769
			//Utils.info("slideDef=" + slideDef);
37 naveen 770
 
42 naveen 771
			if(slideDef == null) {
37 naveen 772
				continue;
773
			}
774
 
775
			Long slideID = slideDef.getID();
776
			this.slideNameSlideDefID.put(slideName, slideID);
42 naveen 777
 
778
			if(slideDef.hasChildren()) {
779
				this.collectChidrenSlideDefinitionIDs(slideName, slideDef);
780
			}
37 naveen 781
		}
782
	}
783
 
784
	/**
785
	 * 
42 naveen 786
	 * @param parentSlideName
787
	 * @param paretnSlideDef
788
	 * @throws Exception 
789
	 */
790
	private void collectChidrenSlideDefinitionIDs(String parentSlideName, 
791
			SlideDefinition parentSlideDef) throws Exception {
45 naveen 792
		Utils.info("collectChidrenSlideDefinitionIDs for " + parentSlideName);
42 naveen 793
 
794
		// May not be needed as validations have already filtered correct 
795
		// children slide names
796
		List<String> childrenSlideNames = 
797
			this.slideNameChildrenSlideNames.get(parentSlideName);
45 naveen 798
		Utils.info("childrenSlideNames=" + childrenSlideNames);
42 naveen 799
 
800
		List<Long> childrenSlideDefinitionIDs = 
801
			parentSlideDef.getChildrenSlideDefinitionIDs();
45 naveen 802
		Utils.info("childrenSlideDefinitionIDs=" + childrenSlideDefinitionIDs);
42 naveen 803
 
804
		DefinitionsContainer defs = 
805
			Catalog.getInstance().getDefinitionsContainer();
806
 
807
		for(Long childSlideDefID : childrenSlideDefinitionIDs) {
808
			SlideDefinition childSlideDef = 
809
				defs.getSlideDefinition(childSlideDefID.longValue());
810
 
811
			String label = childSlideDef.getLabel();
45 naveen 812
			Utils.info("label="+label);
42 naveen 813
 
814
			if(childrenSlideNames.contains(StringUtils.lowerCase(label))) {
815
				String key = parentSlideName + "_" + 
816
					StringUtils.lowerCase(label);
817
 
818
 				this.slideNameSlideDefID.put(key, childSlideDefID);
819
 
820
 				if(childSlideDef.hasChildren()) {
821
 					this.collectChidrenSlideDefinitionIDs(key, childSlideDef);
822
 				}
823
			}
824
		}
825
	}
826
 
827
	/**
828
	 * 
829
	 * @param slideName
830
	 * @return
831
	 * @throws Exception
832
	 */
833
	private SlideDefinition getSlideDefinition(String slideName) 
834
		throws Exception {
835
		DefinitionsContainer  defs = 
836
			Catalog.getInstance().getDefinitionsContainer();
837
 
838
		List<SlideDefinition> slideDefs = 
839
			defs.getSlideDefinitions(this.categoryID, slideName);
840
 
841
		if(slideDefs == null) {
842
			return null;
843
		}
844
 
845
		if (slideDefs.isEmpty()) {
846
			return null;
847
		} 
848
 
849
		// RE-VISIT
850
		// Pick the first
851
		SlideDefinition slideDef = slideDefs.get(0);
852
		//Utils.info("slideDef=" + slideDef);
853
 
854
		return slideDef;
855
	}
49 naveen 856
 
42 naveen 857
	/**
858
	 * 
49 naveen 859
	 * @param slideName
860
	 * @param displayTextPrefix
37 naveen 861
	 * @throws Exception
862
	 */
42 naveen 863
	private void processFeatures(String slideName, String displayTextPrefix) 
37 naveen 864
		throws Exception {
42 naveen 865
		Utils.info("Processing features for " + slideName);
37 naveen 866
 
47 naveen 867
		if(this.slideNameSlideDefID.get(slideName) == null) {
868
			Utils.severe("Unexpected slide \"" + displayTextPrefix + "\"");
869
			return;
870
		}
871
 
37 naveen 872
		long slideDefID = this.slideNameSlideDefID.get(slideName).longValue();
41 naveen 873
		Utils.info("slideID=" + slideDefID);
37 naveen 874
 
875
		List<String> candidateFeatures = 
876
			this.slideNameFeatureNames.get(slideName);
877
 
41 naveen 878
		Utils.info("slideName=" + slideName);
879
		Utils.info("candidateFeatures=" + candidateFeatures);
37 naveen 880
 
881
		// Get all feature definitions for the slide
882
		DefinitionsContainer defs = 
883
			Catalog.getInstance().getDefinitionsContainer();
884
 
885
		SlideDefinition slideDef = defs.getSlideDefinition(slideDefID);
41 naveen 886
		Utils.info("slideDef=" + slideDef);
37 naveen 887
 
888
		List<FeatureDefinition> featureDefs = 
889
			defs.getFeatureDefinitions(slideDefID);
41 naveen 890
		Utils.info("featureDefs=" + featureDefs);
37 naveen 891
 
45 naveen 892
		// Feature less slide
893
		if(featureDefs == null || featureDefs.isEmpty()) {
894
			Utils.info("Feature-less slide");
895
			return;
896
		}
897
 
37 naveen 898
		List<String> validFeatureLabels = new ArrayList<String>();
899
		for(int i=0; i<featureDefs.size(); i++) {
900
			validFeatureLabels.add(
901
					StringUtils.lowerCase(featureDefs.get(i).getLabel()));
902
 
903
		}
41 naveen 904
		Utils.info("validFeatureLabels=" + validFeatureLabels);
45 naveen 905
 
906
		// Missing features check
907
		if(candidateFeatures == null || candidateFeatures.isEmpty()) {
908
			Utils.severe("Missing features " + 
909
					StringUtils.join(validFeatureLabels, ", "));
910
		}
47 naveen 911
 
912
		if(candidateFeatures != null) {
913
			// Discard if feature is not one of the valids
914
			List<String> processedFeatureLabels = new ArrayList<String>();
915
			for(String featureLabel : candidateFeatures) {
916
 
917
				if(validFeatureLabels.contains(featureLabel)) {
918
					processedFeatureLabels.add(featureLabel);
919
				}
920
				else {		
921
					Utils.severe("Invalid feature \"" + displayTextPrefix + 
922
							" > " + featureLabel + "\"");
923
				}
924
 
925
			}
926
			Utils.info("processedFeatureLabels=" + processedFeatureLabels);
37 naveen 927
 
47 naveen 928
			// For all further processing
929
			this.slideNameFeatureNames.put(slideName, processedFeatureLabels);
930
 
931
			// Fetch all mandatory features
932
			List<FeatureDefinition> mandatoryFeatureDefs = 
933
				defs.getFeatureDefinitions(slideDefID,
934
				EditorialImportance.MANDATORY);
935
 
936
			Utils.info("mandatoryFeatureDefs=" + mandatoryFeatureDefs);
937
 
938
			// Severe error if mandatory features are not included
939
			for(FeatureDefinition featureDef : mandatoryFeatureDefs) {
940
				if(!processedFeatureLabels.contains(StringUtils.lowerCase(
941
						featureDef.getLabel()))) {
942
					Utils.severe("Mandatory feature \"" + displayTextPrefix 
943
							+ " > " + featureDef.getLabel() + "\" is missing");
944
				}
37 naveen 945
			}
946
 
47 naveen 947
			// Fetch all recommended features
948
			List<FeatureDefinition> recommendedFeatureDefs = 
949
				defs.getFeatureDefinitions(slideDef.getID(),
950
				EditorialImportance.RECOMMENDED);
951
 
952
			Utils.info("recommendedFeatureDefs=" + recommendedFeatureDefs);
953
 
954
			// Warn if recommended features are not included
955
			for(FeatureDefinition featureDef : recommendedFeatureDefs) {
956
				if(!processedFeatureLabels.contains(StringUtils.lowerCase(
957
						featureDef.getLabel()))) {
958
					Utils.warning("Recommended feature \"" + displayTextPrefix + 
959
							" > " + featureDef.getLabel() + 
960
							"\" is missing");
961
				}
37 naveen 962
			}
963
		}
964
 
42 naveen 965
		// Process features of children slides
966
		List<String> childrenSlideNames = 
967
			this.slideNameChildrenSlideNames.get(slideName);
968
 
969
		if(childrenSlideNames != null && !childrenSlideNames.isEmpty()) {
970
			for(String childSlideName : childrenSlideNames) {
971
				String fullChildSlideName = slideName + "_" + childSlideName;
972
 
973
				String newDisplayTextPrefix = displayTextPrefix + " > " + 
974
					childSlideName;
975
 
976
				this.processFeatures(fullChildSlideName, newDisplayTextPrefix);
977
			}
978
		}
979
 
37 naveen 980
	}
981
 
982
	/**
983
	 * Filter and validate parent slide names
984
	 * 
985
	 * @throws Exception 
986
	 */
987
	private void processSlides() throws Exception {
988
 
989
		// 1 Retrieve meta-data
990
		// 1.1 Retrieve all valid slide names in the content model
991
		DefinitionsContainer defs = 
992
			Catalog.getInstance().getDefinitionsContainer();
993
 
994
		List<SlideDefinition> slideDefs = defs.getSlideDefinitions(
995
				this.categoryID);
996
 
997
		List<String> validSlideNames = new ArrayList<String>();
998
		for (SlideDefinition slideDef : slideDefs) {
999
 
1000
			// To avoid Introduction slide
1001
			if(!slideDef.getLabel().isEmpty()) {
1002
				validSlideNames.add(StringUtils.lowerCase(slideDef.getLabel()));
1003
			}
1004
		}
41 naveen 1005
		Utils.info("validSlideNames=" + validSlideNames.toString());
37 naveen 1006
 
1007
		// 2 Rules
1008
		// 2.1 Discard if slide is not one of the valids
1009
		List<String> processedSlideNames = new ArrayList<String>();
1010
		for(String slideName : this.slideNames) {
1011
			if(validSlideNames.contains(slideName)) {
1012
				processedSlideNames.add(slideName);
1013
			}
40 naveen 1014
			else if(slideName.equals("resource urls") || 
1015
					slideName.equals("reference urls")) {
1016
				// ignore
1017
				continue;
1018
			}
37 naveen 1019
			else {
41 naveen 1020
				Utils.severe("Invalid slide \"" + slideName + "\"");
37 naveen 1021
			}
1022
		}
1023
 
42 naveen 1024
		Utils.info("processedSlideNames=" + processedSlideNames.toString());
37 naveen 1025
 
1026
		// For all further processing use processed slide names only
1027
		this.slideNames = processedSlideNames;
1028
 
1029
		// 3 Retrieve "Mandatory" slide names for the category
1030
		List<SlideDefinition> mandatorySlideDefs = 
1031
			defs.getSlides(this.categoryID, EditorialImportance.MANDATORY);
1032
 
41 naveen 1033
		Utils.info("mandatorySlideDefs=" + 
37 naveen 1034
				mandatorySlideDefs.toString());
1035
 
1036
		// 3.1 All mandatory slides exist - Severe
1037
		for(SlideDefinition mandatorySlideDef : mandatorySlideDefs) {
1038
 
1039
			// Avoid introduction slide
1040
			if(mandatorySlideDef.getLabel().isEmpty()) {
1041
				continue;
1042
			}
1043
 
40 naveen 1044
			if(mandatorySlideDef.getLabel().equals("Introduction")) {
1045
				continue;
1046
			}
1047
 
37 naveen 1048
			if(!this.slideNames.contains(
1049
					StringUtils.lowerCase(mandatorySlideDef.getLabel()))) {
1050
 
41 naveen 1051
				Utils.severe("Mandatory slide \"" + 
37 naveen 1052
						mandatorySlideDef.getLabel() + "\" is missing");
1053
			}
1054
		}
1055
 
1056
		// 4 Retrieve "Recommended" slide names for the category
1057
		List<SlideDefinition> recommendedSlideDefs = 
1058
			defs.getSlides(this.categoryID, EditorialImportance.RECOMMENDED);
1059
 
42 naveen 1060
		Utils.info("recommendedSlideDefs=" + recommendedSlideDefs.toString());
37 naveen 1061
 
1062
		// 4.1 All recommended slides exist - Warn	
1063
		for(SlideDefinition recommendedSlideDef : recommendedSlideDefs) {
1064
			if(!this.slideNames.contains(
1065
					StringUtils.lowerCase(recommendedSlideDef.getLabel()))) {
1066
 
41 naveen 1067
				Utils.warning("Recommended slide \"" + 
37 naveen 1068
						recommendedSlideDef.getLabel() + "\" is missing");
1069
			}
1070
		}
42 naveen 1071
 
1072
		// Process children slides
1073
		for(String parentSlideName : this.slideNames) {
1074
			Utils.info("Process children slides for parentSlideName=" + 
1075
					parentSlideName);
1076
 
1077
			SlideDefinition parentSlideDef = 
1078
				this.getSlideDefinition(parentSlideName);
1079
 
1080
			// ignore for now
1081
			if(parentSlideDef == null) {
1082
				continue;
1083
			}
1084
 
1085
			this.processChildrenSlides(parentSlideDef, parentSlideName, 
1086
					parentSlideDef.getLabel());
1087
		}
1088
 
1089
		Utils.info("slideNameChildrenSlideNames=" + 
1090
				slideNameChildrenSlideNames);
37 naveen 1091
	}
1092
 
1093
	/**
1094
	 * 
42 naveen 1095
	 * @param slideName
1096
	 * @param parentSlideDefinition
1097
	 * @param crumb
1098
	 * @throws Exception 
1099
	 */
1100
	private void processChildrenSlides(SlideDefinition parentSlideDef, 
1101
			String crumb, String displayTextPrefix) throws Exception {
1102
 
1103
		List<Long> childrenSlideDefinitionIDs = 
1104
			parentSlideDef.getChildrenSlideDefinitionIDs();
1105
 
1106
		if(childrenSlideDefinitionIDs == null || 
1107
				childrenSlideDefinitionIDs.isEmpty()) {
1108
			return;
1109
		}
1110
 
1111
		DefinitionsContainer defs = 
1112
			Catalog.getInstance().getDefinitionsContainer();
1113
 
1114
		String parentSlideName = parentSlideDef.getLabel();
1115
		Utils.info("parentSlideName=" + parentSlideName + " has " + 
1116
				childrenSlideDefinitionIDs + " children slides to process");
1117
 
1118
		Utils.info("crumb=" + crumb);
1119
 
1120
		List<String> childrenSlideNames = 
1121
			this.slideNameChildrenSlideNames.get(crumb);
1122
		Utils.info("childrenSlideNames=" + childrenSlideNames);
1123
 
1124
		// Collect allowed children slide labels
1125
		List<String> validChildrenSlideNames = new ArrayList<String>();
1126
 
1127
		Map<String, SlideDefinition> childSlideNameSlideDefinition = 
1128
			new HashMap<String, SlideDefinition>();
1129
 
1130
		for(Long childSlideDefID : childrenSlideDefinitionIDs) {
1131
			Utils.info("childSlideDefID=" + childSlideDefID);
1132
 
1133
			SlideDefinition childSlideDef = 
1134
				defs.getSlideDefinition(childSlideDefID.longValue());
1135
			Utils.info("childSlideDef=" + childSlideDef);
1136
 
1137
			String displaytext = displayTextPrefix + " > " + 
1138
				childSlideDef.getLabel();
1139
 
1140
			// All children slides defined are mandatory
1141
			String childSlideName = 
1142
				StringUtils.lowerCase(childSlideDef.getLabel());
1143
			Utils.info("childSlideName=" + childSlideName);
1144
 
1145
			if(childrenSlideNames == null || 
1146
					!childrenSlideNames.contains(childSlideName)) {
1147
				Utils.severe("Missing child slide \"" + displaytext + "\"");
1148
				continue;
1149
			}
1150
 
1151
			validChildrenSlideNames.add(childSlideName);
1152
			childSlideNameSlideDefinition.put(childSlideName, childSlideDef);
1153
		}
1154
 
1155
		this.slideNameChildrenSlideNames.put(crumb, validChildrenSlideNames);
1156
		Utils.info("validChildrenSlideNames=" + validChildrenSlideNames);
1157
 
1158
		for(String childSlideName : childSlideNameSlideDefinition.keySet()) {
1159
			SlideDefinition slideDef = 
1160
				childSlideNameSlideDefinition.get(childSlideName);
1161
 
1162
			String newcrumb = crumb + "_" + 
1163
				StringUtils.lowerCase(childSlideName);
1164
 
1165
			String newDisplayTextPrefix = displayTextPrefix + " > " + 
1166
				slideDef.getLabel();
1167
 
1168
			this.processChildrenSlides(slideDef, newcrumb, 
1169
					newDisplayTextPrefix);
1170
		}
1171
	}
49 naveen 1172
 
42 naveen 1173
	/**
1174
	 * 
37 naveen 1175
	 * @param bulletText
49 naveen 1176
	 * @param featureDef
1177
	 * @param crumb
1178
	 * @param prefix
1179
	 * @return
1180
	 * @throws Exception
37 naveen 1181
	 */
1182
	private Bullet processBulletText(String bulletText, 
38 naveen 1183
			FeatureDefinition featureDef, String crumb, String prefix) 
1184
			throws Exception {
41 naveen 1185
		Utils.info("featureDef.getLabel=" + featureDef.getLabel());
1186
		Utils.info("bulletText=" + bulletText);
40 naveen 1187
 
37 naveen 1188
		BulletDefinition bulletDef = featureDef.getBulletDefinition();
41 naveen 1189
		Utils.info("bulletDefinition=" + bulletDef);
37 naveen 1190
 
1191
		DefinitionsContainer defs = 
1192
			Catalog.getInstance().getDefinitionsContainer();
1193
 
1194
		// If unit is defined
1195
		Unit unitDef =  null;
1196
		if(bulletDef.getUnitID() != 0L) {
1197
			long unitID = bulletDef.getUnitID();
1198
			unitDef = defs.getUnit(unitID);
41 naveen 1199
			Utils.info("unitDef=" + unitDef);
37 naveen 1200
		}
1201
 
1202
		long datatypeDefID = bulletDef.getDatatypeDefinitionID();
1203
		DatatypeDefinition datatypeDef = 
1204
			defs.getDatatypeDefinition(datatypeDefID);
41 naveen 1205
		Utils.info("datatypeDef=" + datatypeDef);
37 naveen 1206
 
1207
		// If primitive
1208
		boolean isEnum = false;
1209
		boolean isComposite = false;
1210
		boolean isPrimitive = false;
1211
		if(datatypeDef instanceof EnumDefinition) {
1212
			isEnum = true;
1213
		}
1214
		else if(datatypeDef instanceof CompositeDefinition) {
1215
			isComposite = true;
1216
		}
1217
		else {
1218
			isPrimitive = true;
1219
		}
1220
 
41 naveen 1221
		Utils.info("isEnum=" + isEnum + " isComposite=" + isComposite +
37 naveen 1222
				" isPrimitive=" + isPrimitive);
1223
 
1224
		// if no unit is defined for this bullet whole is treated as value
1225
		String bulletValue = bulletText;
1226
		Bullet bullet = null;
1227
 
1228
		// If unit is defined
1229
		if(bulletDef.getUnitID() != 0L) {
1230
 
1231
			// Validate unit
1232
			String[] parts = StringUtils.split(bulletText, " ");
1233
			if(parts.length < 2) {
41 naveen 1234
				Utils.severe("Unit is missing, \"" + crumb + "\" = " + 
37 naveen 1235
						bulletText);
1236
 
1237
				return null;
1238
			}
1239
 
1240
			else if(parts.length > 2) {
41 naveen 1241
				Utils.severe("Invalid value, \"" + crumb + "\" = " + 
37 naveen 1242
						bulletText);
1243
 
1244
				return null;
1245
			}
1246
 
1247
			bulletValue = parts[0];
1248
			String unitValue = parts[1];
41 naveen 1249
			Utils.info("unitValue="+unitValue);
37 naveen 1250
 
1251
			if(!(unitValue.equalsIgnoreCase(unitDef.getShortForm()) ||
1252
					unitValue.equalsIgnoreCase(unitDef.getFullForm()))) {
1253
 
41 naveen 1254
				Utils.severe("Invalid unit, \"" + crumb + "\" = " + 
37 naveen 1255
						bulletText);
1256
 
1257
			}
1258
		}
1259
 
1260
		// Validate bullet value
41 naveen 1261
		Utils.info("bulletValue=" + bulletValue);
37 naveen 1262
		if(isPrimitive) {
1263
			if(!this.validatePrimitive(bulletValue, datatypeDef, crumb)) {
1264
				return null;
1265
			}
1266
 
1267
			bullet = new Bullet(new PrimitiveDataObject(bulletValue));
1268
		}
1269
 
1270
		// Enum and fixed
1271
		else if(isEnum && !bulletDef.isLearned()) {
1272
			long enumValueID = defs.getEnumValueID(datatypeDef.getID(), 
1273
					bulletValue);
41 naveen 1274
			Utils.info("enumValueID=" + enumValueID);
37 naveen 1275
 
1276
			// Treat it to be free-form
1277
			if(enumValueID == -1L) {
41 naveen 1278
				Utils.severe("Not one of the valid enum values, \"" +
40 naveen 1279
						crumb + "\" = " + bulletValue);
37 naveen 1280
 
1281
				return null;
1282
			}
1283
 
1284
			EnumDataObject enumDataObject = new EnumDataObject(enumValueID);
1285
			bullet = new Bullet(enumDataObject);
1286
		}
1287
 
1288
		// Composite
1289
		else if(isComposite) {
1290
			CompositeDefinition compositeDef = 
1291
				(CompositeDefinition)datatypeDef;
1292
 
1293
			String separator = compositeDef.getSeparator();
1294
			String[] compositeParts = 
1295
				StringUtils.split(bulletValue, separator);
1296
 
1297
			List<CompositePartDefinition> compositePartDefs = 
1298
				compositeDef.getCompositePartDefinitions();
1299
 
1300
			// Validate number of parts
1301
			if(compositeParts.length != compositePartDefs.size()) {
41 naveen 1302
				Utils.severe("Invalid value, " + crumb + " = " + 
37 naveen 1303
						bulletValue);
1304
 
1305
				return null;
1306
			}
1307
 
1308
			// Remove spurious whitespaces
1309
			boolean validPart = true;
1310
			for(int j=0;j<compositeParts.length;j++) {
1311
				compositeParts[j] = StringUtils.strip(compositeParts[j]);
41 naveen 1312
				Utils.info("compositeParts["+ j + "]=" + 
37 naveen 1313
						compositeParts[j]);
1314
 
1315
				// Validate each part
1316
				// Each part can be enum or composite in itself
1317
				// We will stick to primitive for now
1318
				long partDatatypeDefID = 
1319
					compositePartDefs.get(j).getDatatypeDefinitionID();
1320
 
1321
				DatatypeDefinition partDatatypeDef = 
1322
					defs.getDatatypeDefinition(partDatatypeDefID);
41 naveen 1323
				Utils.info("partDatatypeDef=" + partDatatypeDef);
37 naveen 1324
 
1325
				if(!this.validatePrimitive(compositeParts[j], 
1326
						partDatatypeDef, crumb)) {
1327
					validPart = false;
1328
					break;
1329
				}
1330
			}
1331
 
1332
			if(!validPart) {
1333
				return null;
1334
			}
1335
 
1336
			CompositeDataObject compositeDataObject = 
1337
				new CompositeDataObject();
1338
 
1339
			for(int j=0;j<compositeParts.length;j++) {
1340
				compositeDataObject.addPrimitiveDataObject(
1341
						new PrimitiveDataObject(compositeParts[j]));
1342
			}
1343
 
1344
			bullet = new Bullet(compositeDataObject);
1345
		}
1346
 
38 naveen 1347
		// Free-form content at bullet level
1348
		String key = prefix + "_" + bulletText;
1349
		List<String> bulletFFCs = this.containerFCCs.get(key);
1350
		bullet.setFreeformContent(new FreeformContent(StringUtils.join(
1351
				bulletFFCs, "|")));
1352
 
37 naveen 1353
		return bullet;
1354
	}
1355
 
1356
 
1357
	/**
1358
	 * 
1359
	 * @param bulletValue
1360
	 * @param datatypeDef
1361
	 * @param crumb
1362
	 */
1363
	private boolean validatePrimitive(String bulletValue, 
1364
			DatatypeDefinition datatypeDef, String crumb) {
1365
		String dt = datatypeDef.getName();
1366
 
1367
		// integer
1368
		if(dt.equals("integer")) {
1369
			try {
1370
				Integer.parseInt(bulletValue);
1371
			}
1372
			catch(NumberFormatException nfe) {
41 naveen 1373
				Utils.severe("Invalid integer value, \"" + crumb +
40 naveen 1374
						"\" = " + bulletValue);
39 naveen 1375
				return false;
37 naveen 1376
			}
1377
		}
1378
 
1379
		// decimal
39 naveen 1380
		else if(dt.equals("decimal")) {
37 naveen 1381
			try {
1382
				Float.parseFloat(bulletValue);
1383
			}
1384
			catch(NumberFormatException nfe) {
41 naveen 1385
				Utils.severe("Invalid decimal value, \"" + crumb +
40 naveen 1386
						"\" = " + bulletValue);
39 naveen 1387
				return false;
37 naveen 1388
			}
1389
		}
1390
 
39 naveen 1391
		// hours_mins e.g. 2 hours 40 mins
1392
		else if(dt.equals("hours_mins")) {
1393
			String[]  parts = StringUtils.split(bulletValue, " ");
1394
			if(!(parts.length == 2 || parts.length == 4)) {
42 naveen 1395
				Utils.severe("Invalid value, \"" + crumb +
1396
						"\" = " + bulletValue);
39 naveen 1397
				return false;
1398
			}
1399
			// parts[0]
1400
			try {
1401
				Integer.parseInt(StringUtils.strip(parts[0]));
1402
			}
1403
			catch (NumberFormatException nfe) {
41 naveen 1404
				Utils.severe("Invalid value, \"" + crumb +
40 naveen 1405
						"\" = " + bulletValue);
39 naveen 1406
				return false;
1407
			}
1408
 
1409
			// parts[1]
42 naveen 1410
			if(!"hours".equalsIgnoreCase(StringUtils.strip(parts[1]))) {
41 naveen 1411
				Utils.severe("Invalid value, \"" + crumb +
40 naveen 1412
						"\" = " + bulletValue);
39 naveen 1413
				return false;
1414
			}
1415
 
1416
			if(parts.length == 4) {
1417
				// parts[2]
1418
				try {
1419
					Integer.parseInt(StringUtils.strip(parts[2]));
1420
				}
1421
				catch (NumberFormatException nfe) {
41 naveen 1422
					Utils.severe("Invalid value, \"" + crumb +
40 naveen 1423
							"\" = " + bulletValue);
39 naveen 1424
					return false;
1425
				}
1426
 
1427
				// parts[3]
42 naveen 1428
				if(!"mins".equalsIgnoreCase(StringUtils.strip(parts[3]))) {
41 naveen 1429
					Utils.severe("Invalid value, \"" + crumb +
40 naveen 1430
							"\" = " + bulletValue);
39 naveen 1431
					return false;
1432
				}
1433
			}
1434
		} 
1435
 
1436
		// days_hours e.g. 9 days 14 hours
1437
		else if(dt.equals("days_hours")) {
1438
			String[]  parts = StringUtils.split(bulletValue, " ");
1439
			if(!(parts.length == 2 || parts.length == 4)) {
42 naveen 1440
				Utils.severe("Invalid value, \"" + crumb +
1441
						"\" = " + bulletValue);
39 naveen 1442
				return false;
1443
			}
1444
 
1445
			// parts[0]
1446
			try {
1447
				Integer.parseInt(StringUtils.strip(parts[0]));
1448
			}
1449
			catch (NumberFormatException nfe) {
41 naveen 1450
				Utils.severe("Invalid value, \"" + crumb +
40 naveen 1451
						"\" = " + bulletValue);
39 naveen 1452
				return false;
1453
			}
1454
 
1455
			// parts[1]
42 naveen 1456
			if(!"days".equalsIgnoreCase(StringUtils.strip(parts[1]))) {
41 naveen 1457
				Utils.severe("Invalid value, \"" + crumb +
40 naveen 1458
						"\" = " + bulletValue);
39 naveen 1459
				return false;
1460
			}
1461
 
1462
			if(parts.length == 4) {
1463
				// parts[2]
1464
				try {
1465
					Integer.parseInt(StringUtils.strip(parts[2]));
1466
				}
1467
				catch (NumberFormatException nfe) {
41 naveen 1468
					Utils.severe("Invalid value, \"" + crumb +
40 naveen 1469
							"\" = " + bulletValue);
39 naveen 1470
					return false;
1471
				}
1472
 
1473
				// parts[3]
42 naveen 1474
				if("hours".equalsIgnoreCase(StringUtils.strip(parts[3]))) {
41 naveen 1475
					Utils.severe("Invalid value, \"" + crumb +
40 naveen 1476
							"\" = " + bulletValue);
39 naveen 1477
					return false;
1478
				}
1479
			}
1480
		}
1481
 
1482
		return true;
37 naveen 1483
	}
1484
 
1485
	/**
1486
	 * 
1487
	 * @param richTextRuns
1488
	 * @param info
1489
	 * @param indent
1490
	 * @param prefix
1491
	 */
36 naveen 1492
	@SuppressWarnings("unchecked")
1493
	private void drilldown(RichTextRun[] richTextRuns, 
37 naveen 1494
			Map<String, Object[]> info, int indent, String prefix) {
41 naveen 1495
		Utils.info("drilldown");
36 naveen 1496
		//System.exit(0);
1497
 
1498
 
40 naveen 1499
		Object[] featuresInfo = info.get("features");
1500
		if(featuresInfo != null) {
1501
			List<String> featureLabels = (List<String>) featuresInfo[0];
1502
			List<Integer> featureIndices = (List<Integer>) featuresInfo[1];
41 naveen 1503
			Utils.info("featureLabels=" + featureLabels);
1504
			Utils.info("featureIndices=" + featureIndices);
36 naveen 1505
 
41 naveen 1506
			Utils.info("processing features");
40 naveen 1507
			for(int i=0;i<featureLabels.size();i++) {
1508
				String featureLabel = featureLabels.get(i);
41 naveen 1509
				Utils.info("featureLabel="+featureLabel);
40 naveen 1510
 
1511
				featureLabels.set(i, StringUtils.lowerCase(
1512
						StringUtils.strip(StringUtils.trim(featureLabel))));
1513
 
1514
				int contentStartIndex = featureIndices.get(i) + 1;
1515
				int contentIndent = indent + 1;
1516
 
1517
				Map<String, Object[]> info1 = 
1518
					getContents(richTextRuns, contentStartIndex, contentIndent);
1519
 
1520
				String newprefix = StringUtils.lowerCase(prefix + "_" + 
1521
						featureLabel);
1522
 
1523
				drilldown(richTextRuns, info1, contentIndent, newprefix);
1524
			}
36 naveen 1525
 
40 naveen 1526
			if(featureLabels.size() > 0) {
44 naveen 1527
				Utils.info("prefix=" + prefix);
1528
				Utils.info("featureLabels=" + featureLabels);
1529
 
40 naveen 1530
				this.slideNameFeatureNames.put(prefix, featureLabels);
1531
			}
36 naveen 1532
		}
1533
		//System.exit(0);
1534
 
40 naveen 1535
 
1536
		Object[] bulletsInfo = info.get("bullets");
1537
		if(bulletsInfo != null) {
1538
			List<String> bulletLabels = (List<String>) bulletsInfo[0];
1539
			List<Integer> bulletIndices = (List<Integer>) bulletsInfo[1];
41 naveen 1540
			Utils.info("bulletLabels=" + bulletLabels);
1541
			Utils.info("bulletIndices=" + bulletIndices);
36 naveen 1542
 
41 naveen 1543
			Utils.info("processing bullets");
40 naveen 1544
			for(int i=0;i<bulletLabels.size();i++) {
1545
				String bulletLabel = bulletLabels.get(i);
41 naveen 1546
				Utils.info("bulletLabel="+bulletLabel);
40 naveen 1547
 
1548
				int contentStartIndex = bulletIndices.get(i) + 1;
1549
				int contentIndent = indent + 1;
1550
 
1551
				Map<String, Object[]> info1 = getContents(richTextRuns, 
1552
						contentStartIndex, contentIndent);
1553
 
1554
				drilldown(richTextRuns, info1, contentIndent, prefix);
1555
			}
36 naveen 1556
 
40 naveen 1557
			if(bulletLabels.size() > 0) {
1558
				this.slideNameFeatureNameBulletTexts.put(prefix, bulletLabels);
1559
			}
36 naveen 1560
		}
1561
		//System.exit(0);
1562
 
40 naveen 1563
 
1564
		Object[] childrenSlidesInfo = info.get("childrenSlides");
1565
		if(childrenSlidesInfo != null) {
1566
			List<String> childrenSlideLabels = 
1567
				(List<String>) childrenSlidesInfo[0];
36 naveen 1568
 
40 naveen 1569
			List<Integer> childrenSlideIndices = 
1570
				(List<Integer>) childrenSlidesInfo[1];
36 naveen 1571
 
41 naveen 1572
			Utils.info("childrenSlideLabels=" + 
40 naveen 1573
					childrenSlideLabels);
36 naveen 1574
 
41 naveen 1575
			Utils.info("childrenSlideIndices=" + 
40 naveen 1576
					childrenSlideIndices);
36 naveen 1577
 
41 naveen 1578
			Utils.info("processing children slides");
40 naveen 1579
			for(int i=0;i<childrenSlideLabels.size();i++) {
1580
				String slideLabel = childrenSlideLabels.get(i);
41 naveen 1581
				Utils.info("slideLabel="+slideLabel);
40 naveen 1582
 
1583
				childrenSlideLabels.set(i, StringUtils.lowerCase(slideLabel));
1584
 
1585
				int contentStartIndex = childrenSlideIndices.get(i) + 1;
1586
				int contentIndent = indent + 1;
1587
 
1588
				Map<String, Object[]> info1 = getContents(richTextRuns, 
1589
						contentStartIndex, contentIndent);
1590
 
1591
				String newprefix = StringUtils.lowerCase(prefix + "_" + 
1592
						slideLabel);
1593
 
1594
				drilldown(richTextRuns, info1, contentIndent, newprefix);
1595
			}
37 naveen 1596
 
40 naveen 1597
			if(childrenSlideLabels.size() > 0) {
1598
				this.slideNameChildrenSlideNames.put(prefix, 
1599
						childrenSlideLabels);
1600
			}
36 naveen 1601
		}
40 naveen 1602
 
36 naveen 1603
 
40 naveen 1604
		Object[] ffcInfo = info.get("ffc");
1605
		if(ffcInfo != null) {
1606
			List<String> ffcTexts = (List<String>) ffcInfo[0];
1607
			List<Integer> ffcIndices = (List<Integer>) ffcInfo[1];
41 naveen 1608
			Utils.info("ffcTexts=" + ffcTexts);
1609
			Utils.info("ffcIndices=" + ffcIndices);
40 naveen 1610
 
41 naveen 1611
			Utils.info("processing ffc");
40 naveen 1612
			if(ffcTexts.size() > 0) {
1613
				this.containerFCCs.put(prefix, ffcTexts);
1614
			}
37 naveen 1615
		}
36 naveen 1616
	}
1617
 
37 naveen 1618
	/**
1619
	 * 
1620
	 * @param richTextRuns
1621
	 * @param startIndex
1622
	 * @param indent
1623
	 * @return
1624
	 */
36 naveen 1625
	private Map<String, Object[]> getContents(RichTextRun[] richTextRuns, 
1626
			int startIndex, int indent) {
1627
		Map<String, Object[]> info = new HashMap<String, Object[]>();
1628
 
1629
		Object[] childrenSlidesInfo = getChildrenSlides(richTextRuns, 
1630
				startIndex, indent);
1631
		info.put("childrenSlides", childrenSlidesInfo);
1632
 
40 naveen 1633
		if(childrenSlidesInfo != null) {
41 naveen 1634
			Utils.info("childrenSlidesInfo[0]=" + 
40 naveen 1635
					childrenSlidesInfo[0]);
1636
 
41 naveen 1637
			Utils.info("childrenSlidesInfo[1]=" + 
40 naveen 1638
					childrenSlidesInfo[1]);
1639
		}
1640
 
36 naveen 1641
		Object[] featuresInfo = getFeatures(richTextRuns, 
1642
				startIndex, indent);
1643
		info.put("features", featuresInfo);
1644
 
40 naveen 1645
		if(featuresInfo != null) {
41 naveen 1646
			Utils.info("featuresInfo[0]=" + featuresInfo[0]);
1647
			Utils.info("featuresInfo[1]=" + featuresInfo[1]);
40 naveen 1648
		}
36 naveen 1649
 
1650
		Object[] bulletsInfo = getBulletInfo(richTextRuns, 
1651
				startIndex, indent);
1652
		info.put("bullets", bulletsInfo);
1653
 
40 naveen 1654
		if(bulletsInfo != null) {
41 naveen 1655
			Utils.info("bulletsInfo[0]=" + bulletsInfo[0]);
1656
			Utils.info("bulletsInfo[1]=" + bulletsInfo[1]);
40 naveen 1657
		}
36 naveen 1658
 
1659
		Object[] ffcInfo = getFreeformContent(richTextRuns, 
1660
				startIndex, indent);
1661
		info.put("ffc", ffcInfo);
1662
 
40 naveen 1663
		if(ffcInfo != null) {
41 naveen 1664
			Utils.info("ffcInfo[0]=" + ffcInfo[0]);
1665
			Utils.info("ffcInfo[1]=" + ffcInfo[1]);
40 naveen 1666
		}
36 naveen 1667
 
1668
		return info;
1669
	}
1670
 
37 naveen 1671
	/**
1672
	 * 
1673
	 * @param richTextRuns
1674
	 * @param startIndex
1675
	 * @param indent
1676
	 * @return
1677
	 */
36 naveen 1678
	private Object[] getBulletInfo(RichTextRun[] richTextRuns, 
1679
			int startIndex, int indent) {
1680
 
37 naveen 1681
		// -16776961 - Blue
36 naveen 1682
		Object[] bulletsInfo = this.getInfo(richTextRuns, startIndex, indent, 
38 naveen 1683
				HSLF.BLUE, true);
36 naveen 1684
 
1685
		return bulletsInfo;
1686
	}
1687
 
37 naveen 1688
	/**
1689
	 * 
1690
	 * @param richTextRuns
1691
	 * @param startIndex
1692
	 * @param indent
1693
	 * @return
1694
	 */
36 naveen 1695
	private Object[] getFreeformContent(RichTextRun[] richTextRuns, 
1696
			int startIndex, int indent) {
1697
 
37 naveen 1698
		// -6749953 - Purple
36 naveen 1699
		Object[] ffcInfo = this.getInfo(richTextRuns, startIndex, 
40 naveen 1700
				indent, HSLF.PURPLE, true);
36 naveen 1701
 
1702
 
1703
		return ffcInfo;
1704
	}
1705
 
37 naveen 1706
	/**
1707
	 * 
1708
	 * @param richTextRuns
1709
	 * @param startIndex
1710
	 * @param indent
1711
	 * @return
1712
	 */
36 naveen 1713
	private Object[] getFeatures(RichTextRun[] richTextRuns, 
1714
			int startIndex, int indent) {
1715
 
37 naveen 1716
		// -16711936 - Green
36 naveen 1717
		Object[] featuresInfo = this.getInfo(richTextRuns, startIndex, 
40 naveen 1718
				indent, HSLF.GREEN, true);
36 naveen 1719
 
1720
		return featuresInfo;
1721
	}
1722
 
37 naveen 1723
	/**
1724
	 * 
1725
	 * @param richTextRuns
1726
	 * @param startIndex
1727
	 * @param indent
1728
	 * @return
1729
	 */
36 naveen 1730
	private Object[] getChildrenSlides(RichTextRun[] richTextRuns, 
1731
			int startIndex, int indent) {
1732
 
37 naveen 1733
		// -26368 - Orange
36 naveen 1734
		Object[] childrenSlidesInfo = this.getInfo(richTextRuns, startIndex, 
40 naveen 1735
				indent, HSLF.ORANGE, true);
36 naveen 1736
 
1737
		return childrenSlidesInfo;
1738
	}
1739
 
37 naveen 1740
	/**
1741
	 * 
1742
	 * @param rts
1743
	 * @param startIndex
1744
	 * @param indent
1745
	 * @param rgb
1746
	 * @param debug
1747
	 * @return
1748
	 */
36 naveen 1749
	private Object[] getInfo(RichTextRun[] rts, int startIndex, 
1750
			int indent, int rgb, boolean debug) {
1751
		List<String> labels = new ArrayList<String>();
1752
		List<Integer> indices = new ArrayList<Integer>();
40 naveen 1753
 
1754
		if(startIndex >= rts.length) {
1755
			return null;
1756
		}
1757
 
36 naveen 1758
		int i = startIndex;
1759
		while(true) {
1760
			if(debug) {
41 naveen 1761
				Utils.info("rts["+i+"].getRawText=" + 
36 naveen 1762
						rts[i].getRawText());
1763
 
41 naveen 1764
				Utils.info("rts["+i+"].isBullet=" + rts[i].isBullet());
1765
				Utils.info("rts["+i+"].getIndentLevel=" + 
36 naveen 1766
						rts[i].getIndentLevel());
1767
 
41 naveen 1768
				Utils.info("rts["+i+"].getBulletColor().getRGB=" + 
36 naveen 1769
						rts[i].getBulletColor().getRGB());
1770
 
1771
 
41 naveen 1772
				Utils.info("rts["+i+"].getFontColor().getRGB=" + 
36 naveen 1773
						rts[i].getFontColor().getRGB());
1774
 
41 naveen 1775
				Utils.info("rgb=" + rgb);
1776
				Utils.info("indent=" + indent);
37 naveen 1777
 
41 naveen 1778
				Utils.info("rts.length=" + rts.length);
36 naveen 1779
			}
40 naveen 1780
			// rts[i].isBullet() && 
1781
			// rts[i].getBulletColor().getRGB() == rgb
1782
			// rts[i].getFontColor().getRGB()
1783
			if(rts[i].getIndentLevel() == indent &&
1784
					(rts[i].getBulletColor().getRGB() == rgb || 
1785
							rts[i].getFontColor().getRGB() == rgb)) {
1786
 
41 naveen 1787
				Utils.info("Criteria of color, indent etc. is met");
36 naveen 1788
				i = this.getValidLabel(i, rts, labels, indices, debug);
41 naveen 1789
				if(debug) Utils.info("new i="+ i);
36 naveen 1790
			}
41 naveen 1791
			Utils.info("labels=" + labels);
1792
			Utils.info("indices=" + indices);
36 naveen 1793
 
41 naveen 1794
			Utils.info("(i >= (rts.length-1))" + (i >= (rts.length-1)));
40 naveen 1795
			if(i >= (rts.length-1)) {
1796
				break;
1797
			}
36 naveen 1798
 
40 naveen 1799
			// rts[i+1].isBullet() && 
1800
			if(rts[i+1].getIndentLevel() < indent) {
1801
				break;
1802
			}
1803
 
36 naveen 1804
			i++;
1805
		}
1806
		return new Object[] {labels, indices};
1807
	}
1808
 
37 naveen 1809
	/**
1810
	 * 
1811
	 * @param index
1812
	 * @param rts
1813
	 * @param labels
1814
	 * @param indices
1815
	 * @param debug
1816
	 * @return
1817
	 */
36 naveen 1818
	private int getValidLabel(int index, RichTextRun[] rts, 
1819
		List<String> labels, List<Integer> indices, boolean debug){
1820
		StringBuffer sb = new StringBuffer();
1821
		while(true) {
37 naveen 1822
			if(index > rts.length - 1) {
1823
				break;
1824
			}
1825
 
36 naveen 1826
			String text = rts[index].getRawText();
1827
		    if(text.equals("\r")) {
1828
		    	break;
1829
		    }
1830
		    sb.append(text);
1831
		    index++;
1832
		}
41 naveen 1833
		if(debug)Utils.info("before label=]"+sb.toString()+"[");
36 naveen 1834
		String label = StringUtils.strip(StringUtils.trim(sb.toString()));
41 naveen 1835
		if(debug)Utils.info("after label=]"+label+"[");
36 naveen 1836
 
41 naveen 1837
		//for(int i=0;i<label.length();i++) Utils.info(label.charAt(i));
36 naveen 1838
 
1839
		if(!label.isEmpty()) {
1840
			indices.add(new Integer(index));
37 naveen 1841
 
1842
			// Remove hardspace character \xa0
1843
			char hardspace = (char)160;
1844
			char softspace = (char)32;
1845
			label = StringUtils.strip(StringUtils.replaceChars(label, 
1846
					hardspace, softspace));
1847
 
36 naveen 1848
			labels.add(label);
1849
		}
1850
 
1851
		return index;
1852
	}
41 naveen 1853
 
37 naveen 1854
	/**
1855
	 * TEST ONLY
1856
	 * 
1857
	 * @param filename
1858
	 * @throws Exception
1859
	 */
36 naveen 1860
	public static void showAllRichText(String filename) throws Exception {
1861
		HSLFSlideShow hslfSS = new HSLFSlideShow(filename);
1862
		SlideShow ss = new SlideShow(hslfSS);
1863
		Slide[] ssarr = ss.getSlides();
1864
 
1865
		for(int i=0; i < ssarr.length; i++) {
1866
			TextRun[] trarr = ssarr[i].getTextRuns();
1867
			//System.out.println("\nTitle=" + ssarr[i].getTitle());
1868
			//System.out.println(ssarr[i].getTitle());
1869
 
1870
			for(int j=0; j < trarr.length; j++) {
1871
				System.out.println("\ntrarr[" + j + "].getRawText=" + 
1872
						trarr[j].getRawText());
1873
 
1874
				RichTextRun[] rtrarr = trarr[j].getRichTextRuns();
1875
 
1876
				StringBuffer indent2 = new StringBuffer();
1877
 
1878
				for(int k=0; k < rtrarr.length; k++) {
1879
					String rawText = rtrarr[k].getRawText();
1880
					System.out.println("\nrtrarr[" + k + "].getRawText=" + 
1881
							rawText);
1882
					System.out.println("rtrarr[" + k + "].isBullet=" + 
1883
							rtrarr[k].isBullet());
1884
 
1885
					System.out.println("rtrarr[" + k + "].isUnderlined=" + 
1886
							rtrarr[k].isUnderlined());
1887
 
1888
					//System.out.println("Ends with CR=" + 
1889
					//		StringUtils.endsWith(rawText, "\r"));
1890
 
1891
					//System.out.println("\nRawText=" + rawText);
1892
 
1893
					/*
1894
					if(StringUtils.strip(rawText).isEmpty()) {
1895
						continue;
1896
					}
1897
					*/
1898
 
1899
					int indent = rtrarr[k].getIndentLevel();
1900
					System.out.println("indent=" + indent);
1901
					if(indent == 2) {
1902
						indent2.append(rawText);
1903
					}
1904
 
1905
					int rgb = rtrarr[k].getBulletColor().getRGB();
1906
					System.out.println("rgb=" + rgb);
1907
 
1908
					int fontrgb = rtrarr[k].getFontColor().getRGB();
1909
					System.out.println("font rgb=" + fontrgb);
1910
 
1911
					String fontname = rtrarr[k].getFontName();
1912
					System.out.println("font rgb=" + fontname);
1913
 
1914
				}
1915
			}
1916
		}
1917
	}
1918
 
37 naveen 1919
	/**
1920
	 * TEST ONLY
1921
	 * 
1922
	 * @param filename
1923
	 * @throws Exception
1924
	 */
36 naveen 1925
	public static void showAllText(String filename) throws Exception {
1926
		PowerPointExtractor ppe = new PowerPointExtractor(filename);
1927
		System.out.println(ppe.getText());		
1928
	}
1929
}