Subversion Repositories SmartDukaan

Rev

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

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