1 | /* $Id: AbstractFilePersister.java 19907 2012-12-30 13:06:01Z closettop_nightlybuild $ | |
2 | ***************************************************************************** | |
3 | * Copyright (c) 2009-2012 Contributors - see below | |
4 | * All rights reserved. This program and the accompanying materials | |
5 | * are made available under the terms of the Eclipse Public License v1.0 | |
6 | * which accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: | |
10 | * tfmorris | |
11 | * Michiel van der Wulp | |
12 | ***************************************************************************** | |
13 | * | |
14 | * Some portions of this file was previously release using the BSD License: | |
15 | */ | |
16 | ||
17 | // Copyright (c) 1996-2007 The Regents of the University of California. All | |
18 | // Rights Reserved. Permission to use, copy, modify, and distribute this | |
19 | // software and its documentation without fee, and without a written | |
20 | // agreement is hereby granted, provided that the above copyright notice | |
21 | // and this paragraph appear in all copies. This software program and | |
22 | // documentation are copyrighted by The Regents of the University of | |
23 | // California. The software program and documentation are supplied "AS | |
24 | // IS", without any accompanying services from The Regents. The Regents | |
25 | // does not warrant that the operation of the program will be | |
26 | // uninterrupted or error-free. The end-user understands that the program | |
27 | // was developed for research purposes and is advised not to rely | |
28 | // exclusively on the program for any reason. IN NO EVENT SHALL THE | |
29 | // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, | |
30 | // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, | |
31 | // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF | |
32 | // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF | |
33 | // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY | |
34 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
35 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE | |
36 | // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF | |
37 | // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, | |
38 | // UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | |
39 | ||
40 | package org.argouml.persistence; | |
41 | ||
42 | import java.io.File; | |
43 | import java.io.FileInputStream; | |
44 | import java.io.FileNotFoundException; | |
45 | import java.io.FileOutputStream; | |
46 | import java.io.IOException; | |
47 | import java.util.HashMap; | |
48 | import java.util.Map; | |
49 | import java.util.logging.Level; | |
50 | import java.util.logging.Logger; | |
51 | ||
52 | import javax.swing.event.EventListenerList; | |
53 | import javax.swing.filechooser.FileFilter; | |
54 | ||
55 | import org.argouml.configuration.Configuration; | |
56 | import org.argouml.kernel.ProfileConfiguration; | |
57 | import org.argouml.kernel.Project; | |
58 | import org.argouml.kernel.ProjectMember; | |
59 | import org.argouml.taskmgmt.ProgressEvent; | |
60 | import org.argouml.taskmgmt.ProgressListener; | |
61 | import org.argouml.uml.ProjectMemberModel; | |
62 | import org.argouml.uml.cognitive.ProjectMemberTodoList; | |
63 | import org.argouml.uml.diagram.ProjectMemberDiagram; | |
64 | import org.argouml.util.ThreadUtils; | |
65 | ||
66 | /** | |
67 | * To persist to and from zargo (zipped file) storage. | |
68 | * | |
69 | * @author Bob Tarling | |
70 | */ | |
71 | public abstract class AbstractFilePersister extends FileFilter | |
72 | implements ProjectFilePersister { | |
73 | ||
74 | private static final Logger LOG = | |
75 | Logger.getLogger(AbstractFilePersister.class.getName()); | |
76 | ||
77 | /** | |
78 | * Map of persisters by target class. | |
79 | */ | |
80 | private static Map<Class, Class<? extends MemberFilePersister>> | |
81 | persistersByClass = | |
82 | new HashMap<Class, Class<? extends MemberFilePersister>>(); | |
83 | ||
84 | /** | |
85 | * Map of persisters by tag / file extension. | |
86 | */ | |
87 | private static Map<String, Class<? extends MemberFilePersister>> | |
88 | persistersByTag = | |
89 | new HashMap<String, Class<? extends MemberFilePersister>>(); | |
90 | ||
91 | static { | |
92 | registerPersister(ProjectMemberDiagram.class, "pgml", | |
93 | DiagramMemberFilePersister.class); | |
94 | registerPersister(ProfileConfiguration.class, "profile", | |
95 | ProfileConfigurationFilePersister.class); | |
96 | registerPersister(ProjectMemberTodoList.class, "todo", | |
97 | TodoListMemberFilePersister.class); | |
98 | registerPersister(ProjectMemberModel.class, "xmi", | |
99 | ModelMemberFilePersister.class); | |
100 | } | |
101 | ||
102 | private EventListenerList listenerList = new EventListenerList(); | |
103 | ||
104 | // This can be made public to allow others to extend their own persisters | |
105 | private static boolean registerPersister(Class target, String tag, | |
106 | Class<? extends MemberFilePersister> persister) { | |
107 | persistersByClass.put(target, persister); | |
108 | persistersByTag.put(tag, persister); | |
109 |
1
1. registerPersister : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return true; |
110 | } | |
111 | ||
112 | /** | |
113 | * Create a temporary copy of the existing file. | |
114 | * | |
115 | * @param file the file to copy. | |
116 | * @return the temp file or null if none copied. | |
117 | * @throws FileNotFoundException if file not found | |
118 | * @throws IOException if error reading or writing | |
119 | */ | |
120 | protected File createTempFile(File file) | |
121 | throws FileNotFoundException, IOException { | |
122 | File tempFile = new File(file.getAbsolutePath() + "#"); | |
123 | ||
124 |
1
1. createTempFile : negated conditional → NO_COVERAGE |
if (tempFile.exists()) { |
125 | tempFile.delete(); | |
126 | } | |
127 | ||
128 |
1
1. createTempFile : negated conditional → NO_COVERAGE |
if (file.exists()) { |
129 | copyFile(file, tempFile); | |
130 | } | |
131 | ||
132 |
1
1. createTempFile : mutated return of Object value for org/argouml/persistence/AbstractFilePersister::createTempFile to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return tempFile; |
133 | } | |
134 | ||
135 | /** | |
136 | * Saving in a safe way means: Retain the previous project | |
137 | * file even when the save operation causes an | |
138 | * exception in the middle. | |
139 | * Also create a backup file after saving. | |
140 | * | |
141 | * See issue 6012 - our method of saving in a safe way does not | |
142 | * work on a SharePoint drive. | |
143 | * Hence we can configure ArgoUML to save unsafe, too... | |
144 | * | |
145 | * @return true if we should be careful | |
146 | */ | |
147 | protected boolean useSafeSaves() { | |
148 | boolean result = Configuration.getBoolean( | |
149 | PersistenceManager.USE_SAFE_SAVES, true); | |
150 | ||
151 | /* make sure this setting exists in the configuration file | |
152 | * to facilitate changing: */ | |
153 |
1
1. useSafeSaves : removed call to org/argouml/configuration/Configuration::setBoolean → NO_COVERAGE |
Configuration.setBoolean(PersistenceManager.USE_SAFE_SAVES, result); |
154 | ||
155 |
1
1. useSafeSaves : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return result; |
156 | } | |
157 | ||
158 | /** | |
159 | * Copies one file src to another, raising file exceptions | |
160 | * if there are some problems. | |
161 | * | |
162 | * @param dest The destination file. | |
163 | * @param src The source file. | |
164 | * @return The destination file after successful copying. | |
165 | * @throws IOException if there is some problems with the files. | |
166 | * @throws FileNotFoundException if any of the files cannot be found. | |
167 | */ | |
168 | protected File copyFile(File src, File dest) | |
169 | throws FileNotFoundException, IOException { | |
170 | ||
171 | FileInputStream fis = new FileInputStream(src); | |
172 | FileOutputStream fos = new FileOutputStream(dest); | |
173 | byte[] buf = new byte[1024]; | |
174 | int i = 0; | |
175 |
1
1. copyFile : negated conditional → NO_COVERAGE |
while ((i = fis.read(buf)) != -1) { |
176 |
1
1. copyFile : removed call to java/io/FileOutputStream::write → NO_COVERAGE |
fos.write(buf, 0, i); |
177 | } | |
178 |
1
1. copyFile : removed call to java/io/FileInputStream::close → NO_COVERAGE |
fis.close(); |
179 |
1
1. copyFile : removed call to java/io/FileOutputStream::close → NO_COVERAGE |
fos.close(); |
180 | ||
181 | dest.setLastModified(src.lastModified()); | |
182 | ||
183 |
1
1. copyFile : mutated return of Object value for org/argouml/persistence/AbstractFilePersister::copyFile to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return dest; |
184 | } | |
185 | ||
186 | ||
187 | ||
188 | //////////////////////////////////////////////////////////////// | |
189 | // FileFilter API | |
190 | ||
191 | /* | |
192 | * @see javax.swing.filechooser.FileFilter#accept(java.io.File) | |
193 | */ | |
194 | public boolean accept(File f) { | |
195 |
1
1. accept : negated conditional → NO_COVERAGE |
if (f == null) { |
196 |
1
1. accept : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return false; |
197 | } | |
198 |
1
1. accept : negated conditional → NO_COVERAGE |
if (f.isDirectory()) { |
199 |
1
1. accept : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return true; |
200 | } | |
201 | String s = getExtension(f); | |
202 |
1
1. accept : negated conditional → NO_COVERAGE |
if (s != null) { |
203 | // this check for files without extension... | |
204 |
1
1. accept : negated conditional → NO_COVERAGE |
if (s.equalsIgnoreCase(getExtension())) { |
205 |
1
1. accept : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return true; |
206 | } | |
207 | } | |
208 |
1
1. accept : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return false; |
209 | } | |
210 | ||
211 | /** | |
212 | * The extension valid for this type of file. | |
213 | * (Just the chars, not the dot: e.g. "zargo".) | |
214 | * | |
215 | * @return the extension valid for this type of file | |
216 | */ | |
217 | public abstract String getExtension(); | |
218 | ||
219 | /** | |
220 | * Just the description, not the extension between "()". | |
221 | * | |
222 | * @return the description valid for this type of file | |
223 | */ | |
224 | protected abstract String getDesc(); | |
225 | ||
226 | private static String getExtension(File f) { | |
227 |
1
1. getExtension : negated conditional → NO_COVERAGE |
if (f == null) { |
228 |
1
1. getExtension : mutated return of Object value for org/argouml/persistence/AbstractFilePersister::getExtension to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return null; |
229 | } | |
230 |
1
1. getExtension : mutated return of Object value for org/argouml/persistence/AbstractFilePersister::getExtension to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return getExtension(f.getName()); |
231 | } | |
232 | ||
233 | private static String getExtension(String filename) { | |
234 | int i = filename.lastIndexOf('.'); | |
235 |
5
1. getExtension : changed conditional boundary → NO_COVERAGE 2. getExtension : changed conditional boundary → NO_COVERAGE 3. getExtension : Replaced integer subtraction with addition → NO_COVERAGE 4. getExtension : negated conditional → NO_COVERAGE 5. getExtension : negated conditional → NO_COVERAGE |
if (i > 0 && i < filename.length() - 1) { |
236 |
2
1. getExtension : Replaced integer addition with subtraction → NO_COVERAGE 2. getExtension : mutated return of Object value for org/argouml/persistence/AbstractFilePersister::getExtension to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return filename.substring(i + 1).toLowerCase(); |
237 | } | |
238 |
1
1. getExtension : mutated return of Object value for org/argouml/persistence/AbstractFilePersister::getExtension to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return null; |
239 | } | |
240 | ||
241 | /** | |
242 | * Given the full filename this returns true if that filename contains the | |
243 | * expected extension for the is persister. | |
244 | * | |
245 | * @param filename The filename to test. | |
246 | * @return true if the filename is valid for this persister | |
247 | */ | |
248 | public boolean isFileExtensionApplicable(String filename) { | |
249 |
1
1. isFileExtensionApplicable : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return filename.toLowerCase().endsWith("." + getExtension()); |
250 | } | |
251 | ||
252 | /* | |
253 | * @see javax.swing.filechooser.FileFilter#getDescription() | |
254 | */ | |
255 | public String getDescription() { | |
256 |
1
1. getDescription : mutated return of Object value for org/argouml/persistence/AbstractFilePersister::getDescription to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return getDesc() + " (*." + getExtension() + ")"; |
257 | } | |
258 | ||
259 | /** | |
260 | * Save a project to file.<p> | |
261 | * This first archives the existing file, then calls | |
262 | * doSave(...) to do the actual saving.<p> | |
263 | * Should doSave(...) throw an exception then it is | |
264 | * caught here and any rollback handled before rethrowing | |
265 | * the exception. | |
266 | * | |
267 | * @param project The project being saved. | |
268 | * @param file The file to which the save is taking place. | |
269 | * @throws SaveException when anything goes wrong | |
270 | * @throws InterruptedException if the thread is interrupted | |
271 | * | |
272 | * @see org.argouml.persistence.ProjectFilePersister#save( | |
273 | * org.argouml.kernel.Project, java.io.File) | |
274 | */ | |
275 | public final void save(Project project, File file) throws SaveException, | |
276 | InterruptedException { | |
277 |
1
1. save : removed call to org/argouml/persistence/AbstractFilePersister::preSave → NO_COVERAGE |
preSave(project, file); |
278 |
1
1. save : removed call to org/argouml/persistence/AbstractFilePersister::doSave → NO_COVERAGE |
doSave(project, file); |
279 |
1
1. save : removed call to org/argouml/persistence/AbstractFilePersister::postSave → NO_COVERAGE |
postSave(project, file); |
280 | } | |
281 | ||
282 | /** | |
283 | * Handle archiving of previous file or any other common | |
284 | * requirements before saving a model to a file. | |
285 | * | |
286 | * @param project The project being saved. | |
287 | * @param file The file to which the save is taking place. | |
288 | * @throws SaveException when anything goes wrong | |
289 | */ | |
290 | private void preSave(Project project, File file) throws SaveException { | |
291 |
2
1. preSave : negated conditional → NO_COVERAGE 2. preSave : negated conditional → NO_COVERAGE |
if (project == null && file == null) { |
292 | throw new SaveException("No project nor file given"); | |
293 | } | |
294 | } | |
295 | ||
296 | /** | |
297 | * Handle archiving on completion of a save such as renaming | |
298 | * the temporary save file to the real filename. | |
299 | * | |
300 | * @param project The project being saved. | |
301 | * @param file The file to which the save is taking place. | |
302 | * @throws SaveException when anything goes wrong | |
303 | */ | |
304 | private void postSave(Project project, File file) throws SaveException { | |
305 |
2
1. postSave : negated conditional → NO_COVERAGE 2. postSave : negated conditional → NO_COVERAGE |
if (project == null && file == null) { |
306 | throw new SaveException("No project nor file given"); | |
307 | } | |
308 | } | |
309 | ||
310 | /** | |
311 | * Implement in your concrete class to save a project to a | |
312 | * file.<p> | |
313 | * There is no need to worry about archiving or restoring | |
314 | * archive on failure, that is handled by the rest of the | |
315 | * framework.<p> | |
316 | * | |
317 | * @param project the project to save | |
318 | * @param file The file to write. | |
319 | * @throws SaveException when anything goes wrong | |
320 | * @throws InterruptedException if the thread is interrupted | |
321 | * | |
322 | * @see org.argouml.persistence.AbstractFilePersister#save( | |
323 | * org.argouml.kernel.Project, java.io.File) | |
324 | */ | |
325 | protected abstract void doSave(Project project, File file) | |
326 | throws SaveException, InterruptedException; | |
327 | ||
328 | /** | |
329 | * Some persisters only provide load functionality for discontinued formats | |
330 | * but no save. | |
331 | * This method returns true by default. Those Peristers that do not provide | |
332 | * save must override this. | |
333 | * @return true if this persister is able to save | |
334 | */ | |
335 | public boolean isSaveEnabled() { | |
336 |
1
1. isSaveEnabled : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return true; |
337 | } | |
338 | ||
339 | /** | |
340 | * Some persisters only provide save functionality for deprecated formats. | |
341 | * Other persisters with the same extension will manage loading. | |
342 | * This method returns true by default. Those Peristers that do not provide | |
343 | * load must override this. | |
344 | * @return true if this persister is able to load | |
345 | */ | |
346 | public boolean isLoadEnabled() { | |
347 |
1
1. isLoadEnabled : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return true; |
348 | } | |
349 | ||
350 | /* | |
351 | * @see org.argouml.persistence.ProjectFilePersister#doLoad(java.io.File) | |
352 | */ | |
353 | public abstract Project doLoad(File file) | |
354 | throws OpenException, InterruptedException; | |
355 | ||
356 | ||
357 | ||
358 | /** | |
359 | * Add any object interested in listening to persistence progress. | |
360 | * | |
361 | * @param listener the interested listener. | |
362 | */ | |
363 | public void addProgressListener(ProgressListener listener) { | |
364 |
1
1. addProgressListener : removed call to javax/swing/event/EventListenerList::add → NO_COVERAGE |
listenerList.add(ProgressListener.class, listener); |
365 | } | |
366 | ||
367 | /** | |
368 | * Remove any object no longer interested in listening to persistence | |
369 | * progress. | |
370 | * | |
371 | * @param listener the listener to remove. | |
372 | */ | |
373 | public void removeProgressListener(ProgressListener listener) { | |
374 |
1
1. removeProgressListener : removed call to javax/swing/event/EventListenerList::remove → NO_COVERAGE |
listenerList.remove(ProgressListener.class, listener); |
375 | } | |
376 | ||
377 | /** | |
378 | * Returns true if a FileChooser should visualize an icon for the | |
379 | * persister. | |
380 | * | |
381 | * @return true if the persister is associated to an icon | |
382 | */ | |
383 | public abstract boolean hasAnIcon(); | |
384 | ||
385 | ||
386 | /** | |
387 | * Get a MemberFilePersister based on a given ProjectMember. | |
388 | * | |
389 | * @param pm the project member | |
390 | * @return the persister | |
391 | */ | |
392 | protected MemberFilePersister getMemberFilePersister(ProjectMember pm) { | |
393 | Class<? extends MemberFilePersister> persister = null; | |
394 |
1
1. getMemberFilePersister : negated conditional → NO_COVERAGE |
if (persistersByClass.containsKey(pm)) { |
395 | persister = persistersByClass.get(pm); | |
396 | } else { | |
397 | /* | |
398 | * TODO: Not sure we need to do this, but just to be safe for now. | |
399 | */ | |
400 |
1
1. getMemberFilePersister : negated conditional → NO_COVERAGE |
for (Class clazz : persistersByClass.keySet()) { |
401 |
1
1. getMemberFilePersister : negated conditional → NO_COVERAGE |
if (clazz.isAssignableFrom(pm.getClass())) { |
402 | persister = persistersByClass.get(clazz); | |
403 | break; | |
404 | } | |
405 | } | |
406 | } | |
407 |
1
1. getMemberFilePersister : negated conditional → NO_COVERAGE |
if (persister != null) { |
408 |
1
1. getMemberFilePersister : mutated return of Object value for org/argouml/persistence/AbstractFilePersister::getMemberFilePersister to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return newPersister(persister); |
409 | } | |
410 |
1
1. getMemberFilePersister : mutated return of Object value for org/argouml/persistence/AbstractFilePersister::getMemberFilePersister to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return null; |
411 | } | |
412 | ||
413 | ||
414 | /** | |
415 | * Get a MemberFilePersister based on a given tag. | |
416 | * | |
417 | * @param tag The tag. | |
418 | * @return the persister | |
419 | */ | |
420 | protected MemberFilePersister getMemberFilePersister(String tag) { | |
421 | Class<? extends MemberFilePersister> persister = | |
422 | persistersByTag.get(tag); | |
423 |
1
1. getMemberFilePersister : negated conditional → NO_COVERAGE |
if (persister != null) { |
424 |
1
1. getMemberFilePersister : mutated return of Object value for org/argouml/persistence/AbstractFilePersister::getMemberFilePersister to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return newPersister(persister); |
425 | } | |
426 |
1
1. getMemberFilePersister : mutated return of Object value for org/argouml/persistence/AbstractFilePersister::getMemberFilePersister to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return null; |
427 | } | |
428 | ||
429 | private static MemberFilePersister newPersister( | |
430 | Class<? extends MemberFilePersister> clazz) { | |
431 | try { | |
432 |
1
1. newPersister : mutated return of Object value for org/argouml/persistence/AbstractFilePersister::newPersister to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return clazz.newInstance(); |
433 | } catch (InstantiationException e) { | |
434 | LOG.log(Level.SEVERE, "Exception instantiating file persister " + clazz, e); | |
435 |
1
1. newPersister : mutated return of Object value for org/argouml/persistence/AbstractFilePersister::newPersister to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return null; |
436 | } catch (IllegalAccessException e) { | |
437 | LOG.log(Level.SEVERE, "Exception instantiating file persister " + clazz, e); | |
438 |
1
1. newPersister : mutated return of Object value for org/argouml/persistence/AbstractFilePersister::newPersister to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return null; |
439 | } | |
440 | } | |
441 | ||
442 | // TODO: Document | |
443 | class ProgressMgr implements ProgressListener { | |
444 | ||
445 | /** | |
446 | * The percentage completeness of phases complete. | |
447 | * Does not include part-completed phases. | |
448 | */ | |
449 | private int percentPhasesComplete; | |
450 | ||
451 | /** | |
452 | * The sections complete of a load or save. | |
453 | */ | |
454 | private int phasesCompleted; | |
455 | ||
456 | /** | |
457 | * The number of equals phases the progress will measure. | |
458 | * It is assumed each phase will be of equal time. | |
459 | * There is one phase for each upgrade from a previous | |
460 | * version and one pahse for the final load. | |
461 | */ | |
462 | private int numberOfPhases; | |
463 | ||
464 | public void setPercentPhasesComplete(int aPercentPhasesComplete) { | |
465 | this.percentPhasesComplete = aPercentPhasesComplete; | |
466 | } | |
467 | ||
468 | public void setPhasesCompleted(int aPhasesCompleted) { | |
469 | this.phasesCompleted = aPhasesCompleted; | |
470 | } | |
471 | ||
472 | public void setNumberOfPhases(int aNumberOfPhases) { | |
473 | this.numberOfPhases = aNumberOfPhases; | |
474 | } | |
475 | ||
476 | public int getNumberOfPhases() { | |
477 |
1
1. getNumberOfPhases : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return this.numberOfPhases; |
478 | } | |
479 | ||
480 | protected void nextPhase() throws InterruptedException { | |
481 |
1
1. nextPhase : removed call to org/argouml/util/ThreadUtils::checkIfInterrupted → NO_COVERAGE |
ThreadUtils.checkIfInterrupted(); |
482 |
1
1. nextPhase : Replaced integer addition with subtraction → NO_COVERAGE |
++phasesCompleted; |
483 | percentPhasesComplete = | |
484 |
2
1. nextPhase : Replaced integer multiplication with division → NO_COVERAGE 2. nextPhase : Replaced integer division with multiplication → NO_COVERAGE |
(phasesCompleted * 100) / numberOfPhases; |
485 |
1
1. nextPhase : removed call to org/argouml/persistence/AbstractFilePersister$ProgressMgr::fireProgressEvent → NO_COVERAGE |
fireProgressEvent(percentPhasesComplete); |
486 | } | |
487 | ||
488 | /** | |
489 | * Called when a ProgressEvent is fired. | |
490 | * | |
491 | * @see org.argouml.taskmgmt.ProgressListener#progress(org.argouml.taskmgmt.ProgressEvent) | |
492 | * @throws InterruptedException if thread is interrupted | |
493 | */ | |
494 | public void progress(ProgressEvent event) throws InterruptedException { | |
495 |
1
1. progress : removed call to org/argouml/util/ThreadUtils::checkIfInterrupted → NO_COVERAGE |
ThreadUtils.checkIfInterrupted(); |
496 |
1
1. progress : Replaced integer subtraction with addition → NO_COVERAGE |
int percentPhasesLeft = 100 - percentPhasesComplete; |
497 | long position = event.getPosition(); | |
498 | long length = event.getLength(); | |
499 |
2
1. progress : Replaced long multiplication with division → NO_COVERAGE 2. progress : Replaced long division with multiplication → NO_COVERAGE |
long proportion = (position * percentPhasesLeft) / length; |
500 |
2
1. progress : Replaced long addition with subtraction → NO_COVERAGE 2. progress : removed call to org/argouml/persistence/AbstractFilePersister$ProgressMgr::fireProgressEvent → NO_COVERAGE |
fireProgressEvent(percentPhasesComplete + proportion); |
501 | } | |
502 | ||
503 | /** | |
504 | * Inform listeners of any progress notifications. | |
505 | * @param percent the current percentage progress. | |
506 | * @throws InterruptedException if thread is interrupted | |
507 | */ | |
508 | protected void fireProgressEvent(long percent) | |
509 | throws InterruptedException { | |
510 | ProgressEvent event = null; | |
511 | // Guaranteed to return a non-null array | |
512 | Object[] listeners = listenerList.getListenerList(); | |
513 | // Process the listeners last to first, notifying | |
514 | // those that are interested in this event | |
515 |
4
1. fireProgressEvent : changed conditional boundary → NO_COVERAGE 2. fireProgressEvent : Changed increment from -2 to 2 → NO_COVERAGE 3. fireProgressEvent : Replaced integer subtraction with addition → NO_COVERAGE 4. fireProgressEvent : negated conditional → NO_COVERAGE |
for (int i = listeners.length - 2; i >= 0; i -= 2) { |
516 |
1
1. fireProgressEvent : negated conditional → NO_COVERAGE |
if (listeners[i] == ProgressListener.class) { |
517 | // Lazily create the event: | |
518 |
1
1. fireProgressEvent : negated conditional → NO_COVERAGE |
if (event == null) { |
519 | event = new ProgressEvent(this, percent, 100); | |
520 | } | |
521 |
2
1. fireProgressEvent : Replaced integer addition with subtraction → NO_COVERAGE 2. fireProgressEvent : removed call to org/argouml/taskmgmt/ProgressListener::progress → NO_COVERAGE |
((ProgressListener) listeners[i + 1]).progress(event); |
522 | } | |
523 | } | |
524 | } | |
525 | } | |
526 | } | |
Mutations | ||
109 |
1.1 |
|
124 |
1.1 |
|
128 |
1.1 |
|
132 |
1.1 |
|
153 |
1.1 |
|
155 |
1.1 |
|
175 |
1.1 |
|
176 |
1.1 |
|
178 |
1.1 |
|
179 |
1.1 |
|
183 |
1.1 |
|
195 |
1.1 |
|
196 |
1.1 |
|
198 |
1.1 |
|
199 |
1.1 |
|
202 |
1.1 |
|
204 |
1.1 |
|
205 |
1.1 |
|
208 |
1.1 |
|
227 |
1.1 |
|
228 |
1.1 |
|
230 |
1.1 |
|
235 |
1.1 2.2 3.3 4.4 5.5 |
|
236 |
1.1 2.2 |
|
238 |
1.1 |
|
249 |
1.1 |
|
256 |
1.1 |
|
277 |
1.1 |
|
278 |
1.1 |
|
279 |
1.1 |
|
291 |
1.1 2.2 |
|
305 |
1.1 2.2 |
|
336 |
1.1 |
|
347 |
1.1 |
|
364 |
1.1 |
|
374 |
1.1 |
|
394 |
1.1 |
|
400 |
1.1 |
|
401 |
1.1 |
|
407 |
1.1 |
|
408 |
1.1 |
|
410 |
1.1 |
|
423 |
1.1 |
|
424 |
1.1 |
|
426 |
1.1 |
|
432 |
1.1 |
|
435 |
1.1 |
|
438 |
1.1 |
|
477 |
1.1 |
|
481 |
1.1 |
|
482 |
1.1 |
|
484 |
1.1 2.2 |
|
485 |
1.1 |
|
495 |
1.1 |
|
496 |
1.1 |
|
499 |
1.1 2.2 |
|
500 |
1.1 2.2 |
|
515 |
1.1 2.2 3.3 4.4 |
|
516 |
1.1 |
|
518 |
1.1 |
|
521 |
1.1 2.2 |