1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package p3j.misc;
17
18 import james.SimSystem;
19 import james.core.util.misc.Strings;
20
21 import java.beans.XMLDecoder;
22 import java.beans.XMLEncoder;
23 import java.io.BufferedInputStream;
24 import java.io.BufferedOutputStream;
25 import java.io.FileInputStream;
26 import java.io.FileOutputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.ObjectInputStream;
30 import java.io.ObjectOutputStream;
31 import java.io.OutputStream;
32 import java.util.ArrayList;
33 import java.util.Collections;
34 import java.util.Comparator;
35 import java.util.HashMap;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Map.Entry;
39 import java.util.logging.Level;
40 import java.util.zip.GZIPInputStream;
41 import java.util.zip.GZIPOutputStream;
42
43 import p3j.database.IP3MDatabase;
44 import p3j.gui.P3J;
45 import p3j.gui.dialogs.ShowWarningAfterProjectionLoadingDialog;
46 import p3j.gui.dialogs.execstatus.SimpleProgressDialog;
47 import p3j.misc.gui.GUI;
48 import p3j.pppm.ProjectionModel;
49 import p3j.pppm.parameters.Parameter;
50 import p3j.pppm.parameters.ParameterAssignment;
51 import p3j.pppm.parameters.ParameterAssignmentSet;
52 import p3j.pppm.parameters.ParameterInstance;
53 import p3j.pppm.sets.Set;
54 import p3j.pppm.sets.SetType;
55
56
57
58
59
60
61
62
63
64
65
66
67 public class Serializer {
68
69
70
71
72
73 private boolean usingXML = true;
74
75
76
77
78 private boolean usingCompression = false;
79
80
81
82
83
84
85
86
87
88
89
90
91 public Object load(String file) throws IOException, ClassNotFoundException {
92 if (usingXML) {
93 return loadFromXML(file);
94 }
95 return loadFromBinary(file);
96 }
97
98
99
100
101
102
103
104
105
106
107
108
109 public Object loadFromBinary(String file) throws IOException,
110 ClassNotFoundException {
111 ObjectInputStream input = new ObjectInputStream(getInputStream(file));
112 Object o = input.readObject();
113 input.close();
114 return o;
115 }
116
117
118
119
120
121
122
123
124
125
126 public Object loadFromXML(String file) throws IOException {
127 XMLDecoder xmlDecoder = new XMLDecoder(getInputStream(file));
128 Object object = xmlDecoder.readObject();
129 xmlDecoder.close();
130 return object;
131 }
132
133
134
135
136
137
138
139
140
141
142 protected InputStream getInputStream(String file) throws IOException {
143 InputStream in = new BufferedInputStream(new FileInputStream(file));
144 if (isUsingCompression()) {
145 in = new GZIPInputStream(in);
146 }
147 return in;
148 }
149
150
151
152
153
154
155
156
157
158
159 protected OutputStream getOutputStream(String file) throws IOException {
160 OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
161 if (isUsingCompression()) {
162 out = new GZIPOutputStream(out);
163 }
164 return out;
165 }
166
167
168
169
170
171
172
173
174
175
176
177 public void save(ProjectionModel pm, String file) throws IOException {
178 ProjectionModel modelToSave = copyProjection(pm);
179 if (usingXML) {
180 saveToXML(modelToSave, file);
181 } else {
182 saveToBinary(modelToSave, file);
183 }
184 }
185
186
187
188
189
190
191
192
193
194
195
196 public void saveToBinary(Object object, String file) throws IOException {
197 ObjectOutputStream output = new ObjectOutputStream(getOutputStream(file));
198 output.writeObject(object);
199 output.close();
200 }
201
202
203
204
205
206
207
208
209
210
211
212 public void saveToXML(Object object, String file) throws IOException {
213 XMLEncoder xmlEncoder = new XMLEncoder(getOutputStream(file));
214 xmlEncoder.writeObject(object);
215 xmlEncoder.close();
216 }
217
218 public boolean isUsingXML() {
219 return usingXML;
220 }
221
222 public void setUsingXML(boolean usingXML) {
223 this.usingXML = usingXML;
224 }
225
226 public boolean isUsingCompression() {
227 return usingCompression;
228 }
229
230 public void setUsingCompression(boolean usingCompression) {
231 this.usingCompression = usingCompression;
232 }
233
234
235
236
237
238
239
240
241
242
243
244 private ProjectionModel copyProjection(ProjectionModel original) {
245 ProjectionModel copy = new ProjectionModel();
246
247 IProgressObserver progress = SimpleProgressDialog.showDialog(
248 P3J.getInstance(), "Saving projection '" + original.getName() + "'",
249 "", 6, false);
250 progress.incrementProgress("General properties...");
251 copySimpleFields(original, copy);
252 progress.incrementProgress("Parameter instances...");
253 Map<ParameterInstance, ParameterInstance> paramInstances = copyParameterInstances(
254 original, copy);
255 progress.incrementProgress("Sets...");
256 Map<Set, Set> sets = copySets(original, copy, paramInstances);
257 progress.incrementProgress("Set Types...");
258 Map<SetType, SetType> setTypes = copySetTypes(original, copy,
259 paramInstances, sets);
260 progress.incrementProgress("Set Type Mapping...");
261 copyParamInstToSetTypeMapping(original, copy, paramInstances, setTypes);
262 progress.incrementProgress("Done");
263 progress.taskFinished();
264 return copy;
265 }
266
267
268
269
270
271
272
273
274
275 private void copySimpleFields(ProjectionModel original, ProjectionModel copy) {
276 copy.setName(original.getName());
277 copy.setDescription(original.getDescription());
278 copy.setJumpOffYear(original.getJumpOffYear());
279 copy.setMaximumAge(original.getMaximumAge());
280 copy.setYears(original.getYears());
281 copy.setGenerations(original.getGenerations());
282 }
283
284
285
286
287
288
289
290
291
292
293
294
295
296 private Map<ParameterInstance, ParameterInstance> copyParameterInstances(
297 ProjectionModel original, ProjectionModel copy) {
298 Map<ParameterInstance, ParameterInstance> paramInstances = new HashMap<>();
299 List<ParameterInstance> listOfNewParamInstances = new ArrayList<>();
300 for (ParameterInstance paramInstance : original.getAllParameterInstances()) {
301 ParameterInstance piCopy = copyParameterInstance(paramInstance);
302 paramInstances.put(paramInstance, piCopy);
303 listOfNewParamInstances.add(piCopy);
304 }
305 copy.setAllParameterInstances(listOfNewParamInstances);
306 return paramInstances;
307 }
308
309
310
311
312
313
314
315
316
317
318
319
320
321 private Map<Set, Set> copySets(ProjectionModel original,
322 ProjectionModel copy,
323 Map<ParameterInstance, ParameterInstance> paramInstances) {
324 Map<Set, Set> sets = new HashMap<>();
325 Set newDefaultSet = copySet(original.getDefaultSet(), paramInstances);
326 copy.setDefaultSet(newDefaultSet);
327 sets.put(original.getDefaultSet(), newDefaultSet);
328 for (SetType setType : original.getAllSetTypes())
329 for (Set set : setType.getSets()) {
330 Set setCopy = copySet(set, paramInstances);
331 sets.put(set, setCopy);
332 }
333 return sets;
334 }
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352 private Map<SetType, SetType> copySetTypes(ProjectionModel original,
353 ProjectionModel copy,
354 Map<ParameterInstance, ParameterInstance> paramInstances,
355 Map<Set, Set> sets) {
356 Map<SetType, SetType> setTypes = new HashMap<>();
357 SetType newDefaultSetType = copySetType(original.getDefaultSetType(),
358 paramInstances, sets);
359 copy.setDefaultType(newDefaultSetType);
360 setTypes.put(original.getDefaultSetType(), newDefaultSetType);
361 List<SetType> listOfNewUserDefSetTypes = new ArrayList<>();
362 for (SetType setType : original.getUserDefinedTypes()) {
363 SetType stCopy = copySetType(setType, paramInstances, sets);
364 setTypes.put(setType, stCopy);
365 listOfNewUserDefSetTypes.add(stCopy);
366 }
367 copy.setUserDefinedTypes(listOfNewUserDefSetTypes);
368 return setTypes;
369 }
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384 private void copyParamInstToSetTypeMapping(ProjectionModel original,
385 ProjectionModel copy,
386 Map<ParameterInstance, ParameterInstance> paramInstances,
387 Map<SetType, SetType> setTypes) {
388 Map<ParameterInstance, SetType> newInstanceSetTypesMap = new HashMap<>();
389 for (Entry<ParameterInstance, SetType> instSetTypeEntry : original
390 .getInstanceSetTypes().entrySet()) {
391 newInstanceSetTypesMap.put(paramInstances.get(instSetTypeEntry.getKey()),
392 setTypes.get(instSetTypeEntry.getValue()));
393 }
394 copy.setInstanceSetTypes(newInstanceSetTypesMap);
395 }
396
397
398
399
400
401
402
403
404 private ParameterInstance copyParameterInstance(
405 ParameterInstance paramInstance) {
406 Parameter param = paramInstance.getParameter();
407 return new ParameterInstance(paramInstance.getComparisonIndex(),
408 new Parameter(param.getID(), param.isGenerationDependent(),
409 param.getName(), param.getValueHeight(), param.getValueWidth(),
410 param.getPopulation()), paramInstance.getGeneration());
411 }
412
413
414
415
416
417
418
419
420
421
422 private Set copySet(Set set,
423 Map<ParameterInstance, ParameterInstance> paramInstances) {
424 Set copy = new Set();
425 copy.setName(set.getName());
426 copy.setDescription(set.getDescription());
427 copy.setProbability(set.getProbability());
428
429 Map<ParameterInstance, ParameterAssignmentSet> copyOfSetData = new HashMap<>();
430 for (Entry<ParameterInstance, ParameterAssignmentSet> setDataEntry : set
431 .getSetData().entrySet()) {
432 copyOfSetData.put(paramInstances.get(setDataEntry.getKey()),
433 copyParamAssignmentSet(setDataEntry.getValue(), paramInstances));
434 }
435
436 copy.setSetData(copyOfSetData);
437 return copy;
438 }
439
440
441
442
443
444
445
446
447
448
449 private ParameterAssignmentSet copyParamAssignmentSet(
450 ParameterAssignmentSet paramAssignmentSet,
451 Map<ParameterInstance, ParameterInstance> paramInstances) {
452 ParameterAssignmentSet copy = new ParameterAssignmentSet();
453 for (ParameterAssignment assignment : paramAssignmentSet.getAssignments()) {
454 copy.add(new ParameterAssignment(paramInstances.get(assignment
455 .getParamInstance()), assignment.getName(), assignment
456 .getDescription(), assignment.getProbability(), assignment
457 .getDeviation(), assignment.getMatrix().copy()));
458 }
459 return copy;
460 }
461
462
463
464
465
466
467
468
469
470
471
472
473 private SetType copySetType(SetType setType,
474 Map<ParameterInstance, ParameterInstance> paramInstances,
475 Map<Set, Set> sets) {
476 SetType copy = new SetType(setType.getName(), setType.getDescription());
477
478 List<ParameterInstance> copyDefinedParameters = new ArrayList<>();
479 for (ParameterInstance paramInstance : setType.getDefinedParameters())
480 copyDefinedParameters.add(paramInstances.get(paramInstance));
481 List<Set> copySets = new ArrayList<>();
482 for (Set set : setType.getSets())
483 copySets.add(sets.get(set));
484
485 copy.setDefinedParameters(copyDefinedParameters);
486 copy.setSets(copySets);
487
488 return copy;
489 }
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507 public ProjectionModel loadProjection(String absolutePath,
508 IP3MDatabase database) throws ClassNotFoundException, IOException,
509 LoadedProjectionFormatException {
510 ProjectionModel newProjection = new ProjectionModel();
511
512 try {
513 List<String> warnings = new ArrayList<>();
514 ProjectionModel loadedProjection = (ProjectionModel) load(absolutePath);
515
516 copySimpleFields(loadedProjection, newProjection);
517 database.newProjection(newProjection);
518
519 Map<ParameterInstance, ParameterInstance> paramInstances = matchParameterInstances(
520 loadedProjection, newProjection, warnings);
521 Map<SetType, SetType> setTypes = saveSetTypes(loadedProjection,
522 newProjection, paramInstances);
523 database.saveProjection(newProjection);
524 saveSets(loadedProjection, newProjection, paramInstances, setTypes,
525 database);
526
527 database.saveProjection(newProjection);
528
529 if (!warnings.isEmpty())
530 new ShowWarningAfterProjectionLoadingDialog(P3J.getInstance(), warnings)
531 .setVisible(true);
532 } catch (Exception ex) {
533 GUI.printErrorMessage("Loading the projection failed", ex);
534 }
535
536 return newProjection;
537 }
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552 private Map<ParameterInstance, ParameterInstance> matchParameterInstances(
553 ProjectionModel loadedProjection, ProjectionModel newProjection,
554 List<String> warnings) throws LoadedProjectionFormatException {
555
556 Map<ParameterInstance, ParameterInstance> matching = new HashMap<>();
557 List<ParameterInstance> oldInstances = new ArrayList<>(
558 loadedProjection.getAllParameterInstances());
559
560 for (final ParameterInstance newInstance : newProjection
561 .getAllParameterInstances()) {
562
563 List<ParameterInstance> matchCandidates = new ArrayList<>();
564
565 for (ParameterInstance oldInstance : oldInstances)
566 if (newInstance.getComparisonIndex() == oldInstance
567 .getComparisonIndex()
568 && newInstance.getGeneration() == oldInstance.getGeneration()
569 && newInstance.getValueHeight() == oldInstance.getValueHeight()
570 && newInstance.getValueWidth() == oldInstance.getValueWidth()
571 && newInstance.getParameter().getPopulation() == oldInstance
572 .getParameter().getPopulation()
573 && newInstance.getParameter().isGenerationDependent() == oldInstance
574 .getParameter().isGenerationDependent()) {
575 matchCandidates.add(oldInstance);
576 }
577
578 if (matchCandidates.isEmpty())
579 throw new LoadedProjectionFormatException(
580 "No match found for parameter instance " + newInstance);
581
582 oldInstances.remove(matchParameterInstances(matching, newInstance,
583 matchCandidates, warnings));
584 }
585
586 return matching;
587 }
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604 private ParameterInstance matchParameterInstances(
605 Map<ParameterInstance, ParameterInstance> matching,
606 final ParameterInstance targetInstance,
607 List<ParameterInstance> matchCandidates, List<String> warnings) {
608
609 ParameterInstance bestMatch = Collections.min(matchCandidates,
610 new Comparator<ParameterInstance>() {
611 final String targetName = targetInstance.getParameter().getName();
612
613 @Override
614 public int compare(ParameterInstance inst1, ParameterInstance inst2) {
615 return Integer.compare(Strings.getLevenshteinDistance(inst1
616 .getParameter().getName(), targetName), Strings
617 .getLevenshteinDistance(inst2.getParameter().getName(),
618 targetName));
619 }
620 });
621
622 matching.put(bestMatch, targetInstance);
623 SimSystem.report(Level.INFO, "Matched '" + bestMatch + "' to '"
624 + targetInstance + "'.");
625 if (!bestMatch.getParameter().getName()
626 .equals(targetInstance.getParameter().getName()))
627 warnings.add("Could not find perfect match for parameter '"
628 + targetInstance.getParameter() + "', using best match '"
629 + bestMatch.getParameter());
630
631 return bestMatch;
632 }
633
634
635
636
637
638
639
640
641
642
643
644
645 private Map<SetType, SetType> saveSetTypes(ProjectionModel loadedProjection,
646 ProjectionModel newProjection,
647 Map<ParameterInstance, ParameterInstance> paramInstances) {
648
649 Map<SetType, SetType> setTypes = new HashMap<>();
650
651 setTypes.put(loadedProjection.getDefaultSetType(),
652 newProjection.getDefaultSetType());
653
654 for (SetType loadedSetType : loadedProjection.getUserDefinedTypes()) {
655 SetType newSetType = newProjection.createSetType(loadedSetType.getName(),
656 loadedSetType.getDescription());
657 setTypes.put(loadedSetType, newSetType);
658 for (ParameterInstance paramInst : loadedSetType.getDefinedParameters())
659 newProjection.assignParameterInstance(paramInstances.get(paramInst),
660 newSetType, false);
661 }
662
663 return setTypes;
664 }
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680 private void saveSets(ProjectionModel loadedProjection,
681 ProjectionModel newProjection,
682 Map<ParameterInstance, ParameterInstance> paramInstances,
683 Map<SetType, SetType> setTypes, IP3MDatabase database) {
684
685 int numAssignments = loadedProjection.countNumberOfParameterAssignments();
686 IProgressObserver progress = SimpleProgressDialog.showDialog(
687 P3J.getInstance(), "Loading projection '" + loadedProjection.getName()
688 + "'", "Loading " + numAssignments + " parameter assignments:",
689 numAssignments, false);
690
691 for (SetType loadedSetType : loadedProjection.getAllSetTypes()) {
692 SetType newSetType = setTypes.get(loadedSetType);
693 for (Set loadedSet : loadedSetType.getSets()) {
694 Set newSet = loadedSet != loadedProjection.getDefaultSet() ? newSetType
695 .createSet(loadedSet.getName(), loadedSet.getDescription(),
696 loadedSet.getProbability()) : newProjection.getDefaultSet();
697 saveSet(loadedSet, newSet, loadedSetType, paramInstances, database,
698 progress);
699 }
700 }
701 progress.taskFinished();
702 }
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720 private void saveSet(Set loadedSet, Set newSet, SetType loadedSetType,
721 Map<ParameterInstance, ParameterInstance> paramInstances,
722 IP3MDatabase database, IProgressObserver progress) {
723 for (ParameterInstance paramInst : loadedSetType.getDefinedParameters()) {
724 ParameterAssignmentSet paramAssignSet = loadedSet
725 .getParameterAssignments(paramInst);
726 for (ParameterAssignment paramAssign : paramAssignSet.getAssignments()) {
727 ParameterAssignment newParamAssign = database.newParameterAssignment(
728 paramInstances.get(paramInst), paramAssign.getName(),
729 paramAssign.getDescription(), paramAssign.getProbability(),
730 paramAssign.getDeviation(), paramAssign.getMatrixValue());
731 newSet.addParameterAssignment(newParamAssign);
732 progress.incrementProgress("Assignment '" + newParamAssign.getName()
733 + "'");
734 }
735 }
736 }
737
738 }