AbstractFilePersister.java

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
Location : registerPersister
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

124

1.1
Location : createTempFile
Killed by : none
negated conditional → NO_COVERAGE

128

1.1
Location : createTempFile
Killed by : none
negated conditional → NO_COVERAGE

132

1.1
Location : createTempFile
Killed by : none
mutated return of Object value for org/argouml/persistence/AbstractFilePersister::createTempFile to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

153

1.1
Location : useSafeSaves
Killed by : none
removed call to org/argouml/configuration/Configuration::setBoolean → NO_COVERAGE

155

1.1
Location : useSafeSaves
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

175

1.1
Location : copyFile
Killed by : none
negated conditional → NO_COVERAGE

176

1.1
Location : copyFile
Killed by : none
removed call to java/io/FileOutputStream::write → NO_COVERAGE

178

1.1
Location : copyFile
Killed by : none
removed call to java/io/FileInputStream::close → NO_COVERAGE

179

1.1
Location : copyFile
Killed by : none
removed call to java/io/FileOutputStream::close → NO_COVERAGE

183

1.1
Location : copyFile
Killed by : none
mutated return of Object value for org/argouml/persistence/AbstractFilePersister::copyFile to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

195

1.1
Location : accept
Killed by : none
negated conditional → NO_COVERAGE

196

1.1
Location : accept
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

198

1.1
Location : accept
Killed by : none
negated conditional → NO_COVERAGE

199

1.1
Location : accept
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

202

1.1
Location : accept
Killed by : none
negated conditional → NO_COVERAGE

204

1.1
Location : accept
Killed by : none
negated conditional → NO_COVERAGE

205

1.1
Location : accept
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

208

1.1
Location : accept
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

227

1.1
Location : getExtension
Killed by : none
negated conditional → NO_COVERAGE

228

1.1
Location : getExtension
Killed by : none
mutated return of Object value for org/argouml/persistence/AbstractFilePersister::getExtension to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

230

1.1
Location : getExtension
Killed by : none
mutated return of Object value for org/argouml/persistence/AbstractFilePersister::getExtension to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

235

1.1
Location : getExtension
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : getExtension
Killed by : none
changed conditional boundary → NO_COVERAGE

3.3
Location : getExtension
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

4.4
Location : getExtension
Killed by : none
negated conditional → NO_COVERAGE

5.5
Location : getExtension
Killed by : none
negated conditional → NO_COVERAGE

236

1.1
Location : getExtension
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

2.2
Location : getExtension
Killed by : none
mutated return of Object value for org/argouml/persistence/AbstractFilePersister::getExtension to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

238

1.1
Location : getExtension
Killed by : none
mutated return of Object value for org/argouml/persistence/AbstractFilePersister::getExtension to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

249

1.1
Location : isFileExtensionApplicable
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

256

1.1
Location : getDescription
Killed by : none
mutated return of Object value for org/argouml/persistence/AbstractFilePersister::getDescription to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

277

1.1
Location : save
Killed by : none
removed call to org/argouml/persistence/AbstractFilePersister::preSave → NO_COVERAGE

278

1.1
Location : save
Killed by : none
removed call to org/argouml/persistence/AbstractFilePersister::doSave → NO_COVERAGE

279

1.1
Location : save
Killed by : none
removed call to org/argouml/persistence/AbstractFilePersister::postSave → NO_COVERAGE

291

1.1
Location : preSave
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : preSave
Killed by : none
negated conditional → NO_COVERAGE

305

1.1
Location : postSave
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : postSave
Killed by : none
negated conditional → NO_COVERAGE

336

1.1
Location : isSaveEnabled
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

347

1.1
Location : isLoadEnabled
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

364

1.1
Location : addProgressListener
Killed by : none
removed call to javax/swing/event/EventListenerList::add → NO_COVERAGE

374

1.1
Location : removeProgressListener
Killed by : none
removed call to javax/swing/event/EventListenerList::remove → NO_COVERAGE

394

1.1
Location : getMemberFilePersister
Killed by : none
negated conditional → NO_COVERAGE

400

1.1
Location : getMemberFilePersister
Killed by : none
negated conditional → NO_COVERAGE

401

1.1
Location : getMemberFilePersister
Killed by : none
negated conditional → NO_COVERAGE

407

1.1
Location : getMemberFilePersister
Killed by : none
negated conditional → NO_COVERAGE

408

1.1
Location : getMemberFilePersister
Killed by : none
mutated return of Object value for org/argouml/persistence/AbstractFilePersister::getMemberFilePersister to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

410

1.1
Location : getMemberFilePersister
Killed by : none
mutated return of Object value for org/argouml/persistence/AbstractFilePersister::getMemberFilePersister to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

423

1.1
Location : getMemberFilePersister
Killed by : none
negated conditional → NO_COVERAGE

424

1.1
Location : getMemberFilePersister
Killed by : none
mutated return of Object value for org/argouml/persistence/AbstractFilePersister::getMemberFilePersister to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

426

1.1
Location : getMemberFilePersister
Killed by : none
mutated return of Object value for org/argouml/persistence/AbstractFilePersister::getMemberFilePersister to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

432

1.1
Location : newPersister
Killed by : none
mutated return of Object value for org/argouml/persistence/AbstractFilePersister::newPersister to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

435

1.1
Location : newPersister
Killed by : none
mutated return of Object value for org/argouml/persistence/AbstractFilePersister::newPersister to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

438

1.1
Location : newPersister
Killed by : none
mutated return of Object value for org/argouml/persistence/AbstractFilePersister::newPersister to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

477

1.1
Location : getNumberOfPhases
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

481

1.1
Location : nextPhase
Killed by : none
removed call to org/argouml/util/ThreadUtils::checkIfInterrupted → NO_COVERAGE

482

1.1
Location : nextPhase
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

484

1.1
Location : nextPhase
Killed by : none
Replaced integer multiplication with division → NO_COVERAGE

2.2
Location : nextPhase
Killed by : none
Replaced integer division with multiplication → NO_COVERAGE

485

1.1
Location : nextPhase
Killed by : none
removed call to org/argouml/persistence/AbstractFilePersister$ProgressMgr::fireProgressEvent → NO_COVERAGE

495

1.1
Location : progress
Killed by : none
removed call to org/argouml/util/ThreadUtils::checkIfInterrupted → NO_COVERAGE

496

1.1
Location : progress
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

499

1.1
Location : progress
Killed by : none
Replaced long multiplication with division → NO_COVERAGE

2.2
Location : progress
Killed by : none
Replaced long division with multiplication → NO_COVERAGE

500

1.1
Location : progress
Killed by : none
Replaced long addition with subtraction → NO_COVERAGE

2.2
Location : progress
Killed by : none
removed call to org/argouml/persistence/AbstractFilePersister$ProgressMgr::fireProgressEvent → NO_COVERAGE

515

1.1
Location : fireProgressEvent
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : fireProgressEvent
Killed by : none
Changed increment from -2 to 2 → NO_COVERAGE

3.3
Location : fireProgressEvent
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

4.4
Location : fireProgressEvent
Killed by : none
negated conditional → NO_COVERAGE

516

1.1
Location : fireProgressEvent
Killed by : none
negated conditional → NO_COVERAGE

518

1.1
Location : fireProgressEvent
Killed by : none
negated conditional → NO_COVERAGE

521

1.1
Location : fireProgressEvent
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

2.2
Location : fireProgressEvent
Killed by : none
removed call to org/argouml/taskmgmt/ProgressListener::progress → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 0.32