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()) {
54 naveen 908
			Utils.info("No features found on the slide");
909
			candidateFeatures = new ArrayList<String>();
45 naveen 910
		}
47 naveen 911
 
54 naveen 912
		// Discard if feature is not one of the valids
913
		List<String> processedFeatureLabels = new ArrayList<String>();
914
		for(String featureLabel : candidateFeatures) {
37 naveen 915
 
54 naveen 916
			if(validFeatureLabels.contains(featureLabel)) {
917
				processedFeatureLabels.add(featureLabel);
37 naveen 918
			}
54 naveen 919
			else {		
920
				Utils.severe("Invalid feature \"" + displayTextPrefix + 
921
						" > " + featureLabel + "\"");
922
			}
37 naveen 923
 
54 naveen 924
		}
925
		Utils.info("processedFeatureLabels=" + processedFeatureLabels);
926
 
927
		// For all further processing
928
		this.slideNameFeatureNames.put(slideName, processedFeatureLabels);
929
 
930
		// Fetch all mandatory features
931
		List<FeatureDefinition> mandatoryFeatureDefs = 
932
			defs.getFeatureDefinitions(slideDefID,
933
			EditorialImportance.MANDATORY);
934
 
935
		Utils.info("mandatoryFeatureDefs=" + mandatoryFeatureDefs);
936
 
937
		// Severe error if mandatory features are not included
938
		for(FeatureDefinition featureDef : mandatoryFeatureDefs) {
939
			if(!processedFeatureLabels.contains(StringUtils.lowerCase(
940
					featureDef.getLabel()))) {
941
				Utils.severe("Mandatory feature \"" + displayTextPrefix 
942
						+ " > " + featureDef.getLabel() + "\" is missing");
37 naveen 943
			}
944
		}
945
 
54 naveen 946
		// Fetch all recommended features
947
		List<FeatureDefinition> recommendedFeatureDefs = 
948
			defs.getFeatureDefinitions(slideDef.getID(),
949
			EditorialImportance.RECOMMENDED);
950
 
951
		Utils.info("recommendedFeatureDefs=" + recommendedFeatureDefs);
952
 
953
		// Warn if recommended features are not included
954
		for(FeatureDefinition featureDef : recommendedFeatureDefs) {
955
			if(!processedFeatureLabels.contains(StringUtils.lowerCase(
956
					featureDef.getLabel()))) {
957
				Utils.warning("Recommended feature \"" + displayTextPrefix + 
958
						" > " + featureDef.getLabel() + 
959
						"\" is missing");
960
			}
961
		}
962
 
42 naveen 963
		// Process features of children slides
964
		List<String> childrenSlideNames = 
965
			this.slideNameChildrenSlideNames.get(slideName);
966
 
967
		if(childrenSlideNames != null && !childrenSlideNames.isEmpty()) {
968
			for(String childSlideName : childrenSlideNames) {
969
				String fullChildSlideName = slideName + "_" + childSlideName;
970
 
971
				String newDisplayTextPrefix = displayTextPrefix + " > " + 
972
					childSlideName;
973
 
974
				this.processFeatures(fullChildSlideName, newDisplayTextPrefix);
975
			}
976
		}
977
 
37 naveen 978
	}
979
 
980
	/**
981
	 * Filter and validate parent slide names
982
	 * 
983
	 * @throws Exception 
984
	 */
