Project

General

Profile

Download (23.2 KB) Statistics
| Branch: | Revision:
1
package eu.etaxonomy.cdm.io.xper;
2

    
3
import java.util.HashMap;
4
import java.util.List;
5
import java.util.Map;
6
import java.util.Set;
7
import java.util.UUID;
8

    
9
import org.apache.commons.lang.StringUtils;
10
import org.apache.log4j.Logger;
11
import org.springframework.stereotype.Component;
12
import org.springframework.transaction.TransactionStatus;
13

    
14
import eu.etaxonomy.cdm.api.service.ITermService;
15
import eu.etaxonomy.cdm.api.service.IVocabularyService;
16
import eu.etaxonomy.cdm.api.service.pager.Pager;
17
import eu.etaxonomy.cdm.common.CdmUtils;
18
import eu.etaxonomy.cdm.io.common.CdmIoBase;
19
import eu.etaxonomy.cdm.io.common.IoStateBase;
20
import eu.etaxonomy.cdm.model.common.CdmBase;
21
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
22
import eu.etaxonomy.cdm.model.common.Language;
23
import eu.etaxonomy.cdm.model.common.Representation;
24
import eu.etaxonomy.cdm.model.common.TermVocabulary;
25
import eu.etaxonomy.cdm.model.common.UuidAndTitleCache;
26
import eu.etaxonomy.cdm.model.description.CategoricalData;
27
import eu.etaxonomy.cdm.model.description.Feature;
28
import eu.etaxonomy.cdm.model.description.FeatureNode;
29
import eu.etaxonomy.cdm.model.description.FeatureTree;
30
import eu.etaxonomy.cdm.model.description.MeasurementUnit;
31
import eu.etaxonomy.cdm.model.description.QuantitativeData;
32
import eu.etaxonomy.cdm.model.description.State;
33
import eu.etaxonomy.cdm.model.description.StateData;
34
import eu.etaxonomy.cdm.model.description.WorkingSet;
35
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
36
import fr_jussieu_snv_lis.XPApp;
37
import fr_jussieu_snv_lis.Xper;
38
import fr_jussieu_snv_lis.IO.IExternalAdapter;
39
import fr_jussieu_snv_lis.base.Individual;
40
import fr_jussieu_snv_lis.base.Mode;
41
import fr_jussieu_snv_lis.base.Variable;
42
import fr_jussieu_snv_lis.utils.Utils;
43

    
44
@Component
45
public class CdmXperAdapter extends CdmIoBase implements IExternalAdapter{
46
	private static final Logger logger = Logger.getLogger(CdmXperAdapter.class);
47
	
48
	TransactionStatus tx;
49
	
50
	private CdmXperAdapter  adapter = this;
51

    
52
//	private CdmApplicationController cdmApplicationController;
53
	private CdmXperBaseControler baseController;
54
	private UUID uuidWorkingSet;
55
//	private WorkingSet workingSet; 
56
	
57
	//TODO preliminary
58
	//CONFIGURATION
59
	private boolean isLazyModes = false;
60
	private boolean isLazyIndMatrix = true;
61
	private boolean useSecInTaxonName = false;
62
	
63
	public CdmXperAdapter(){
64
		BaseCdm base = new BaseCdm();
65
		CdmXperBaseControler baseController = new CdmXperBaseControler(base, this);
66
		setBaseController(baseController);
67
	}
68
	
69
	public boolean startXper(UUID uuidWorkingSet){
70
		this.uuidWorkingSet = uuidWorkingSet;
71
		Thread t = new Thread() {
72
			public void run() {
73
				new Xper(adapter);
74
			}
75
			
76
		};
77
		System.out.println("xper2 start");
78
		t.start();
79
//		while(!XPApp.xperReady){
80
//			//TODO
81
//		}
82
//		System.out.println("xper2 started :::");
83
		return true;
84
	}
85

    
86
	
87
//************************* GETTER /SETTER **********************/	
88

    
89
	public void setBaseController(CdmXperBaseControler baseController) {
90
		this.baseController = baseController;
91
	}
92

    
93
	/* (non-Javadoc)
94
	 * @see fr_jussieu_snv_lis.IO.IExternalAdapter#getBaseController()
95
	 */
96
	public CdmXperBaseControler getBaseController() {
97
		return baseController;
98
	}
99

    
100
	public WorkingSet getWorkingSet() {
101
//		if (this.workingSet == null){
102
			WorkingSet workingSet = getWorkingSetService().find(uuidWorkingSet);
103
//		}
104
		return workingSet;
105
	}
106
	
107
	public WorkingSet getLanguage() {
108
		
109
//		if (this.workingSet == null){
110
			WorkingSet workingSet = getWorkingSetService().find(uuidWorkingSet);
111
//		}
112
		return workingSet;
113
	}
114
	
115
	
116
	
117
//*********************** METHODS **********************/	
118
	
119
	public void load(){
120
		loadFeatures();
121
		loadTaxa();
122
	}
123

    
124
	// Load the featureTree with the UUID
125
	public void loadFeatures() {
126
		logger.warn("load features start");
127
		TransactionStatus tx = startTransaction();
128
		
129
		FeatureTree featureTree = getWorkingSet().getDescriptiveSystem();
130
		getFeatureTreeService().saveOrUpdate(featureTree);
131
		
132
		if (featureTree != null) {
133
			loadFeatureNode(featureTree.getRoot(), -1);
134
		}else{
135
			logger.warn("No feature tree available");
136
		}
137
		commitTransaction(tx);
138
		logger.warn("load features end :::");
139
	}
140

    
141

    
142
	
143
	/**
144
	 * Recursive methode to load FeatureNode and all its children
145
	 * 
146
	 * @param featureNode
147
	 * @param indiceParent
148
	 */
149
	public void loadFeatureNode(FeatureNode featureNode, int indiceParent){
150
		List<FeatureNode> featureList = featureNode.getChildren();
151
		
152
		adaptFeatureListToVariableList(indiceParent, featureList);
153
	}
154

    
155
	/**
156
	 * @param indiceParent
157
	 * @param featureList
158
	 */
159
	public void adaptFeatureListToVariableList(int indiceParent, List<FeatureNode> featureList) {
160
//		List<Variable> result = new ArrayList<Variable>(featureList.size()); 
161
		for(FeatureNode child : featureList){
162
			boolean alreadyExist = false;
163
			Variable variable = adaptFeatureNodeToVariable(child);
164
			
165
			//?? TODO
166
			List<Variable> vars = XPApp.getCurrentBase().getVariables();
167
			
168
			for(Variable var : vars){
169
				if(var.getName().equals(variable.getName()))
170
					alreadyExist = true;
171
			}
172
			
173
			if(!alreadyExist && (child.getFeature().isSupportsCategoricalData() || child.getFeature().isSupportsQuantitativeData())){
174
				
175
				XPApp.getCurrentBase().addVariable(variable);
176
//				result.add(variable);
177
				
178
				if(child.getFeature().isSupportsCategoricalData()){
179
					// Add states to the feature
180
					if (! isLazyModes){
181
						addModesToVariable(child, variable);
182
					}
183
				}
184
				
185
				if(indiceParent != -1 && XPApp.getCurrentBase().getVariableAt(indiceParent) != null){
186
//				if(indiceParent != -1 && result.get(indiceParent) != null){
187
					variable.addMother((XPApp.getCurrentBase().getVariableAt(indiceParent -1)));
188
//					variable.addMother(result.get(indiceParent -1 ));
189
				}
190
				
191
				adaptFeatureListToVariableList(variable.getIndexInt(), child.getChildren());
192
			}else{
193
				adaptFeatureListToVariableList(indiceParent, child.getChildren());
194
			}
195
		}
196
		return;
197
	}
198

    
199
	/**
200
	 * @param child
201
	 * @param variable
202
	 */
203
	private void addModesToVariable(FeatureNode child, Variable variable) {
204
		Set<TermVocabulary<State>> termVocabularySet = child.getFeature().getSupportedCategoricalEnumerations();
205
		for(TermVocabulary<State> termVocabulary : termVocabularySet){
206
			for(State state : termVocabulary.getTerms()){
207
				Mode mode = adaptStateToMode(state);
208
				variable.addMode(mode);
209
			}
210
		}
211
	}
212

    
213
	/**
214
	 * @param child
215
	 * @return
216
	 */
217
	private Variable adaptFeatureNodeToVariable(FeatureNode child) {
218
		Variable variable = new Variable(child.getFeature().getLabel());
219
		variable.setUuid(child.getFeature().getUuid());
220
		if (child.getFeature().isSupportsQuantitativeData()){
221
			// Specify the character type (numerical)
222
			variable.setType(Utils.numType);
223
		}else if (child.getFeature().isSupportsCategoricalData()){
224
			variable.setType(Utils.catType);
225
		}
226
		return variable;
227
	}
228
	
229
// ******************** STATE - MODE ***********************************/
230
	private Mode adaptStateToMode(State state) {
231
		Mode result =  new Mode(state.getLabel());
232
		result.setUuid(state.getUuid());
233
		return result;	
234
	}
235
	
236

    
237
	public State adaptModeToState(Mode mode) {
238
		State state = State.NewInstance(mode.getDescription(), mode.getName(), null);
239
		mode.setUuid(state.getUuid());
240
		return state;
241
	}
242
	
243
// ******************** TAXON - INDIVIDUAL ***********************************/
244

    
245
	/**
246
	 * @param taxonBase
247
	 * @return
248
	 */
249
	public Individual adaptTaxonToIndividual(TaxonBase taxonBase) {
250
		String name = useSecInTaxonName? taxonBase.getTitleCache() : taxonBase.getName().getTitleCache();
251
		Individual individual = new Individual(name);
252
		individual.setUuid(taxonBase.getUuid());
253
		return individual;
254
	}
255
	
256
// ******************************** ******************************************/	
257
//    // OLD
258
//	// Load all the taxa and 1 description
259
//	public void loadTaxaAndDescription() {
260
//		logger.warn("load taxa start");
261
//		//fill all variables with empty lists
262
//
263
//		
264
//		TransactionStatus tx = startTransaction();
265
//		
266
//		getWorkingSet().getDescriptions();
267
//		
268
//		logger.warn("load taxa from CDM");
269
//		List<TaxonBase> taxonList = getTaxonService().list(Taxon.class , null, null, null, null);
270
//		
271
//		for(TaxonBase taxonBase : taxonList){
272
//			if (XPApp.getCurrentBase() != null) {
273
//				
274
//				// Add a image to the taxon
275
//				BaseObjectResource bor = new BaseObjectResource(new XPResource("http://www.cheloniophilie.com/Images/Photos/Chelonia-mydas/tortue-marine.JPG"));
276
//                individual.addResource(bor); 
277
//                
278
//				// Add an empty description
279
//                
280
//                loadDescription(individual, taxonBase);
281
//                
282
//			}
283
//		}
284
//		commitTransaction(tx);
285
//		logger.warn("load taxa end :::");
286
//	}
287

    
288

    
289
	/**
290
	 * Load taxa and convert to individuals.
291
	 * Loads the 
292
	 *  - uuid
293
	 *  - name
294
	 *  - varModMatrix, 
295
	 *  - varNumValuesMatrix
296
	 *  - varComment (TODO)
297
	 *  - varUnknown (TODO)
298
	 */
299
	public void loadTaxa(){
300
		//categorical data
301
		logger.warn("load categorical data");
302
		Map<UuidAndTitleCache, Map<UUID, Set<CategoricalData>>> categoricalData = getCategoricalData();
303
		handleCategoricalData(categoricalData);
304
		logger.warn("load categorical data :::");
305
		
306
		//quantitative data
307
		logger.warn("load quantitative data");
308
		Map<UuidAndTitleCache, Map<UUID, Set<QuantitativeData>>> quantitativeData = getQuantitativeData();
309
		handleQuantitativeData(quantitativeData);
310
		logger.warn("load quantitative data :::");
311
		
312
		//TODO
313
		//descriptions with no data
314
		
315
		//TODO varComment
316
		
317
		//TODO varUnknown
318
		
319
		//TODO Resources
320
		
321
//		TODO private String index;
322
//		TODO private String description;
323

    
324
		
325
		
326
	}
327

    
328
	/**
329
	 * @return
330
	 */
331
	private Map<UuidAndTitleCache, Map<UUID, Set<CategoricalData>>> getCategoricalData() {
332
		Map<UuidAndTitleCache, Map<UUID, Set<CategoricalData>>> data = getWorkingSetService().getTaxonFeatureDescriptionElementMap(
333
				CategoricalData.class, uuidWorkingSet, null, null, null, null);
334
		return data;
335
	}
336

    
337
	private Map<UuidAndTitleCache, Map<UUID, Set<QuantitativeData>>> getQuantitativeData() {
338
		Map<UuidAndTitleCache, Map<UUID, Set<QuantitativeData>>> data = getWorkingSetService().getTaxonFeatureDescriptionElementMap(
339
				QuantitativeData.class, uuidWorkingSet, null, null, null, null);
340
		return data;
341
	}
342

    
343

    
344

    
345
	private void handleCategoricalData(Map<UuidAndTitleCache, Map<UUID, Set<CategoricalData>>> categoricalData) {
346
		for (UuidAndTitleCache taxon : categoricalData.keySet()){
347
			Map<UUID, Set<CategoricalData>> variableMap = categoricalData.get(taxon);
348
			Individual individual = getIndividualByUuidAndTitleCache(taxon);
349
			
350
			handleCategoricalData(variableMap, individual);
351
		}
352
	}
353
	
354
	private void handleQuantitativeData(Map<UuidAndTitleCache, Map<UUID, Set<QuantitativeData>>> quantitativeData) {
355
		for (UuidAndTitleCache taxon : quantitativeData.keySet()){
356
			Map<UUID, Set<QuantitativeData>> variableMap = quantitativeData.get(taxon);
357
			Individual individual = getIndividualByUuidAndTitleCache(taxon);
358
			handleQuantitativeData(variableMap, individual);
359
		}
360
	}
361

    
362

    
363
	private void handleCategoricalData(Map<UUID, Set<CategoricalData>> variableMap, Individual individual) {
364
		for (UUID featureUuid : variableMap.keySet()){
365
			Variable variable = baseController.findVariableByUuid(featureUuid);
366
			if (variable != null){
367
				for (CategoricalData categorical : variableMap.get(featureUuid)) {
368
					// create a list of xper Mode corresponding
369
					List<Mode> modesList = variable.getModes();
370
					List<StateData> stateDataList = categorical.getStates();
371
					for (StateData state : stateDataList) {
372
						for (Mode mode : modesList) {
373
							if (state.getState().getUuid().equals(mode.getUuid())) {
374
								// Add state to the Description
375
								individual.addModeMatrix(variable, mode);
376
							}
377
						}
378
					}
379
				}
380
			}else{
381
				logger.warn("Variable not found for uuid " +  featureUuid.toString());
382
			}
383
		}
384
	}
385
	
386
	
387
	private void handleQuantitativeData(Map<UUID, Set<QuantitativeData>> variableMap, Individual individual) {
388
		for (UUID featureUuid : variableMap.keySet()){
389
			Variable variable = baseController.findVariableByUuid(featureUuid);
390
			if (variable != null){
391
				for (QuantitativeData qdCDM : variableMap.get(featureUuid)){
392
					fr_jussieu_snv_lis.base.QuantitativeData qdXper = adaptQdCdm2QdXper(qdCDM);
393
					individual.addNumMatrix(variable, qdXper);
394
				}
395
			}else{
396
				logger.warn("Variable not found for uuid " +  featureUuid.toString());
397
			}
398
		}
399
	}
400

    
401
	/**
402
	 * @param qdCDM
403
	 * @return
404
	 */
405
	private fr_jussieu_snv_lis.base.QuantitativeData adaptQdCdm2QdXper(
406
			QuantitativeData qdCDM) {
407
		fr_jussieu_snv_lis.base.QuantitativeData qdXper = new fr_jussieu_snv_lis.base.QuantitativeData();
408
		
409
		if (qdCDM.getMax() != null){
410
			qdXper.setMax(new Double(qdCDM.getMax()));
411
		}
412
		if (qdCDM.getMin() != null){
413
			qdXper.setMin(new Double(qdCDM.getMin()));
414
		}
415
		if (qdCDM.getTypicalLowerBoundary() != null){
416
			qdXper.setUmethLower(new Double(qdCDM
417
					.getTypicalLowerBoundary()));
418
		}
419
		if (qdCDM.getTypicalUpperBoundary() != null){
420
			qdXper.setUmethUpper(new Double(qdCDM
421
					.getTypicalUpperBoundary()));
422
		}
423
		if (qdCDM.getAverage() != null){
424
			qdXper.setMean(new Double(qdCDM.getAverage()));
425
		}
426
		if (qdCDM.getStandardDeviation() != null){
427
			qdXper.setSd(new Double(qdCDM.getStandardDeviation()));
428
		}
429
		if (qdCDM.getSampleSize() != null){
430
			qdXper.setNSample(new Integer(Math.round(qdCDM.getSampleSize())));
431
		}
432
		return qdXper;
433
	}
434
	
435
	
436
	private Individual getIndividualByUuidAndTitleCache(UuidAndTitleCache taxon) {
437
		Individual result = this.getBaseController().findIndividualByName(taxon.getTitleCache());
438
		if (result == null){
439
			result= new Individual(taxon.getTitleCache());
440
			result.setUuid(taxon.getUuid());
441
			this.getBaseController().addIndividual(result);
442
		}
443
		return result;
444
	}
445

    
446

    
447
//	// Create a workingSet if not exist
448
//	public void createWorkingSet(){
449
//		
450
//		if(getWorkingSetService().list(WorkingSet.class, null, null, null, null).size() <= 0){
451
//			WorkingSet ws = WorkingSet.NewInstance();
452
//			
453
//			UUID featureTreeUUID = UUID.fromString("47eda782-89c7-4c69-9295-e4052ebe16c6");
454
//			List<String> featureTreeInit = Arrays.asList(new String[]{"root.children.feature.representations"});
455
//			
456
//			FeatureTree featureTree = getFeatureTreeService().load(featureTreeUUID, featureTreeInit);
457
//			ws.setDescriptiveSystem(featureTree);
458
//			
459
//			List<TaxonBase> taxonList = getTaxonService().list(Taxon.class , null, null, null, null);
460
//			for(TaxonBase taxonBase : taxonList){
461
//				Pager<TaxonDescription> taxonDescriptionPager = getDescriptionService().getTaxonDescriptions((Taxon)taxonBase, null, null, null, 0, Arrays.asList(new String[]{"elements.states", "elements.feature"} ));
462
//				List<TaxonDescription> taxonDescriptionList = taxonDescriptionPager.getRecords();
463
//				TaxonDescription taxonDescription = taxonDescriptionList.get(0);
464
//				ws.addDescription(taxonDescription);
465
//				System.out.println(taxonDescription.getUuid());
466
//			}
467
//			
468
//			getWorkingSetService().save(ws);
469
//		}
470
//	}
471

    
472
// ************************************ SAVE *************************************/	
473
	
474
	@Override
475
	public void save() {
476
		List<Variable> vars = XPApp.getCurrentBase().getVariables();
477
		saveFeatureTree(vars);
478
		saveFeatures(vars);
479
	}
480

    
481

    
482
	private void saveFeatureTree(List<Variable> vars) {
483
		logger.warn("Save feature tree  not yet implemented");
484
	}
485

    
486
	/**
487
	 * @param vars
488
	 */
489
	private void saveFeatures(List<Variable> vars) {
490
		tx = startTransaction();
491
		for (Variable variable : vars){
492
			Feature feature = getFeature(variable);
493
			if (Utils.numType.equals(variable.getType())){
494
				saveNumericalFeature(variable, feature);
495
			}else if (Utils.catType.equals(variable.getType())){
496
				saveCategoricalFeature(variable, feature);
497
			}else{
498
				logger.warn("variable type undefined");
499
			}
500
		}
501
		commitTransaction(tx);
502
	}
503

    
504

    
505
	/**
506
	 * @param variable
507
	 * @return
508
	 */
509
	public Feature getFeature(Variable variable) {
510
		UUID uuid = variable.getUuid();
511
		ITermService termService = getTermService();
512
		DefinedTermBase<?> term = termService.find(uuid);
513
		Feature feature = CdmBase.deproxy(term, Feature.class);
514
		return feature;
515
	}
516

    
517
	private void saveCategoricalFeature(Variable variable, Feature feature) {
518
		ITermService termService = getTermService();
519
		IVocabularyService vocService = getVocabularyService();
520
		if (feature == null){
521
			saveNewFeature(variable, termService, vocService);
522
		}else{
523
			if (isChanged(feature, variable)){
524
				feature.setLabel(variable.getName());
525
				termService.save(feature);
526
			}else{
527
				logger.info("No change for variable: " + variable.getName());
528
			}
529
			
530
			HashMap<UUID, State> allStates = getAllSupportedStates(feature);
531
			for (Mode mode : variable.getModes()){
532
				State state = allStates.get(mode.getUuid());
533
				if (state == null){
534
					saveNewState(mode, feature);
535
				}else{
536
					allStates.remove(state.getUuid());
537
					if (modeHasChanged(mode, state)){
538
						String stateDescription = null;
539
						String stateLabel = mode.getName();
540
						String stateAbbrev = null;
541
						Language lang = Language.DEFAULT();
542
						Representation rep = state.getRepresentation(lang);
543
						rep.setLabel(stateLabel);
544
						termService.saveOrUpdate(state);
545
//						State state = State.NewInstance(stateDescription, stateLabel, stateAbbrev);
546
//						termService.save(state);
547
//						voc.addTerm(state);
548
//						vocService.save(voc);
549
					}
550
				}
551
			}
552
			for (State state : allStates.values()){
553
				logger.warn("There is a state to delete: " + feature.getLabel() + "-" + state.getLabel());
554
				for (TermVocabulary<State> voc :feature.getSupportedCategoricalEnumerations()){
555
					voc.removeTerm(state);
556
				}
557
			}
558
		}
559
	}
560

    
561

    
562
	private boolean modeHasChanged(Mode mode, State state) {
563
		if (CdmUtils.nullSafeEqual(mode.getName(), state.getLabel())){
564
			return false;
565
		}else{
566
			return true;
567
		}
568
	}
569

    
570

    
571
	public void saveNewState(Mode mode, Feature feature) {
572
		TransactionStatus ta = startTransaction();
573
		ITermService termService = getTermService();
574
		IVocabularyService vocService = getVocabularyService();
575
		
576
		termService.saveOrUpdate(feature);
577
		int numberOfVocs = feature.getSupportedCategoricalEnumerations().size();
578
		
579
		TermVocabulary<State> voc;
580
		if (numberOfVocs <= 0){
581
			//new voc
582
			String vocLabel = "Vocabulary for feature " + feature.getLabel();
583
			String vocDescription = vocLabel + ". Automatically created by Xper.";
584
			String vocAbbrev = null;
585
			String termSourceUri = null;
586
			voc = TermVocabulary.NewInstance(vocDescription, vocLabel, vocAbbrev, termSourceUri);
587
		}else if (numberOfVocs == 1){
588
			voc = feature.getSupportedCategoricalEnumerations().iterator().next();
589
		}else{
590
			//numberOfVocs > 1
591
			//FIXME preliminary
592
			logger.warn("Multiple supported vocabularies not yet correctly implemented");
593
			voc = feature.getSupportedCategoricalEnumerations().iterator().next();
594
		}
595
		saveNewModeToVoc(termService, vocService, voc, mode);
596
		commitTransaction(ta);
597
	}
598
	
599

    
600
	/**
601
	 * @param variable
602
	 * @param termService
603
	 * @param vocService
604
	 */
605
	private void saveNewFeature(Variable variable, ITermService termService,
606
			IVocabularyService vocService) {
607
		Feature feature;
608
		//new feature
609
		String description = null;
610
		String label = variable.getName();
611
		String labelAbbrev = null;
612
		feature = Feature.NewInstance(description, label, labelAbbrev);
613
		variable.setUuid(feature.getUuid());
614
		termService.save(feature);
615
		//new voc
616
		String vocDescription = null;
617
		String vocLabel = "Vocabulary for feature " + label;
618
		String vocAbbrev = null;
619
		String termSourceUri = null;
620
		TermVocabulary<State> voc = TermVocabulary.NewInstance(vocDescription, vocLabel, vocAbbrev, termSourceUri);
621
		for (Mode mode:variable.getModes()){
622
			saveNewModeToVoc(termService, vocService, voc, mode);
623
		}
624
		feature.addSupportedCategoricalEnumeration(voc);
625
		termService.saveOrUpdate(feature);
626
	}
627

    
628

    
629
	/**
630
	 * @param termService
631
	 * @param vocService
632
	 * @param voc
633
	 * @param mode
634
	 */
635
	private void saveNewModeToVoc(ITermService termService, IVocabularyService vocService, TermVocabulary<State> voc, Mode mode) {
636
		State state = adaptModeToState(mode);
637
		termService.save(state);
638
		voc.addTerm(state);
639
		vocService.saveOrUpdate(voc);
640
	}
641

    
642

    
643

    
644
	private HashMap<UUID, State> getAllSupportedStates(Feature feature) {
645
		HashMap<UUID, State> result = new HashMap<UUID,State>();
646
		Set<TermVocabulary<State>> vocs = feature.getSupportedCategoricalEnumerations();
647
		for (TermVocabulary<State> voc : vocs){
648
			for (State state : voc.getTerms()){
649
				result.put(state.getUuid(), state);
650
			}
651
		}
652
		return result;
653
	}
654

    
655

    
656
	private boolean isChanged(Feature feature, Variable variable) {
657
		//preliminary
658
		return ! variable.getName().equals(feature.getLabel());
659
	}
660

    
661

    
662

    
663
	private void saveNumericalFeature(Variable variable, Feature feature) {
664
//		IVocabularyService vocService = getVocabularyService();
665
		String variableUnit = variable.getUnit();
666
		Set<MeasurementUnit> units = feature.getRecommendedMeasurementUnits();
667
		//preliminary
668
		if (StringUtils.isBlank(variableUnit) ){
669
			//unit is empty
670
			if (!units.isEmpty()){
671
				feature.getRecommendedMeasurementUnits().clear();
672
			}
673
		}else{
674
			// unit is not empty
675
			boolean unitExists = false;
676
			for (MeasurementUnit measurementUnit: units){
677
				//TODO ??
678
				String labelOfUnit = measurementUnit.getLabel();
679
				if (variableUnit.equals(labelOfUnit)){
680
					unitExists = true;
681
					break;
682
				}
683
			}
684
			if (! unitExists){
685
				units.clear();
686
				MeasurementUnit existingUnit = findExistingUnit(variableUnit);
687
				if (existingUnit == null){
688
					String unitDescription = null;
689
					String unitLabel = variableUnit;
690
					String labelAbbrev = null;
691
					MeasurementUnit newUnit = MeasurementUnit.NewInstance(unitDescription, unitLabel, labelAbbrev);
692
					getTermService().save(newUnit);
693
					UUID defaultMeasurmentUnitVocabularyUuid = UUID.fromString("3b82c375-66bb-4636-be74-dc9cd087292a");
694
					TermVocabulary voc = getVocabularyService().find(defaultMeasurmentUnitVocabularyUuid);
695
					if (voc == null){
696
						logger.warn("Could not find MeasurementService vocabulary");
697
					}else{
698
						voc.addTerm(newUnit);
699
						getVocabularyService().saveOrUpdate(voc);
700
					}
701
					existingUnit = newUnit;
702
				}
703
				feature.addRecommendedMeasurementUnit(existingUnit);
704
			}
705
		}
706
	}
707

    
708

    
709
	private MeasurementUnit findExistingUnit(String variableUnit) {
710
		Pager<MeasurementUnit> existingUnits = getTermService().findByRepresentationText(variableUnit, MeasurementUnit.class, null, null);
711
		for (MeasurementUnit exUnit : existingUnits.getRecords()){
712
			if (variableUnit.equals(exUnit.getLabel())){
713
				return exUnit;
714
			}
715
		}
716
		return null;
717
	}
718

    
719

    
720
// ************************** Override ********************************/	
721
	
722
	@Override
723
	protected boolean doInvoke(IoStateBase state) {
724
		//not needed
725
		return false;
726
	}
727

    
728
	@Override
729
	protected boolean doCheck(IoStateBase state) {
730
		//not needed
731
		return false;
732
	}
733

    
734
	@Override
735
	protected boolean isIgnore(IoStateBase state) {
736
		//not needed
737
		return false;
738
	}
739

    
740
	@Override
741
	public String toString() {
742
		String ws = uuidWorkingSet == null ?"-" : uuidWorkingSet.toString();
743
		return "CdmXperAdapter (" + ws + ")";
744
	}
745
	
746
	
747
	
748

    
749
}
(2-2/3)