ZipFilePersister.java

1
/* $Id: ZipFilePersister.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-2008 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.BufferedOutputStream;
43
import java.io.File;
44
import java.io.FileNotFoundException;
45
import java.io.FileOutputStream;
46
import java.io.IOException;
47
import java.io.InputStream;
48
import java.io.OutputStream;
49
import java.net.URL;
50
import java.util.logging.Level;
51
import java.util.logging.Logger;
52
import java.util.zip.ZipEntry;
53
import java.util.zip.ZipInputStream;
54
import java.util.zip.ZipOutputStream;
55
56
import org.argouml.i18n.Translator;
57
import org.argouml.kernel.Project;
58
import org.argouml.kernel.ProjectFactory;
59
import org.argouml.kernel.ProjectManager;
60
import org.argouml.kernel.ProjectMember;
61
import org.argouml.model.Model;
62
import org.xml.sax.InputSource;
63
64
/**
65
 * To persist to and from zipped xmi file storage.
66
 *
67
 * @author Bob Tarling
68
 * @author Ludovic Maître
69
 */
70
class ZipFilePersister extends XmiFilePersister {
71
    /**
72
     * Logger.
73
     */
74
    private static final Logger LOG =
75
        Logger.getLogger(ZipFilePersister.class.getName());
76
77
    /**
78
     * The constructor.
79
     */
80
    public ZipFilePersister() {
81
    }
82
83
    /*
84
     * @see org.argouml.persistence.AbstractFilePersister#getExtension()
85
     */
86
    public String getExtension() {
87 1 1. getExtension : mutated return of Object value for org/argouml/persistence/ZipFilePersister::getExtension to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
        return "zip";
88
    }
89
90
    /*
91
     * @see org.argouml.persistence.AbstractFilePersister#getDesc()
92
     */
93
    protected String getDesc() {
94 1 1. getDesc : mutated return of Object value for org/argouml/persistence/ZipFilePersister::getDesc to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
        return Translator.localize("combobox.filefilter.zip");
95
    }
96
97
    /*
98
     * @see org.argouml.persistence.XmiFilePersister#isSaveEnabled()
99
     */
100
    public boolean isSaveEnabled() {
101 1 1. isSaveEnabled : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
        return true;
102
    }
103
104
    /**
105
     * Save the project in ZIP format.
106
     *
107
     * @param file
108
     *            The file to write.
109
     * @param project
110
     *            the project to save
111
     * @throws SaveException
112
     *             when anything goes wrong
113
     *
114
     * @see org.argouml.persistence.ProjectFilePersister#save(
115
     *      org.argouml.kernel.Project, java.io.File)
116
     */
117
    public void doSave(Project project, File file) throws SaveException {
118
119
        LOG.log(Level.INFO, "Receiving file {0}", file.getName());
120
121
        /* Retain the previous project file even when the save operation
122
         * crashes in the middle. Also create a backup file after saving. */
123
        boolean doSafeSaves = useSafeSaves();
124
125
        File lastArchiveFile = new File(file.getAbsolutePath() + "~");
126
        File tempFile = null;
127
128 1 1. doSave : negated conditional → NO_COVERAGE
        if (doSafeSaves) {
129
            try {
130
                tempFile = createTempFile(file);
131
            } catch (FileNotFoundException e) {
132
                throw new SaveException(Translator.localize(
133
                        "optionpane.save-project-exception-cause1"), e);
134
            } catch (IOException e) {
135
                throw new SaveException(Translator.localize(
136
                        "optionpane.save-project-exception-cause2"), e);
137
            }
138
        }
139
140
        OutputStream bufferedStream = null;
141
        try {
142
            //project.setFile(file);
143
144
            ZipOutputStream stream =
145
                new ZipOutputStream(new FileOutputStream(file));
146
            String fileName = file.getName();
147
            ZipEntry xmiEntry =
148
                new ZipEntry(fileName.substring(0, fileName.lastIndexOf(".")));
149 1 1. doSave : removed call to java/util/zip/ZipOutputStream::putNextEntry → NO_COVERAGE
            stream.putNextEntry(xmiEntry);
150
            bufferedStream = new BufferedOutputStream(stream);
151
152
            int size = project.getMembers().size();
153 3 1. doSave : changed conditional boundary → NO_COVERAGE
2. doSave : Changed increment from 1 to -1 → NO_COVERAGE
3. doSave : negated conditional → NO_COVERAGE
            for (int i = 0; i < size; i++) {
154
                ProjectMember projectMember =
155
                    project.getMembers().get(i);
156 1 1. doSave : negated conditional → NO_COVERAGE
                if (projectMember.getType().equalsIgnoreCase("xmi")) {
157
                    LOG.log(Level.FINE,
158
                            "Saving member of type: {0}",
159
                            projectMember.getType());
160
161
                    MemberFilePersister persister
162
                        = new ModelMemberFilePersister();
163 1 1. doSave : removed call to org/argouml/persistence/MemberFilePersister::save → NO_COVERAGE
                    persister.save(projectMember, bufferedStream);
164
                }
165
            }
166 1 1. doSave : removed call to java/util/zip/ZipOutputStream::close → NO_COVERAGE
            stream.close();
167
168 1 1. doSave : negated conditional → NO_COVERAGE
            if (doSafeSaves) {
169
                // if save did not raise an exception
170
                // and name+"#" exists move name+"#" to name+"~"
171
                // this is the correct backup file
172 1 1. doSave : negated conditional → NO_COVERAGE
                if (lastArchiveFile.exists()) {
173
                    lastArchiveFile.delete();
174
                }
175 2 1. doSave : negated conditional → NO_COVERAGE
2. doSave : negated conditional → NO_COVERAGE
                if (tempFile.exists() && !lastArchiveFile.exists()) {
176
                    tempFile.renameTo(lastArchiveFile);
177
                }
178 1 1. doSave : negated conditional → NO_COVERAGE
                if (tempFile.exists()) {
179
                    tempFile.delete();
180
                }
181
            }
182
        } catch (Exception e) {
183
            LOG.log(Level.SEVERE, "Exception occured during save attempt", e);
184
            try {
185 1 1. doSave : removed call to java/io/OutputStream::close → NO_COVERAGE
                bufferedStream.close();
186
            } catch (IOException ex) {
187
                // If we get a 2nd error, just ignore it
188
            }
189
190 1 1. doSave : negated conditional → NO_COVERAGE
            if (doSafeSaves) {
191
                // frank: in case of exception
192
                // delete name and mv name+"#" back to name if name+"#" exists
193
                // this is the "rollback" to old file
194
                file.delete();
195
                tempFile.renameTo(file);
196
            }
197
            // we have to give a message to user and set the system to unsaved!
198
            throw new SaveException(e);
199
        }
200
201
        try {
202 1 1. doSave : removed call to java/io/OutputStream::close → NO_COVERAGE
            bufferedStream.close();
203
        } catch (IOException ex) {
204
            LOG.log(Level.SEVERE, "Failed to close save output writer", ex);
205
        }
206
    }
207
208
    /*
209
     * @see org.argouml.persistence.ProjectFilePersister#doLoad(java.io.File)
210
     */
211
    public Project doLoad(File file)
212
        throws OpenException {
213
214
        LOG.log(Level.INFO, "Receiving file {0}", file.getName());
215
216
        try {
217
            Project p = ProjectFactory.getInstance().createProject();
218
            String fileName = file.getName();
219
            String extension =
220
                fileName.substring(
221
                        fileName.indexOf('.'),
222
                        fileName.lastIndexOf('.'));
223
            InputStream stream = openZipStreamAt(file.toURI().toURL(),
224
                    extension);
225
226
            // TODO: What progressMgr is to be used here? Where does
227
            //       it come from?
228
            InputSource is =
229
                new InputSource(
230
                    new XmiInputStream(stream, this, 100000, null));
231 1 1. doLoad : removed call to org/xml/sax/InputSource::setSystemId → NO_COVERAGE
            is.setSystemId(file.toURI().toURL().toExternalForm());
232
233
            ModelMemberFilePersister modelPersister =
234
                new ModelMemberFilePersister();
235
236 1 1. doLoad : removed call to org/argouml/persistence/ModelMemberFilePersister::readModels → NO_COVERAGE
            modelPersister.readModels(is);
237
            // TODO Handle multiple top level packages
238
            Object model = modelPersister.getCurModel();
239 1 1. doLoad : removed call to org/argouml/model/UmlHelper::addListenersToModel → NO_COVERAGE
            Model.getUmlHelper().addListenersToModel(model);
240 1 1. doLoad : removed call to org/argouml/kernel/Project::setUUIDRefs → NO_COVERAGE
            p.setUUIDRefs(modelPersister.getUUIDRefs());
241 1 1. doLoad : removed call to org/argouml/kernel/Project::addMember → NO_COVERAGE
            p.addMember(model);
242 1 1. doLoad : removed call to org/argouml/persistence/ZipFilePersister::parseXmiExtensions → NO_COVERAGE
            parseXmiExtensions(p);
243 1 1. doLoad : removed call to org/argouml/persistence/ModelMemberFilePersister::registerDiagrams → NO_COVERAGE
            modelPersister.registerDiagrams(p);
244
245 1 1. doLoad : removed call to org/argouml/kernel/Project::setRoot → NO_COVERAGE
            p.setRoot(model);
246 1 1. doLoad : removed call to org/argouml/kernel/Project::setRoots → NO_COVERAGE
            p.setRoots(modelPersister.getElementsRead());
247 1 1. doLoad : removed call to org/argouml/kernel/ProjectManager::setSaveEnabled → NO_COVERAGE
            ProjectManager.getManager().setSaveEnabled(false);
248 1 1. doLoad : mutated return of Object value for org/argouml/persistence/ZipFilePersister::doLoad to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
            return p;
249
        } catch (IOException e) {
250
            throw new OpenException(e);
251
        }
252
253
    }
254
255
    /**
256
     * Open a ZipInputStream to the first file found with a given extension.
257
     *
258
     * @param url
259
     *            The URL of the zip file.
260
     * @param ext
261
     *            The required extension.
262
     * @return the zip stream positioned at the required location.
263
     * @throws IOException
264
     *             if there is a problem opening the file.
265
     */
266
    private ZipInputStream openZipStreamAt(URL url, String ext)
267
        throws IOException {
268
        ZipInputStream zis = new ZipInputStream(url.openStream());
269
        ZipEntry entry = zis.getNextEntry();
270 2 1. openZipStreamAt : negated conditional → NO_COVERAGE
2. openZipStreamAt : negated conditional → NO_COVERAGE
        while (entry != null && !entry.getName().endsWith(ext)) {
271
            entry = zis.getNextEntry();
272
        }
273 1 1. openZipStreamAt : mutated return of Object value for org/argouml/persistence/ZipFilePersister::openZipStreamAt to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
        return zis;
274
    }
275
276
    /**
277
     * Returns false. Only Argo specific files have an icon.
278
     *
279
     * @see org.argouml.persistence.AbstractFilePersister#hasAnIcon()
280
     */
281
    @Override
282
    public boolean hasAnIcon() {
283 1 1. hasAnIcon : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
        return false;
284
    }
285
}