985
	private void processSlides() throws Exception {
986
 
987
		// 1 Retrieve meta-data
988
		// 1.1 Retrieve all valid slide names in the content model
989
		DefinitionsContainer defs = 
990
			Catalog.getInstance().getDefinitionsContainer();
991
 
992
		List<SlideDefinition> slideDefs = defs.getSlideDefinitions(
993
				this.categoryID);
994
 
995
		List<String> validSlideNames = new ArrayList<String>();
996
		for (SlideDefinition slideDef : slideDefs) {
997
 
998
			// To avoid Introduction slide
999
			if(!slideDef.getLabel().isEmpty()) {
1000
				validSlideNames.add(StringUtils.lowerCase(slideDef.getLabel()));
1001
			}
1002
		}
41 naveen 1003
		Utils.info("validSlideNames=" + validSlideNames.toString());
37 naveen 1004
 
1005
		// 2 Rules
1006
		// 2.1 Discard if slide is not one of the valids
1007
		List<String> processedSlideNames = new ArrayList<String>();
1008
		for(String slideName : this.slideNames) {
1009
			if(validSlideNames.contains(slideName)) {
1010
				processedSlideNames.add(slideName);
1011
			}
40 naveen 1012
			else if(slideName.equals("resource urls") || 
1013
					slideName.equals("reference urls")) {
1014
				// ignore
1015
				continue;
1016
			}
37 naveen 1017
			else {
41 naveen 1018
				Utils.severe("Invalid slide \"" + slideName + "\"");
37 naveen 1019
			}
1020
		}
1021
 
42 naveen 1022
		Utils.info("processedSlideNames=" + processedSlideNames.toString());
37 naveen 1023
 
1024
		// For all further processing use processed slide names only
1025
		this.slideNames = processedSlideNames;
1026
 
1027
		// 3 Retrieve "Mandatory" slide names for the category
1028
		List<SlideDefinition> mandatorySlideDefs = 
1029
			defs.getSlides(this.categoryID, EditorialImportance.MANDATORY);
1030
 
41 naveen 1031
		Utils.info("mandatorySlideDefs=" + 
37 naveen 1032
				mandatorySlideDefs.toString());
1033
 
1034
		// 3.1 All mandatory slides exist - Severe
1035
		for(SlideDefinition mandatorySlideDef : mandatorySlideDefs) {
1036
 
1037
			// Avoid introduction slide
1038
			if(mandatorySlideDef.getLabel().isEmpty()) {
1039
				continue;
1040
			}
1041
 
40 naveen 1042
			if(mandatorySlideDef.getLabel().equals("Introduction")) {
1043
				continue;
1044
			}
1045
 
37 naveen 1046
			if(!this.slideNames.contains(
1047
					StringUtils.lowerCase(mandatorySlideDef.getLabel()))) {
1048
 
41 naveen 1049
				Utils.severe("Mandatory slide \"" + 
37 naveen 1050
						mandatorySlideDef.getLabel() + "\" is missing");
1051
			}
1052
		}
1053
 
1054
		// 4 Retrieve "Recommended" slide names for the category
1055
		List<SlideDefinition> recommendedSlideDefs = 
1056
			defs.getSlides(this.categoryID, EditorialImportance.RECOMMENDED);
1057
 
42 naveen 1058
		Utils.info("recommendedSlideDefs=" + recommendedSlideDefs.toString());
37 naveen 1059
 
1060
		// 4.1 All recommended slides exist - Warn	
1061
		for(SlideDefinition recommendedSlideDef : recommendedSlideDefs) {
1062
			if(!this.slideNames.contains(
1063
					StringUtils.lowerCase(recommendedSlideDef.getLabel()))) {
1064
 
41 naveen 1065
				Utils.warning("Recommended slide \"" + 
37 naveen 1066
						recommendedSlideDef.getLabel() + "\" is missing");
1067
			}
1068
		}
42 naveen 1069
 
1070
		// Process children slides
1071
		for(String parentSlideName : this.slideNames) {
1072
			Utils.info("Process children slides for parentSlideName=" + 
1073
					parentSlideName);
1074
 
1075
			SlideDefinition parentSlideDef = 
1076
				this.getSlideDefinition(parentSlideName);
1077
 
1078
			// ignore for now
1079
			if(parentSlideDef == null) {
1080
				continue;
1081
			}
1082
 
1083
			this.processChildrenSlides(parentSlideDef, parentSlideName, 
1084
					parentSlideDef.getLabel());
1085
		}
1086
 
1087
		Utils.info("slideNameChildrenSlideNames=" + 
1088
				slideNameChildrenSlideNames);
37 naveen 1089
	}
1090
 
1091
	/**
1092
	 * 
42 naveen 1093
	 * @param slideName
1094
	 * @param parentSlideDefinition
1095
	 * @param crumb
1096
	 * @throws Exception 
1097
	 */
1098
	private void processChildrenSlides(SlideDefinition parentSlideDef, 
1099
			String crumb, String displayTextPrefix) throws Exception {
1100
 
1101
		List<Long> childrenSlideDefinitionIDs = 
1102
			parentSlideDef.getChildrenSlideDefinitionIDs();
1103
 
1104
		if(childrenSlideDefinitionIDs == null || 
1105
				childrenSlideDefinitionIDs.isEmpty()) {
1106
			return;
1107
		}
1108
 
1109
		DefinitionsContainer defs = 
1110
			Catalog.getInstance().getDefinitionsContainer();
1111
 
1112
		String parentSlideName = parentSlideDef.getLabel();
1113
		Utils.info("parentSlideName=" + parentSlideName + " has " + 
1114
				childrenSlideDefinitionIDs + " children slides to process");
1115
 
1116
		Utils.info("crumb=" + crumb);
1117
 
1118
		List<String> childrenSlideNames = 
1119
			this.slideNameChildrenSlideNames.get(crumb);
1120
		Utils.info("childrenSlideNames=" + childrenSlideNames);
1121
 
1122
		// Collect allowed children slide labels
1123
		List<String> validChildrenSlideNames = new ArrayList<String>();
1124
 
1125
		Map<String, SlideDefinition> childSlideNameSlideDefinition = 
1126
			new HashMap<String, SlideDefinition>();
1127
 
1128
		for(Long childSlideDefID : childrenSlideDefinitionIDs) {
1129
			Utils.info("childSlideDefID=" + childSlideDefID);
1130
 
1131
			SlideDefinition childSlideDef = 
1132
				defs.getSlideDefinition(childSlideDefID.longValue());
1133
			Utils.info("childSlideDef=" + childSlideDef);
1134
 
1135
			String displaytext = displayTextPrefix + " > " + 
1136
				childSlideDef.getLabel();
1137
 
1138
			// All children slides defined are mandatory
1139
			String childSlideName = 
1140
				StringUtils.lowerCase(childSlideDef.getLabel());
1141
			Utils.info("childSlideName=" + childSlideName);
1142
 
1143
			if(childrenSlideNames == null || 
1144
					!childrenSlideNames.contains(childSlideName)) {
1145
				Utils.severe("Missing child slide \"" + displaytext + "\"");
1146
				continue;
1147
			}
1148
 
1149
			validChildrenSlideNames.add(childSlideName);
1150
			childSlideNameSlideDefinition.put(childSlideName, childSlideDef);
1151
		}
1152
 
1153
		this.slideNameChildrenSlideNames.put(crumb, validChildrenSlideNames);
1154
		Utils.info("validChildrenSlideNames=" + validChildrenSlideNames);
1155
 
1156
		for(String childSlideName : childSlideNameSlideDefinition.keySet()) {
1157
			SlideDefinition slideDef = 
1158
				childSlideNameSlideDefinition.get(childSlideName);
1159
 
1160
			String newcrumb = crumb + "_" + 
1161
				StringUtils.lowerCase(childSlideName);
1162
 
1163
			String newDisplayTextPrefix = displayTextPrefix + " > " + 
1164
				slideDef.getLabel();
1165
 
1166
			this.processChildrenSlides(slideDef, newcrumb, 
1167
					newDisplayTextPrefix);
1168
		}
1169
	}
