View Javadoc

1   /*
2    * Copyright 2006 - 2012 Christina Bohk and Roland Ewald
3    *  
4    * Licensed under the Apache License, Version 2.0 (the "License"); 
5    * you may not use this file except in compliance with the License. 
6    * You may obtain a copy of the License at 
7    *  
8    *  http://www.apache.org/licenses/LICENSE-2.0
9    *  
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13   * See the License for the specific language governing permissions and 
14   * limitations under the License. 
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   * Class that stores and loads serializable classes. Needed to store and load
59   * parameter files.
60   * 
61   * Created on February 12, 2007
62   * 
63   * @author Christina Bohk
64   * @author Roland Ewald
65   * 
66   */
67  public class Serializer {
68  
69    /**
70     * Flag that indicates whether objects should be stored in XML or in binary
71     * encoding.
72     */
73    private boolean usingXML = true;
74  
75    /**
76     * Flag that indicates whether GZIP compression (LZW) is used.
77     */
78    private boolean usingCompression = false;
79  
80    /**
81     * Loads object from file.
82     * 
83     * @param file
84     *          path to file with the object to be loaded
85     * @return object the object that has been loaded
86     * @throws IOException
87     *           if file was not found, file input failed, etc.
88     * @throws ClassNotFoundException
89     *           if class of persistent object could not be found
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     * Load object from a binary file.
100    * 
101    * @param file
102    *          path and file name
103    * @return deserialised object
104    * @throws IOException
105    *           if file was not found, etc.
106    * @throws ClassNotFoundException
107    *           if class of persistent object could not be found
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    * Load object from XML file.
119    * 
120    * @param file
121    *          path and file name
122    * @return deserialised object
123    * @throws IOException
124    *           if file was not found, a read error occurred, etc.
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    * Create an input stream.
135    * 
136    * @param file
137    *          source file
138    * @return input stream from file
139    * @throws IOException
140    *           if stream creation fails
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    * Create an output stream.
152    * 
153    * @param file
154    *          target file
155    * @return output stream to file
156    * @throws IOException
157    *           if stream creation fails
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    * Save object to file.
169    * 
170    * @param object
171    *          the object to be saved in the file
172    * @param file
173    *          the file
174    * @throws IOException
175    *           if outputting went wrong
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    * Save object to binary file.
188    * 
189    * @param object
190    *          the object to be written
191    * @param file
192    *          the target file
193    * @throws IOException
194    *           if writing fails
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    * Save object to XML file.
204    * 
205    * @param object
206    *          the object to be written
207    * @param file
208    *          the target file
209    * @throws IOException
210    *           if writing fails
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    * Creates a full, deep copy of this projection model. This is necessary for
236    * serialization, because hibernate is used with lazy evaluation, so that
237    * non-serializable hibernate-specific collections are used internally. The
238    * copy only relies on serializable collections, so it can be serialized
239    * easily.
240    * 
241    * @return a full copy of the projection model, including copies of all
242    *         sub-elements (set types, matrices, etc.)
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    * Copies all simple fields of the projection model.
269    * 
270    * @param original
271    *          the original
272    * @param copy
273    *          the copy
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    * Copies parameter instances (and parameters) from the original projection to
286    * the copy.
287    * 
288    * @param original
289    *          the original
290    * @param copy
291    *          the copy
292    * @return mapping from old parameter instances to their corresponding new
293    *         parameter instances, which is necessary for creating sets and set
294    *         types with the same structure
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    * Copies all sets of the original model to the copy.
311    * 
312    * @param original
313    *          the original
314    * @param copy
315    *          the copy
316    * @param paramInstances
317    *          the mapping from old to new parameter instances
318    * @return the mapping from old sets to their corresponding copies, which is
319    *         necessary to construct set types with the same structure
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    * Copies set types from the original projection to the copy.
338    * 
339    * @param original
340    *          the original
341    * @param copy
342    *          the copy
343    * @param paramInstances
344    *          the mapping from old to new parameter instances
345    * @param sets
346    *          the mapping from old to new sets
347    * @return the mapping from old to new set types, required to correctly update
348    *         the internal structure of the projection (see
349    *         {@link Serializer#copyParamInstToSetTypeMapping(ProjectionModel, ProjectionModel, Map, Map)}
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    * Copies the mapping from parameter instances to the set types that manage
373    * them from the original projection to the copy.
374    * 
375    * @param copy
376    *          the copy
377    * @param original
378    *          the original
379    * @param paramInstances
380    *          the mapping from old to new parameter instances
381    * @param setTypes
382    *          the mapping from old to new set types
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    * Copies a parameter instance.
399    * 
400    * @param paramInstance
401    *          the original parameter instance
402    * @return the copy
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    * Copies a set.
415    * 
416    * @param set
417    *          the original set
418    * @param paramInstances
419    *          the mapping from old to new parameter instances
420    * @return the copy
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    * Copies a parameter assignment set.
442    * 
443    * @param paramAssignmentSet
444    *          the original parameter assignment set
445    * @param paramInstances
446    *          the map from old to new parameter instances
447    * @return the copy
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    * Copies a set type.
464    * 
465    * @param setType
466    *          the original set type
467    * @param paramInstances
468    *          the mapping from old to new parameter instances
469    * @param sets
470    *          the mapping from old to new sets
471    * @return the copy
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    * Loads a projection into the database. In some sense, this method is the
493    * inverse of @link {@link Serializer#copyProjection(ProjectionModel)}, as it
494    * makes sure that the newly loaded projection model is properly managed by
495    * hibernate. The easiest way to do so is by storing it as a new projection.
496    * 
497    * @param absolutePath
498    *          the absolute path
499    * @param database
500    *          the database
501    * @return the projection model
502    * @throws ClassNotFoundException
503    *           the class not found exception
504    * @throws IOException
505    *           Signals that an I/O exception has occurred.
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    * Matches loaded parameter instances to those stored in the database.
541    * 
542    * @param loadedProjection
543    *          the loaded projection
544    * @param newProjection
545    *          the new projection
546    * @param warnings
547    *          the list of warnings to be handed over to the user
548    * @return the map
549    * @throws LoadedProjectionFormatException
550    *           in case no exact one-to-one matching could be found
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    * Match parameter instances. Sort potential matches by smallest Levenshtein
591    * distance to parameter name. If there is no exact matching, a line is added
592    * to the warnings.
593    * 
594    * @param matching
595    *          the mapping from old to new parameter instance, representing the
596    *          current matching
597    * @param targetInstance
598    *          the parameter instance to be matched
599    * @param matchCandidates
600    *          the match candidates that have been found
601    * @param warnings
602    *          the list of all warnings
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    * Save set types.
636    * 
637    * @param loadedProjection
638    *          the loaded projection
639    * @param newProjection
640    *          the new projection
641    * @param paramInstances
642    *          the mapping from old to new parameter instances
643    * @return the mapping from old to new set types
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    * Save sets.
668    * 
669    * @param loadedProjection
670    *          the loaded projection
671    * @param newProjection
672    *          the new projection
673    * @param paramInstances
674    *          the mapping from old to new parameter instances
675    * @param setTypes
676    *          the mapping from old to new set types
677    * @param database
678    *          the database
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    * Save single set.
706    * 
707    * @param loadedSet
708    *          the loaded set
709    * @param newSet
710    *          the new set
711    * @param loadedSetType
712    *          the set type
713    * @param paramInstances
714    *          the mapping from old to new parameter instances
715    * @param database
716    *          the database
717    * @param progress
718    *          the dialog to show the progress
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 }