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