49 naveen 1170
 
42 naveen 1171
	/**
1172
	 * 
37 naveen 1173
	 * @param bulletText
49 naveen 1174
	 * @param featureDef
1175
	 * @param crumb
1176
	 * @param prefix
1177
	 * @return
1178
	 * @throws Exception
37 naveen 1179
	 */
1180
	private Bullet processBulletText(String bulletText, 
38 naveen 1181
			FeatureDefinition featureDef, String crumb, String prefix) 
1182
			throws Exception {
41 naveen 1183
		Utils.info("featureDef.getLabel=" + featureDef.getLabel());
1184
		Utils.info("bulletText=" + bulletText);
40 naveen 1185
 
37 naveen 1186
		BulletDefinition bulletDef = featureDef.getBulletDefinition();
41 naveen 1187
		Utils.info("bulletDefinition=" + bulletDef);
37 naveen 1188
 
1189
		DefinitionsContainer defs = 
1190
			Catalog.getInstance().getDefinitionsContainer();
1191
 
1192
		// If unit is defined
1193
		Unit unitDef =  null;
1194
		if(bulletDef.getUnitID() != 0L) {
1195
			long unitID = bulletDef.getUnitID();
1196
			unitDef = defs.getUnit(unitID);
41 naveen 1197
			Utils.info("unitDef=" + unitDef);
37 naveen 1198
		}
1199
 
1200
		long datatypeDefID = bulletDef.getDatatypeDefinitionID();
1201
		DatatypeDefinition datatypeDef = 
1202
			defs.getDatatypeDefinition(datatypeDefID);
41 naveen 1203
		Utils.info("datatypeDef=" + datatypeDef);
37 naveen 1204
 
1205
		// If primitive
1206
		boolean isEnum = false;
1207
		boolean isComposite = false;
1208
		boolean isPrimitive = false;
1209
		if(datatypeDef instanceof EnumDefinition) {
1210
			isEnum = true;
1211
		}
1212
		else if(datatypeDef instanceof CompositeDefinition) {
1213
			isComposite = true;
1214
		}
1215
		else {
1216
			isPrimitive = true;
1217
		}
1218
 
41 naveen 1219
		Utils.info("isEnum=" + isEnum + " isComposite=" + isComposite +
37 naveen 1220
				" isPrimitive=" + isPrimitive);
1221
 
1222
		// if no unit is defined for this bullet whole is treated as value
1223
		String bulletValue = bulletText;
1224
		Bullet bullet = null;
1225
 
1226
		// If unit is defined
1227
		if(bulletDef.getUnitID() != 0L) {
1228
 
1229
			// Validate unit
1230
			String[] parts = StringUtils.split(bulletText, " ");
1231
			if(parts.length < 2) {
41 naveen 1232
				Utils.severe("Unit is missing, \"" + crumb + "\" = " + 
37 naveen 1233
						bulletText);
1234
 
1235
				return null;
1236
			}
1237
 
1238
			else if(parts.length > 2) {
41 naveen 1239
				Utils.severe("Invalid value, \"" + crumb + "\" = " + 
37 naveen 1240
						bulletText);
1241
 
1242
				return null;
1243
			}
1244
 
1245
			bulletValue = parts[0];
1246
			String unitValue = parts[1];
41 naveen 1247
			Utils.info("unitValue="+unitValue);
37 naveen 1248
 
1249
			if(!(unitValue.equalsIgnoreCase(unitDef.getShortForm()) ||
1250
					unitValue.equalsIgnoreCase(unitDef.getFullForm()))) {
1251
 
41 naveen 1252
				Utils.severe("Invalid unit, \"" + crumb + "\" = " + 
37 naveen 1253
						bulletText);
1254
 
1255
			}
1256
		}
1257
 
1258
		// Validate bullet value
41 naveen 1259
		Utils.info("bulletValue=" + bulletValue);
37 naveen 1260
		if(isPrimitive) {
1261
			if(!this.validatePrimitive(bulletValue, datatypeDef, crumb)) {
1262
				return null;
1263
			}
1264
 
1265
			bullet = new Bullet(new PrimitiveDataObject(bulletValue));
1266
		}
1267
 
1268
		// Enum and fixed
1269
		else if(isEnum && !bulletDef.isLearned()) {
1270
			long enumValueID = defs.getEnumValueID(datatypeDef.getID(), 
1271
					bulletValue);
41 naveen 1272
			Utils.info("enumValueID=" + enumValueID);
37 naveen 1273
 
1274
			// Treat it to be free-form
1275
			if(enumValueID == -1L) {
41 naveen 1276
				Utils.severe("Not one of the valid enum values, \"" +
40 naveen 1277
						crumb + "\" = " + bulletValue);
37 naveen 1278
 
1279
				return null;
1280
			}
1281
 
1282
			EnumDataObject enumDataObject = new EnumDataObject(enumValueID);
1283
			bullet = new Bullet(enumDataObject);
1284
		}
1285
 
1286
		// Composite
1287
		else if(isComposite) {
1288
			CompositeDefinition compositeDef = 
1289
				(CompositeDefinition)datatypeDef;
1290
 
1291
			String separator = compositeDef.getSeparator();
1292
			String[] compositeParts = 
1293
				StringUtils.split(bulletValue, separator);
1294
 
1295
			List<CompositePartDefinition> compositePartDefs = 
1296
				compositeDef.getCompositePartDefinitions();
1297
 
1298
			// Validate number of parts
1299
			if(compositeParts.length != compositePartDefs.size()) {
41 naveen 1300
				Utils.severe("Invalid value, " + crumb + " = " + 
37 naveen 1301
						bulletValue);
1302
 
1303
				return null;
1304
			}
1305
 
1306
			// Remove spurious whitespaces
1307
			boolean validPart = true;
1308
			for(int j=0;j<compositeParts.length;j++) {
1309
				compositeParts[j] = StringUtils.strip(compositeParts[j]);
41 naveen 1310
				Utils.info("compositeParts["+ j + "]=" + 
37 naveen 1311
						compositeParts[j]);
1312
 
1313
				// Validate each part
1314
				// Each part can be enum or composite in itself
1315
				// We will stick to primitive for now
1316
				long partDatatypeDefID = 
1317
					compositePartDefs.get(j).getDatatypeDefinitionID();
1318
 
1319
				DatatypeDefinition partDatatypeDef = 
1320
					defs.getDatatypeDefinition(partDatatypeDefID);
41 naveen 1321
				Utils.info("partDatatypeDef=" + partDatatypeDef);
37 naveen 1322
 
1323
				if(!this.validatePrimitive(compositeParts[j], 
1324
						partDatatypeDef, crumb)) {
1325
					validPart = false;
1326
					break;
1327
				}
1328
			}
1329
 
1330
			if(!validPart) {
1331
				return null;
1332
			}
1333
 
1334
			CompositeDataObject compositeDataObject = 
1335
				new CompositeDataObject();
1336
 
1337
			for(int j=0;j<compositeParts.length;j++) {
1338
				compositeDataObject.addPrimitiveDataObject(
1339
						new PrimitiveDataObject(compositeParts[j]));
1340
			}
1341
 
1342
			bullet = new Bullet(compositeDataObject);
1343
		}
1344
 
38 naveen 1345
		// Free-form content at bullet level
1346
		String key = prefix + "_" + bulletText;
1347
		List<String> bulletFFCs = this.containerFCCs.get(key);
1348
		bullet.setFreeformContent(new FreeformContent(StringUtils.join(
1349
				bulletFFCs, "|")));
1350
 
37 naveen 1351
		return bullet;
1352
	}