Mutations

87

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

94

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

101

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

128

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

149

1.1
Location : doSave
Killed by : none
removed call to java/util/zip/ZipOutputStream::putNextEntry → NO_COVERAGE

153

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

2.2
Location : doSave
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

3.3
Location : doSave
Killed by : none
negated conditional → NO_COVERAGE

156

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

163

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

166

1.1
Location : doSave
Killed by : none
removed call to java/util/zip/ZipOutputStream::close → NO_COVERAGE

168

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

172

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

175

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

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

178

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

185

1.1
Location : doSave
Killed by : none
removed call to java/io/OutputStream::close → NO_COVERAGE

190

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

202

1.1
Location : doSave
Killed by : none
removed call to java/io/OutputStream::close → NO_COVERAGE

231

1.1
Location : doLoad
Killed by : none
removed call to org/xml/sax/InputSource::setSystemId → NO_COVERAGE

236

1.1
Location : doLoad
Killed by : none
removed call to org/argouml/persistence/ModelMemberFilePersister::readModels → NO_COVERAGE

239

1.1
Location : doLoad
Killed by : none
removed call to org/argouml/model/UmlHelper::addListenersToModel → NO_COVERAGE

240

1.1
Location : doLoad
Killed by : none
removed call to org/argouml/kernel/Project::setUUIDRefs → NO_COVERAGE

241

1.1
Location : doLoad
Killed by : none
removed call to org/argouml/kernel/Project::addMember → NO_COVERAGE

242

1.1
Location : doLoad
Killed by : none
removed call to org/argouml/persistence/ZipFilePersister::parseXmiExtensions → NO_COVERAGE

243

1.1
Location : doLoad
Killed by : none
removed call to org/argouml/persistence/ModelMemberFilePersister::registerDiagrams → NO_COVERAGE

245

1.1
Location : doLoad
Killed by : none
removed call to org/argouml/kernel/Project::setRoot → NO_COVERAGE

246

1.1
Location : doLoad
Killed by : none
removed call to org/argouml/kernel/Project::setRoots → NO_COVERAGE

247

1.1
Location : doLoad
Killed by : none
removed call to org/argouml/kernel/ProjectManager::setSaveEnabled → NO_COVERAGE

248

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

270

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

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

273

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

283

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

Active mutators

Tests examined


Report generated by PIT 0.32