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.gui.dialogs;
17  
18  import java.util.HashMap;
19  import java.util.List;
20  import java.util.Map;
21  import java.util.Map.Entry;
22  import java.util.logging.Level;
23  
24  import javax.swing.JLabel;
25  import javax.swing.JTextField;
26  import javax.swing.SwingWorker;
27  
28  import org.jamesii.SimSystem;
29  
30  import p3j.database.DatabaseFactory;
31  import p3j.database.IP3MDatabase;
32  import p3j.gui.panels.PropertiesShowPanelFactory;
33  import p3j.misc.gui.GUI;
34  import p3j.pppm.PPPModelFactory;
35  import p3j.pppm.ProjectionModel;
36  import p3j.pppm.parameters.ParameterAssignment;
37  import p3j.pppm.parameters.ParameterAssignmentSet;
38  import p3j.pppm.parameters.ParameterInstance;
39  import p3j.pppm.sets.Set;
40  import p3j.pppm.sets.SetType;
41  
42  /**
43   * Duplicates a projection.
44   * 
45   * @author Christina Bohk
46   * @author Roland Ewald
47   */
48  public class DuplicateProjectionDialog extends ProcessProjectionDialog {
49  
50    /** Serialization ID. */
51    private static final long serialVersionUID = 8436821751889161548L;
52  
53    /** The text field to set the name of the new projection. */
54    private final JTextField newProjectionName = new JTextField("");
55  
56    /**
57     * Instantiates a new duplicate projection dialog.
58     * 
59     * @param projection
60     *          the projection
61     */
62    public DuplicateProjectionDialog(ProjectionModel projection) {
63      super(projection);
64      initUI();
65    }
66  
67    /**
68     * Initialize the user interface.
69     */
70    private void initUI() {
71      setTitle("Name of the duplicate projection.");
72      setSize(DIALOG_WIDTH, DIALOG_HEIGHT);
73      setModal(true);
74      GUI.centerOnScreen(this);
75      newProjectionName.setText(getProjectionModel().getName());
76      PropertiesShowPanelFactory pspf = new PropertiesShowPanelFactory(
77          getButtons(), 1);
78      pspf.sep("Duplicate Projection");
79      pspf.app("Name of duplicated projection:", newProjectionName);
80      getContentPane().add(pspf.constructPanel());
81    }
82  
83    /**
84     * Duplicates projection.
85     * 
86     * @param newProjName
87     *          the new projection name
88     */
89    protected void duplicateProjection(final String newProjName) {
90      final JLabel status = reinitializeUIForAdjustment();
91  
92      SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
93        @Override
94        protected Void doInBackground() {
95          try {
96            DuplicateProjectionDialog.duplicate(
97                DatabaseFactory.getDatabaseSingleton(), getProjectionModel(),
98                newProjName, status);
99          } catch (RuntimeException ex) {
100           GUI.printErrorMessage("Error while duplicating projection!", ex);
101         }
102         return null;
103       }
104 
105       @Override
106       public void done() {
107         setVisible(false);
108       }
109     };
110 
111     worker.execute();
112   }
113 
114   /**
115    * Duplicate.
116    * 
117    * @param db
118    *          the database to use
119    * @param originalProjection
120    *          the projection to be duplicated
121    * @param newProjectionName
122    *          the new projection name
123    * @param status
124    *          a label to print the status (may be null)
125    */
126   public static void duplicate(IP3MDatabase db,
127       ProjectionModel originalProjection, String newProjectionName,
128       JLabel status) {
129 
130     ProjectionModel duplicateProjection = PPPModelFactory.createModel(
131         newProjectionName, originalProjection.getDescription(),
132         originalProjection.getGenerations(), originalProjection.getYears(),
133         originalProjection.getMaximumAge(),
134         originalProjection.getJumpOffYear(),
135         originalProjection.getSubPopulationModel());
136 
137     db.newProjection(duplicateProjection);
138 
139     // Copy Settypes
140     Map<SetType, SetType> setTypeMap = new HashMap<SetType, SetType>();
141     for (SetType originalSetType : originalProjection.getUserDefinedTypes()) {
142       SetType duplicateSetType = duplicateProjection.createSetType(
143           originalSetType.getName(), originalSetType.getDescription());
144       setTypeMap.put(originalSetType, duplicateSetType);
145       for (ParameterInstance parameterInstance : originalSetType
146           .getDefinedParameters()) {
147         duplicateProjection.assignParameterInstance(
148             getInstance(duplicateProjection, parameterInstance),
149             duplicateSetType, false);
150       }
151     }
152 
153     // Copy sets
154     for (Entry<SetType, SetType> setTypes : setTypeMap.entrySet()) {
155       copySets(db, status, setTypes.getKey(), duplicateProjection,
156           setTypes.getValue(), false);
157     }
158     copySets(db, status, originalProjection.getDefaultSetType(),
159         duplicateProjection, duplicateProjection.getDefaultSetType(), true);
160 
161     db.saveProjection(duplicateProjection);
162   }
163 
164   /**
165    * Copy sets.
166    * 
167    * @param db
168    *          the database
169    * @param status
170    *          the status
171    * @param originalSetType
172    *          the original Settype
173    * @param duplicateProjection
174    *          the duplicate projection
175    * @param duplicateSetType
176    *          the duplicate Settype
177    * @param isDefaultSetType
178    *          the flag for being the default Settype
179    */
180   private static void copySets(IP3MDatabase db, JLabel status,
181       SetType originalSetType, ProjectionModel duplicateProjection,
182       SetType duplicateSetType, boolean isDefaultSetType) {
183     for (Set set : originalSetType.getSets()) {
184       Set duplicateSet = isDefaultSetType ? duplicateProjection.getDefaultSet()
185           : duplicateSetType.createSet(set.getName(), set.getDescription(),
186               set.getProbability());
187       copySet(db, status, set, duplicateProjection, duplicateSet,
188           originalSetType.getDefinedParameters());
189     }
190   }
191 
192   /**
193    * Copy a set.
194    * 
195    * @param db
196    *          the database
197    * @param status
198    *          the status label
199    * @param originalSet
200    *          the original set
201    * @param duplicateProjection
202    *          the duplicate projection
203    * @param duplicateSet
204    *          the duplicate set
205    * @param definedParameters
206    *          the defined parameters
207    */
208   private static void copySet(IP3MDatabase db, JLabel status, Set originalSet,
209       ProjectionModel duplicateProjection, Set duplicateSet,
210       List<ParameterInstance> definedParameters) {
211     for (ParameterInstance paramInst : definedParameters) {
212       ParameterAssignmentSet paramAssignments = originalSet
213           .getParameterAssignments(paramInst);
214       ParameterInstance duplInst = getInstance(duplicateProjection, paramInst);
215       for (ParameterAssignment origPA : paramAssignments.getAssignments()) {
216         status.setText("Copying parameter assignment '" + origPA.getName()
217             + "' for " + paramInst);
218         SimSystem.report(Level.INFO,
219             "Copying parameter assignment '" + origPA.getName() + "' for "
220                 + paramInst);
221         ParameterAssignment duplPA = db.newParameterAssignment(duplInst,
222             origPA.getName(), origPA.getDescription(), origPA.getProbability(),
223             origPA.getDeviation(), origPA.getMatrixValue());
224         duplPA.setParamInstance(duplInst);
225         duplicateSet.addParameterAssignment(duplPA);
226       }
227     }
228   }
229 
230   /**
231    * Gets a parameter instance equal to the parameter from the projection model.
232    * 
233    * @param newProj
234    *          the new projection model
235    * @param instance
236    *          the instance
237    * 
238    * @return single instance of DuplicateProjectionDialog
239    */
240   private static ParameterInstance getInstance(ProjectionModel newProj,
241       ParameterInstance instance) {
242     for (ParameterInstance inst : newProj.getAllParameterInstances()) {
243       // TODO: Move this to equals(...) method in parameter instance
244       boolean valDimentionMatches = (inst.getValueHeight() == instance
245           .getValueHeight() && inst.getValueWidth() == instance.getValueWidth());
246       boolean subPopMatches = (inst.getGeneration() == instance.getGeneration() && inst
247           .getParameter().getPopulation() == instance.getParameter()
248           .getPopulation());
249       if (inst.getParameter().getName()
250           .equals(instance.getParameter().getName())
251           && subPopMatches && valDimentionMatches) {
252         return inst;
253       }
254     }
255     return null;
256   }
257 
258   @Override
259   protected void okAction() {
260     duplicateProjection(newProjectionName.getText());
261   }
262 
263 }