1353
 
1354
 
1355
	/**
1356
	 * 
1357
	 * @param bulletValue
1358
	 * @param datatypeDef
1359
	 * @param crumb
1360
	 */
1361
	private boolean validatePrimitive(String bulletValue, 
1362
			DatatypeDefinition datatypeDef, String crumb) {
1363
		String dt = datatypeDef.getName();
1364
 
1365
		// integer
1366
		if(dt.equals("integer")) {
1367
			try {
1368
				Integer.parseInt(bulletValue);
1369
			}
1370
			catch(NumberFormatException nfe) {
41 naveen 1371
				Utils.severe("Invalid integer value, \"" + crumb +
40 naveen 1372
						"\" = " + bulletValue);
39 naveen 1373
				return false;
37 naveen 1374
			}
1375
		}
1376
 
1377
		// decimal
39 naveen 1378
		else if(dt.equals("decimal")) {
37 naveen 1379
			try {
1380
				Float.parseFloat(bulletValue);
1381
			}
1382
			catch(NumberFormatException nfe) {
41 naveen 1383
				Utils.severe("Invalid decimal value, \"" + crumb +
40 naveen 1384
						"\" = " + bulletValue);
39 naveen 1385
				return false;
37 naveen 1386
			}
1387
		}
1388
 
39 naveen 1389
		// hours_mins e.g. 2 hours 40 mins
1390
		else if(dt.equals("hours_mins")) {
1391
			String[]  parts = StringUtils.split(bulletValue, " ");
1392
			if(!(parts.length == 2 || parts.length == 4)) {
42 naveen 1393
				Utils.severe("Invalid value, \"" + crumb +
1394
						"\" = " + bulletValue);
39 naveen 1395
				return false;
1396
			}
1397
			// parts[0]
1398
			try {
1399
				Integer.parseInt(StringUtils.strip(parts[0]));
1400
			}
1401
			catch (NumberFormatException nfe) {
41 naveen 1402
				Utils.severe("Invalid value, \"" + crumb +
40 naveen 1403
						"\" = " + bulletValue);
39 naveen 1404
				return false;
1405
			}
1406
 
1407
			// parts[1]
42 naveen 1408
			if(!"hours".equalsIgnoreCase(StringUtils.strip(parts[1]))) {
41 naveen 1409
				Utils.severe("Invalid value, \"" + crumb +
40 naveen 1410
						"\" = " + bulletValue);
39 naveen 1411
				return false;
1412
			}
1413
 
1414
			if(parts.length == 4) {
1415
				// parts[2]
1416
				try {
1417
					Integer.parseInt(StringUtils.strip(parts[2]));
1418
				}
1419
				catch (NumberFormatException nfe) {
41 naveen 1420
					Utils.severe("Invalid value, \"" + crumb +
40 naveen 1421
							"\" = " + bulletValue);
39 naveen 1422
					return false;
1423
				}
1424
 
1425
				// parts[3]
42 naveen 1426
				if(!"mins".equalsIgnoreCase(StringUtils.strip(parts[3]))) {
41 naveen 1427
					Utils.severe("Invalid value, \"" + crumb +
40 naveen 1428
							"\" = " + bulletValue);
39 naveen 1429
					return false;
1430
				}
1431
			}
1432
		} 
1433
 
1434
		// days_hours e.g. 9 days 14 hours
1435
		else if(dt.equals("days_hours")) {
1436
			String[]  parts = StringUtils.split(bulletValue, " ");
1437
			if(!(parts.length == 2 || parts.length == 4)) {
42 naveen 1438
				Utils.severe("Invalid value, \"" + crumb +
1439
						"\" = " + bulletValue);
39 naveen 1440
				return false;
1441
			}
1442
 
1443
			// parts[0]
1444
			try {
1445
				Integer.parseInt(StringUtils.strip(parts[0]));
1446
			}
1447
			catch (NumberFormatException nfe) {
41 naveen 1448
				Utils.severe("Invalid value, \"" + crumb +
40 naveen 1449
						"\" = " + bulletValue);
39 naveen 1450
				return false;
1451
			}
1452
 
1453
			// parts[1]
42 naveen 1454
			if(!"days".equalsIgnoreCase(StringUtils.strip(parts[1]))) {
41 naveen 1455
				Utils.severe("Invalid value, \"" + crumb +
40 naveen 1456
						"\" = " + bulletValue);
39 naveen 1457
				return false;
1458
			}
1459
 
1460
			if(parts.length == 4) {
1461
				// parts[2]
1462
				try {
1463
					Integer.parseInt(StringUtils.strip(parts[2]));
1464
				}
1465
				catch (NumberFormatException nfe) {
41 naveen 1466
					Utils.severe("Invalid value, \"" + crumb +
40 naveen 1467
							"\" = " + bulletValue);
39 naveen 1468
					return false;
1469
				}
1470
 
1471
				// parts[3]
42 naveen 1472
				if("hours".equalsIgnoreCase(StringUtils.strip(parts[3]))) {
41 naveen 1473
					Utils.severe("Invalid value, \"" + crumb +
40 naveen 1474
							"\" = " + bulletValue);
39 naveen 1475
					return false;
1476
				}
1477
			}
1478
		}
1479
 
1480
		return true;
37 naveen 1481
	}
