Coverage Report - org.argouml.persistence.ZipFilePersister
 
Classes in this File Line Coverage Branch Coverage Complexity
ZipFilePersister
7%
6/77
0%
0/18
3.5
 
 1  
 /* $Id: ZipFilePersister.java 18968 2011-01-13 14:39:23Z tfmorris $
 2  
  *****************************************************************************
 3  
  * Copyright (c) 2009 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  
  *****************************************************************************
 12  
  *
 13  
  * Some portions of this file was previously release using the BSD License:
 14  
  */
 15  
 
 16  
 // Copyright (c) 1996-2008 The Regents of the University of California. All
 17  
 // Rights Reserved. Permission to use, copy, modify, and distribute this
 18  
 // software and its documentation without fee, and without a written
 19  
 // agreement is hereby granted, provided that the above copyright notice
 20  
 // and this paragraph appear in all copies.  This software program and
 21  
 // documentation are copyrighted by The Regents of the University of
 22  
 // California. The software program and documentation are supplied "AS
 23  
 // IS", without any accompanying services from The Regents. The Regents
 24  
 // does not warrant that the operation of the program will be
 25  
 // uninterrupted or error-free. The end-user understands that the program
 26  
 // was developed for research purposes and is advised not to rely
 27  
 // exclusively on the program for any reason.  IN NO EVENT SHALL THE
 28  
 // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
 29  
 // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
 30  
 // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
 31  
 // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
 32  
 // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
 33  
 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 34  
 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
 35  
 // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
 36  
 // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
 37  
 // UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 38  
 
 39  
 package org.argouml.persistence;
 40  
 
 41  
 import java.io.BufferedOutputStream;
 42  
 import java.io.File;
 43  
 import java.io.FileNotFoundException;
 44  
 import java.io.FileOutputStream;
 45  
 import java.io.IOException;
 46  
 import java.io.InputStream;
 47  
 import java.io.OutputStream;
 48  
 import java.net.URL;
 49  
 import java.util.zip.ZipEntry;
 50  
 import java.util.zip.ZipInputStream;
 51  
 import java.util.zip.ZipOutputStream;
 52  
 
 53  
 import org.apache.log4j.Logger;
 54  
 import org.argouml.i18n.Translator;
 55  
 import org.argouml.kernel.Project;
 56  
 import org.argouml.kernel.ProjectFactory;
 57  
 import org.argouml.kernel.ProjectManager;
 58  
 import org.argouml.kernel.ProjectMember;
 59  
 import org.argouml.model.Model;
 60  
 import org.xml.sax.InputSource;
 61  
 
 62  
 /**
 63  
  * To persist to and from zipped xmi file storage.
 64  
  *
 65  
  * @author Bob Tarling
 66  
  * @author Ludovic Maître
 67  
  */
 68  
 class ZipFilePersister extends XmiFilePersister {
 69  
     /**
 70  
      * Logger.
 71  
      */
 72  900
     private static final Logger LOG =
 73  
         Logger.getLogger(ZipFilePersister.class);
 74  
 
 75  
     /**
 76  
      * The constructor.
 77  
      */
 78  900
     public ZipFilePersister() {
 79  900
     }
 80  
 
 81  
     /*
 82  
      * @see org.argouml.persistence.AbstractFilePersister#getExtension()
 83  
      */
 84  
     public String getExtension() {
 85  9833
         return "zip";
 86  
     }
 87  
 
 88  
     /*
 89  
      * @see org.argouml.persistence.AbstractFilePersister#getDesc()
 90  
      */
 91  
     protected String getDesc() {
 92  126
         return Translator.localize("combobox.filefilter.zip");
 93  
     }
 94  
     
 95  
     /*
 96  
      * @see org.argouml.persistence.XmiFilePersister#isSaveEnabled()
 97  
      */
 98  
     public boolean isSaveEnabled() {
 99  5
         return true;
 100  
     }
 101  
 
 102  
     /**
 103  
      * It is being considered to save out individual xmi's from individuals
 104  
      * diagrams to make it easier to modularize the output of Argo.
 105  
      *
 106  
      * @param file
 107  
      *            The file to write.
 108  
      * @param project
 109  
      *            the project to save
 110  
      * @throws SaveException
 111  
      *             when anything goes wrong
 112  
      *
 113  
      * @see org.argouml.persistence.ProjectFilePersister#save(
 114  
      *      org.argouml.kernel.Project, java.io.File)
 115  
      */
 116  
     public void doSave(Project project, File file) throws SaveException {
 117  
 
 118  0
         LOG.info("Receiving file '" + file.getName() + "'");
 119  
 
 120  0
         File lastArchiveFile = new File(file.getAbsolutePath() + "~");
 121  0
         File tempFile = null;
 122  
 
 123  
         try {
 124  0
             tempFile = createTempFile(file);
 125  0
         } catch (FileNotFoundException e) {
 126  0
             throw new SaveException(
 127  
                     "Failed to archive the previous file version", e);
 128  0
         } catch (IOException e) {
 129  0
             throw new SaveException(
 130  
                     "Failed to archive the previous file version", e);
 131  0
         }
 132  
 
 133  0
         OutputStream bufferedStream = null;
 134  
         try {
 135  
             //project.setFile(file);
 136  
 
 137  0
             ZipOutputStream stream =
 138  
                 new ZipOutputStream(new FileOutputStream(file));
 139  0
             String fileName = file.getName();
 140  0
             ZipEntry xmiEntry =
 141  
                 new ZipEntry(fileName.substring(0, fileName.lastIndexOf(".")));
 142  0
             stream.putNextEntry(xmiEntry);
 143  0
             bufferedStream = new BufferedOutputStream(stream);
 144  
 
 145  0
             int size = project.getMembers().size();
 146  0
             for (int i = 0; i < size; i++) {
 147  0
                 ProjectMember projectMember =
 148  
                     project.getMembers().get(i);
 149  0
                 if (projectMember.getType().equalsIgnoreCase("xmi")) {
 150  0
                     if (LOG.isInfoEnabled()) {
 151  0
                         LOG.info("Saving member of type: "
 152  
                               + (project.getMembers()
 153  
                                     .get(i)).getType());
 154  
                     }
 155  0
                     MemberFilePersister persister
 156  
                         = new ModelMemberFilePersister();
 157  0
                     persister.save(projectMember, bufferedStream);
 158  
                 }
 159  
             }
 160  0
             stream.close();
 161  
             // if save did not raise an exception
 162  
             // and name+"#" exists move name+"#" to name+"~"
 163  
             // this is the correct backup file
 164  0
             if (lastArchiveFile.exists()) {
 165  0
                 lastArchiveFile.delete();
 166  
             }
 167  0
             if (tempFile.exists() && !lastArchiveFile.exists()) {
 168  0
                 tempFile.renameTo(lastArchiveFile);
 169  
             }
 170  0
             if (tempFile.exists()) {
 171  0
                 tempFile.delete();
 172  
             }
 173  0
         } catch (Exception e) {
 174  0
             LOG.error("Exception occured during save attempt", e);
 175  
             try {
 176  0
                 bufferedStream.close();
 177  0
             } catch (IOException ex) {
 178  
                 // If we get a 2nd error, just ignore it
 179  0
             }
 180  
 
 181  
             // frank: in case of exception
 182  
             // delete name and mv name+"#" back to name if name+"#" exists
 183  
             // this is the "rollback" to old file
 184  0
             file.delete();
 185  0
             tempFile.renameTo(file);
 186  
             // we have to give a message to user and set the system to unsaved!
 187  0
             throw new SaveException(e);
 188  0
         }
 189  
 
 190  
         try {
 191  0
             bufferedStream.close();
 192  0
         } catch (IOException ex) {
 193  0
             LOG.error("Failed to close save output writer", ex);
 194  0
         }
 195  0
     }
 196  
 
 197  
     /*
 198  
      * @see org.argouml.persistence.ProjectFilePersister#doLoad(java.io.File)
 199  
      */
 200  
     public Project doLoad(File file)
 201  
         throws OpenException {
 202  
 
 203  0
         LOG.info("Receiving file '" + file.getName() + "'");
 204  
 
 205  
         try {
 206  0
             Project p = ProjectFactory.getInstance().createProject();
 207  0
             String fileName = file.getName();
 208  0
             String extension =
 209  
                 fileName.substring(
 210  
                         fileName.indexOf('.'),
 211  
                         fileName.lastIndexOf('.'));
 212  0
             InputStream stream = openZipStreamAt(file.toURI().toURL(),
 213  
                     extension);
 214  
 
 215  
             // TODO: What progressMgr is to be used here? Where does
 216  
             //       it come from?
 217  0
             InputSource is =
 218  
                 new InputSource(
 219  
                     new XmiInputStream(stream, this, 100000, null));
 220  0
             is.setSystemId(file.toURI().toURL().toExternalForm());
 221  
 
 222  0
             ModelMemberFilePersister modelPersister =
 223  
                 new ModelMemberFilePersister();
 224  
             
 225  0
             modelPersister.readModels(is);
 226  
             // TODO Handle multiple top level packages
 227  0
             Object model = modelPersister.getCurModel();
 228  0
             Model.getUmlHelper().addListenersToModel(model);
 229  0
             p.setUUIDRefs(modelPersister.getUUIDRefs());
 230  0
             p.addMember(model);
 231  0
             parseXmiExtensions(p);
 232  0
             modelPersister.registerDiagrams(p);
 233  
 
 234  0
             p.setRoot(model);
 235  0
             p.setRoots(modelPersister.getElementsRead());
 236  0
             ProjectManager.getManager().setSaveEnabled(false);
 237  0
             return p;
 238  0
         } catch (IOException e) {
 239  0
             throw new OpenException(e);
 240  
         }
 241  
 
 242  
     }
 243  
 
 244  
     /**
 245  
      * Open a ZipInputStream to the first file found with a given extension.
 246  
      *
 247  
      * @param url
 248  
      *            The URL of the zip file.
 249  
      * @param ext
 250  
      *            The required extension.
 251  
      * @return the zip stream positioned at the required location.
 252  
      * @throws IOException
 253  
      *             if there is a problem opening the file.
 254  
      */
 255  
     private ZipInputStream openZipStreamAt(URL url, String ext)
 256  
         throws IOException {
 257  0
         ZipInputStream zis = new ZipInputStream(url.openStream());
 258  0
         ZipEntry entry = zis.getNextEntry();
 259  0
         while (entry != null && !entry.getName().endsWith(ext)) {
 260  0
             entry = zis.getNextEntry();
 261  
         }
 262  0
         return zis;
 263  
     }
 264  
 
 265  
     /**
 266  
      * Returns false. Only Argo specific files have an icon.
 267  
      * 
 268  
      * @see org.argouml.persistence.AbstractFilePersister#hasAnIcon()
 269  
      */
 270  
     @Override
 271  
     public boolean hasAnIcon() {
 272  0
         return false;
 273  
     }
 274  
 }