1482
 
1483
	/**
1484
	 * 
1485
	 * @param richTextRuns
1486
	 * @param info
1487
	 * @param indent
1488
	 * @param prefix
1489
	 */
36 naveen 1490
	@SuppressWarnings("unchecked")
1491
	private void drilldown(RichTextRun[] richTextRuns, 
37 naveen 1492
			Map<String, Object[]> info, int indent, String prefix) {
41 naveen 1493
		Utils.info("drilldown");
36 naveen 1494
		//System.exit(0);
1495
 
1496
 
40 naveen 1497
		Object[] featuresInfo = info.get("features");
1498
		if(featuresInfo != null) {
1499
			List<String> featureLabels = (List<String>) featuresInfo[0];
1500
			List<Integer> featureIndices = (List<Integer>) featuresInfo[1];
41 naveen 1501
			Utils.info("featureLabels=" + featureLabels);
1502
			Utils.info("featureIndices=" + featureIndices);
36 naveen 1503
 
41 naveen 1504
			Utils.info("processing features");
40 naveen 1505
			for(int i=0;i<featureLabels.size();i++) {
1506
				String featureLabel = featureLabels.get(i);
41 naveen 1507
				Utils.info("featureLabel="+featureLabel);
40 naveen 1508
 
1509
				featureLabels.set(i, StringUtils.lowerCase(
1510
						StringUtils.strip(StringUtils.trim(featureLabel))));
1511
 
1512
				int contentStartIndex = featureIndices.get(i) + 1;
1513
				int contentIndent = indent + 1;
1514
 
1515
				Map<String, Object[]> info1 = 
1516
					getContents(richTextRuns, contentStartIndex, contentIndent);
1517
 
1518
				String newprefix = StringUtils.lowerCase(prefix + "_" + 
1519
						featureLabel);
1520
 
1521
				drilldown(richTextRuns, info1, contentIndent, newprefix);
1522
			}
36 naveen 1523
 
40 naveen 1524
			if(featureLabels.size() > 0) {
44 naveen 1525
				Utils.info("prefix=" + prefix);
1526
				Utils.info("featureLabels=" + featureLabels);
1527
 
40 naveen 1528
				this.slideNameFeatureNames.put(prefix, featureLabels);
1529
			}
36 naveen 1530
		}
1531
		//System.exit(0);
1532
 
40 naveen 1533
 
1534
		Object[] bulletsInfo = info.get("bullets");
1535
		if(bulletsInfo != null) {
1536
			List<String> bulletLabels = (List<String>) bulletsInfo[0];
1537
			List<Integer> bulletIndices = (List<Integer>) bulletsInfo[1];
41 naveen 1538
			Utils.info("bulletLabels=" + bulletLabels);
1539
			Utils.info("bulletIndices=" + bulletIndices);
36 naveen 1540
 
41 naveen 1541
			Utils.info("processing bullets");
40 naveen 1542
			for(int i=0;i<bulletLabels.size();i++) {
1543
				String bulletLabel = bulletLabels.get(i);
41 naveen 1544
				Utils.info("bulletLabel="+bulletLabel);
40 naveen 1545
 
1546
				int contentStartIndex = bulletIndices.get(i) + 1;
1547
				int contentIndent = indent + 1;
1548
 
1549
				Map<String, Object[]> info1 = getContents(richTextRuns, 
1550
						contentStartIndex, contentIndent);
1551
 
1552
				drilldown(richTextRuns, info1, contentIndent, prefix);
1553
			}
36 naveen 1554
 
40 naveen 1555
			if(bulletLabels.size() > 0) {
1556
				this.slideNameFeatureNameBulletTexts.put(prefix, bulletLabels);
1557
			}
36 naveen 1558
		}
1559
		//System.exit(0);
1560
 
40 naveen 1561
 
1562
		Object[] childrenSlidesInfo = info.get("childrenSlides");
1563
		if(childrenSlidesInfo != null) {
1564
			List<String> childrenSlideLabels = 
1565
				(List<String>) childrenSlidesInfo[0];
36 naveen 1566
 
40 naveen 1567
			List<Integer> childrenSlideIndices = 
1568
				(List<Integer>) childrenSlidesInfo[1];
36 naveen 1569
 
41 naveen 1570
			Utils.info("childrenSlideLabels=" + 
40 naveen 1571
					childrenSlideLabels);
36 naveen 1572
 
41 naveen 1573
			Utils.info("childrenSlideIndices=" + 
40 naveen 1574
					childrenSlideIndices);
36 naveen 1575
 
41 naveen 1576
			Utils.info("processing children slides");
40 naveen 1577
			for(int i=0;i<childrenSlideLabels.size();i++) {
1578
				String slideLabel = childrenSlideLabels.get(i);
41 naveen 1579
				Utils.info("slideLabel="+slideLabel);
40 naveen 1580
 
1581
				childrenSlideLabels.set(i, StringUtils.lowerCase(slideLabel));
1582
 
1583
				int contentStartIndex = childrenSlideIndices.get(i) + 1;
1584
				int contentIndent = indent + 1;
1585
 
1586
				Map<String, Object[]> info1 = getContents(richTextRuns, 
1587
						contentStartIndex, contentIndent);
1588
 
1589
				String newprefix = StringUtils.lowerCase(prefix + "_" + 
1590
						slideLabel);
1591
 
1592
				drilldown(richTextRuns, info1, contentIndent, newprefix);
1593
			}
37 naveen 1594
 
40 naveen 1595
			if(childrenSlideLabels.size() > 0) {
1596
				this.slideNameChildrenSlideNames.put(prefix, 
1597
						childrenSlideLabels);
1598
			}
36 naveen 1599
		}
40 naveen 1600
 
36 naveen 1601
 
40 naveen 1602
		Object[] ffcInfo = info.get("ffc");
1603
		if(ffcInfo != null) {
1604
			List<String> ffcTexts = (List<String>) ffcInfo[0];
1605
			List<Integer> ffcIndices = (List<Integer>) ffcInfo[1];
41 naveen 1606
			Utils.info("ffcTexts=" + ffcTexts);
1607
			Utils.info("ffcIndices=" + ffcIndices);
40 naveen 1608
 
41 naveen 1609
			Utils.info("processing ffc");
40 naveen 1610
			if(ffcTexts.size() > 0) {
1611
				this.containerFCCs.put(prefix, ffcTexts);
1612
			}
37 naveen 1613
		}
36 naveen 1614
	}
1615
 
37 naveen 1616
	/**
1617
	 * 
1618
	 * @param richTextRuns
1619
	 * @param startIndex
1620
	 * @param indent
1621
	 * @return
1622
	 */
36 naveen 1623
	private Map<String, Object[]> getContents(RichTextRun[] richTextRuns, 
1624
			int startIndex, int indent) {
1625
		Map<String, Object[]> info = new HashMap<String, Object[]>();
1626
 
1627
		Object[] childrenSlidesInfo = getChildrenSlides(richTextRuns, 
1628
				startIndex, indent);
1629
		info.put("childrenSlides", childrenSlidesInfo);
1630
 
40 naveen 1631
		if(childrenSlidesInfo != null) {
41 naveen 1632
			Utils.info("childrenSlidesInfo[0]=" + 
40 naveen 1633
					childrenSlidesInfo[0]);
1634
 
41 naveen 1635
			Utils.info("childrenSlidesInfo[1]=" + 
40 naveen 1636
					childrenSlidesInfo[1]);
1637
		}
1638
 
36 naveen 1639
		Object[] featuresInfo = getFeatures(richTextRuns, 
1640
				startIndex, indent);
1641
		info.put("features", featuresInfo);
1642
 
40 naveen 1643
		if(featuresInfo != null) {
41 naveen 1644
			Utils.info("featuresInfo[0]=" + featuresInfo[0]);
1645
			Utils.info("featuresInfo[1]=" + featuresInfo[1]);
40 naveen 1646
		}
36 naveen 1647
 
1648
		Object[] bulletsInfo = getBulletInfo(richTextRuns, 
1649
				startIndex, indent);
1650
		info.put("bullets", bulletsInfo);
1651
 
40 naveen 1652
		if(bulletsInfo != null) {
41 naveen 1653
			Utils.info("bulletsInfo[0]=" + bulletsInfo[0]);
1654
			Utils.info("bulletsInfo[1]=" + bulletsInfo[1]);
40 naveen 1655
		}
36 naveen 1656
 
1657
		Object[] ffcInfo = getFreeformContent(richTextRuns, 
1658
				startIndex, indent);
1659
		info.put("ffc", ffcInfo);
1660
 
40 naveen 1661
		if(ffcInfo != null) {
41 naveen 1662
			Utils.info("ffcInfo[0]=" + ffcInfo[0]);
1663
			Utils.info("ffcInfo[1]=" + ffcInfo[1]);
40 naveen 1664
		}
36 naveen 1665
 
1666
		return info;
1667
	}
1668
 
37 naveen 1669
	/**
1670
	 * 
1671
	 * @param richTextRuns
1672
	 * @param startIndex
1673
	 * @param indent
1674
	 * @return
1675
	 */
36 naveen 1676
	private Object[] getBulletInfo(RichTextRun[] richTextRuns, 
1677
			int startIndex, int indent) {
1678
 
37 naveen 1679
		// -16776961 - Blue
36 naveen 1680
		Object[] bulletsInfo = this.getInfo(richTextRuns, startIndex, indent, 
38 naveen 1681
				HSLF.BLUE, true);
36 naveen 1682
 
1683
		return bulletsInfo;
1684
	}
1685
 
37 naveen 1686
	/**
1687
	 * 
1688
	 * @param richTextRuns
1689
	 * @param startIndex
1690
	 * @param indent
1691
	 * @return
1692
	 */
36 naveen 1693
	private Object[] getFreeformContent(RichTextRun[] richTextRuns, 
1694
			int startIndex, int indent) {
1695
 
37 naveen 1696
		// -6749953 - Purple
36 naveen 1697
		Object[] ffcInfo = this.getInfo(richTextRuns, startIndex, 
40 naveen 1698
				indent, HSLF.PURPLE, true);
36 naveen 1699
 
1700
 
1701
		return ffcInfo;
1702
	}
1703
 
37 naveen 1704
	/**
1705
	 * 
1706
	 * @param richTextRuns
1707
	 * @param startIndex
1708
	 * @param indent
1709
	 * @return
1710
	 */
36 naveen 1711
	private Object[] getFeatures(RichTextRun[] richTextRuns, 
1712
			int startIndex, int indent) {
1713
 
37 naveen 1714
		// -16711936 - Green
36 naveen 1715
		Object[] featuresInfo = this.getInfo(richTextRuns, startIndex, 
40 naveen 1716
				indent, HSLF.GREEN, true);
36 naveen 1717
 
1718
		return featuresInfo;
1719
	}
1720
 
37 naveen 1721
	/**
1722
	 * 
1723
	 * @param richTextRuns
1724
	 * @param startIndex
1725
	 * @param indent
1726
	 * @return
1727
	 */
36 naveen 1728
	private Object[] getChildrenSlides(RichTextRun[] richTextRuns, 
1729
			int startIndex, int indent) {
1730
 
37 naveen 1731
		// -26368 - Orange
36 naveen 1732
		Object[] childrenSlidesInfo = this.getInfo(richTextRuns, startIndex, 
40 naveen 1733
				indent, HSLF.ORANGE, true);
36 naveen 1734
 
1735
		return childrenSlidesInfo;
1736
	}
1737
 
37 naveen 1738
	/**
1739
	 * 
1740
	 * @param rts
1741
	 * @param startIndex
1742
	 * @param indent
1743
	 * @param rgb
1744
	 * @param debug
1745
	 * @return
1746
	 */
36 naveen 1747
	private Object[] getInfo(RichTextRun[] rts, int startIndex, 
1748
			int indent, int rgb, boolean debug) {
1749
		List<String> labels = new ArrayList<String>();
1750
		List<Integer> indices = new ArrayList<Integer>();
40 naveen 1751
 
1752
		if(startIndex >= rts.length) {
1753
			return null;
1754
		}
1755
 
36 naveen 1756
		int i = startIndex;
1757
		while(true) {
1758
			if(debug) {
41 naveen 1759
				Utils.info("rts["+i+"].getRawText=" + 
36 naveen 1760
						rts[i].getRawText());
1761
 
41 naveen 1762
				Utils.info("rts["+i+"].isBullet=" + rts[i].isBullet());
1763
				Utils.info("rts["+i+"].getIndentLevel=" + 
36 naveen 1764
						rts[i].getIndentLevel());
1765
 
41 naveen 1766
				Utils.info("rts["+i+"].getBulletColor().getRGB=" + 
36 naveen 1767
						rts[i].getBulletColor().getRGB());
1768
 
1769
 
41 naveen 1770
				Utils.info("rts["+i+"].getFontColor().getRGB=" + 
36 naveen 1771
						rts[i].getFontColor().getRGB());
1772
 
41 naveen 1773
				Utils.info("rgb=" + rgb);
1774
				Utils.info("indent=" + indent);
37 naveen 1775
 
41 naveen 1776
				Utils.info("rts.length=" + rts.length);
36 naveen 1777
			}
40 naveen 1778
			// rts[i].isBullet() && 
1779
			// rts[i].getBulletColor().getRGB() == rgb
1780
			// rts[i].getFontColor().getRGB()
1781
			if(rts[i].getIndentLevel() == indent &&
1782
					(rts[i].getBulletColor().getRGB() == rgb || 
1783
							rts[i].getFontColor().getRGB() == rgb)) {
1784
 
41 naveen 1785
				Utils.info("Criteria of color, indent etc. is met");
36 naveen 1786
				i = this.getValidLabel(i, rts, labels, indices, debug);
41 naveen 1787
				if(debug) Utils.info("new i="+ i);
36 naveen 1788
			}
41 naveen 1789
			Utils.info("labels=" + labels);
1790
			Utils.info("indices=" + indices);
36 naveen 1791
 
41 naveen 1792
			Utils.info("(i >= (rts.length-1))" + (i >= (rts.length-1)));
40 naveen 1793
			if(i >= (rts.length-1)) {
1794
				break;
1795
			}
36 naveen 1796
 
40 naveen 1797
			// rts[i+1].isBullet() && 
1798
			if(rts[i+1].getIndentLevel() < indent) {
1799
				break;
1800
			}
1801
 
36 naveen 1802
			i++;
1803
		}
1804
		return new Object[] {labels, indices};
1805
	}
1806
 
37 naveen 1807
	/**
1808
	 * 
1809
	 * @param index
1810
	 * @param rts
1811
	 * @param labels
1812
	 * @param indices
1813
	 * @param debug
1814
	 * @return
1815
	 */
36 naveen 1816
	private int getValidLabel(int index, RichTextRun[] rts, 
1817
		List<String> labels, List<Integer> indices, boolean debug){
1818
		StringBuffer sb = new StringBuffer();
1819
		while(true) {
37 naveen 1820
			if(index > rts.length - 1) {
1821
				break;
1822
			}
1823
 
36 naveen 1824
			String text = rts[index].getRawText();
1825
		    if(text.equals("\r")) {
1826
		    	break;
1827
		    }
1828
		    sb.append(text);
1829
		    index++;
1830
		}
41 naveen 1831
		if(debug)Utils.info("before label=]"+sb.toString()+"[");
36 naveen 1832
		String label = StringUtils.strip(StringUtils.trim(sb.toString()));
41 naveen 1833
		if(debug)Utils.info("after label=]"+label+"[");
36 naveen 1834
 
41 naveen 1835
		//for(int i=0;i<label.length();i++) Utils.info(label.charAt(i));
36 naveen 1836
 
1837
		if(!label.isEmpty()) {
1838
			indices.add(new Integer(index));
37 naveen 1839
 
1840
			// Remove hardspace character \xa0
1841
			char hardspace = (char)160;
1842
			char softspace = (char)32;
1843
			label = StringUtils.strip(StringUtils.replaceChars(label, 
1844
					hardspace, softspace));
1845
 
36 naveen 1846
			labels.add(label);
1847
		}
1848
 
1849
		return index;
1850
	}
41 naveen 1851
 
37 naveen 1852
	/**
1853
	 * TEST ONLY
1854
	 * 
1855
	 * @param filename
1856
	 * @throws Exception
1857
	 */
36 naveen 1858
	public static void showAllRichText(String filename) throws Exception {
1859
		HSLFSlideShow hslfSS = new HSLFSlideShow(filename);
1860
		SlideShow ss = new SlideShow(hslfSS);
1861
		Slide[] ssarr = ss.getSlides();
1862
 
1863
		for(int i=0; i < ssarr.length; i++) {
1864
			TextRun[] trarr = ssarr[i].getTextRuns();
1865
			//System.out.println("\nTitle=" + ssarr[i].getTitle());
1866
			//System.out.println(ssarr[i].getTitle());
1867
 
1868
			for(int j=0; j < trarr.length; j++) {
1869
				System.out.println("\ntrarr[" + j + "].getRawText=" + 
1870
						trarr[j].getRawText());
1871
 
1872
				RichTextRun[] rtrarr = trarr[j].getRichTextRuns();
1873
 
1874
				StringBuffer indent2 = new StringBuffer();
1875
 
1876
				for(int k=0; k < rtrarr.length; k++) {
1877
					String rawText = rtrarr[k].getRawText();
1878
					System.out.println("\nrtrarr[" + k + "].getRawText=" + 
1879
							rawText);
1880
					System.out.println("rtrarr[" + k + "].isBullet=" + 
1881
							rtrarr[k].isBullet());
1882
 
1883
					System.out.println("rtrarr[" + k + "].isUnderlined=" + 
1884
							rtrarr[k].isUnderlined());
1885
 
1886
					//System.out.println("Ends with CR=" + 
1887
					//		StringUtils.endsWith(rawText, "\r"));
1888
 
1889
					//System.out.println("\nRawText=" + rawText);
1890
 
1891
					/*
1892
					if(StringUtils.strip(rawText).isEmpty()) {
1893
						continue;
1894
					}
1895
					*/
1896
 
1897
					int indent = rtrarr[k].getIndentLevel();
1898
					System.out.println("indent=" + indent);
1899
					if(indent == 2) {
1900
						indent2.append(rawText);
1901
					}
1902
 
1903
					int rgb = rtrarr[k].getBulletColor().getRGB();
1904
					System.out.println("rgb=" + rgb);
1905
 
1906
					int fontrgb = rtrarr[k].getFontColor().getRGB();
1907
					System.out.println("font rgb=" + fontrgb);
1908
 
1909
					String fontname = rtrarr[k].getFontName();
1910
					System.out.println("font rgb=" + fontname);
1911
 
1912
				}
1913
			}
1914
		}
1915
	}
1916
 
37 naveen 1917
	/**
1918
	 * TEST ONLY
1919
	 * 
1920
	 * @param filename
1921
	 * @throws Exception
1922
	 */
36 naveen 1923
	public static void showAllText(String filename) throws Exception {
1924
		PowerPointExtractor ppe = new PowerPointExtractor(filename);
1925
		System.out.println(ppe.getText());		
1926
	}
1927
}