Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
OldZargoFilePersister |
|
| 4.8;4.8 |
1 | /* $Id: OldZargoFilePersister.java 17832 2010-01-12 19:02:29Z linus $ | |
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.BufferedWriter; | |
42 | import java.io.File; | |
43 | import java.io.FileNotFoundException; | |
44 | import java.io.FileOutputStream; | |
45 | import java.io.IOException; | |
46 | import java.io.OutputStreamWriter; | |
47 | import java.util.ArrayList; | |
48 | import java.util.Collection; | |
49 | import java.util.Hashtable; | |
50 | import java.util.zip.ZipEntry; | |
51 | import java.util.zip.ZipOutputStream; | |
52 | ||
53 | import org.apache.log4j.Logger; | |
54 | import org.argouml.application.helpers.ApplicationVersion; | |
55 | import org.argouml.i18n.Translator; | |
56 | import org.argouml.kernel.Project; | |
57 | import org.argouml.kernel.ProjectMember; | |
58 | import org.argouml.ocl.OCLExpander; | |
59 | import org.argouml.util.FileConstants; | |
60 | import org.tigris.gef.ocl.TemplateReader; | |
61 | ||
62 | /** | |
63 | * To persist to and from zargo (zipped file) storage containing seperate | |
64 | * xmi, argo, plgml and todo zip entries. | |
65 | * @author Bob Tarling | |
66 | * TODO: Review use of this against ZargoFilePersister - Bob | |
67 | */ | |
68 | class OldZargoFilePersister extends ZargoFilePersister { | |
69 | /** | |
70 | * Logger. | |
71 | */ | |
72 | 900 | private static final Logger LOG = |
73 | Logger.getLogger(OldZargoFilePersister.class); | |
74 | ||
75 | /** | |
76 | * This is the old version of the ArgoUML tee file which does not contain | |
77 | * the detail of member elements. | |
78 | */ | |
79 | private static final String ARGO_MINI_TEE = | |
80 | "/org/argouml/persistence/argo.tee"; | |
81 | ||
82 | /** | |
83 | * The constructor. | |
84 | */ | |
85 | 900 | public OldZargoFilePersister() { |
86 | 900 | } |
87 | ||
88 | /* | |
89 | * @see org.argouml.persistence.AbstractFilePersister#getDesc() | |
90 | */ | |
91 | protected String getDesc() { | |
92 | 293 | return Translator.localize("combobox.filefilter.zargo"); |
93 | } | |
94 | ||
95 | /* | |
96 | * @see org.argouml.persistence.AbstractFilePersister#isSaveEnabled() | |
97 | */ | |
98 | public boolean isSaveEnabled() { | |
99 | 0 | 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 | * @throws InterruptedException if the thread is interrupted | |
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 | InterruptedException { | |
119 | ||
120 | 0 | ProgressMgr progressMgr = new ProgressMgr(); |
121 | 0 | progressMgr.setNumberOfPhases(4); |
122 | 0 | progressMgr.nextPhase(); |
123 | ||
124 | 0 | File lastArchiveFile = new File(file.getAbsolutePath() + "~"); |
125 | 0 | File tempFile = null; |
126 | ||
127 | try { | |
128 | 0 | tempFile = createTempFile(file); |
129 | 0 | } catch (FileNotFoundException e) { |
130 | 0 | throw new SaveException( |
131 | "Failed to archive the previous file version", e); | |
132 | 0 | } catch (IOException e) { |
133 | 0 | throw new SaveException( |
134 | "Failed to archive the previous file version", e); | |
135 | 0 | } |
136 | ||
137 | 0 | BufferedWriter writer = null; |
138 | try { | |
139 | ||
140 | 0 | project.setFile(file); |
141 | 0 | project.setVersion(ApplicationVersion.getVersion()); |
142 | 0 | project.setPersistenceVersion(PERSISTENCE_VERSION); |
143 | ||
144 | 0 | ZipOutputStream stream = |
145 | new ZipOutputStream(new FileOutputStream(file)); | |
146 | 0 | writer = |
147 | new BufferedWriter(new OutputStreamWriter(stream, "UTF-8")); | |
148 | ||
149 | // Save the .argo entry | |
150 | // TODO: Cyclic dependency with PersistenceManager | |
151 | // move PersistenceManager..getProjectBaseName() someplace else | |
152 | 0 | ZipEntry zipEntry = |
153 | new ZipEntry(PersistenceManager.getInstance() | |
154 | .getProjectBaseName(project) | |
155 | + FileConstants.UNCOMPRESSED_FILE_EXT); | |
156 | 0 | stream.putNextEntry(zipEntry); |
157 | ||
158 | 0 | Hashtable templates = |
159 | TemplateReader.getInstance().read(ARGO_MINI_TEE); | |
160 | 0 | OCLExpander expander = new OCLExpander(templates); |
161 | 0 | expander.expand(writer, project); |
162 | ||
163 | 0 | writer.flush(); |
164 | ||
165 | 0 | stream.closeEntry(); |
166 | ||
167 | 0 | int counter = 0; |
168 | 0 | int size = project.getMembers().size(); |
169 | 0 | Collection<String> names = new ArrayList<String>(); |
170 | 0 | for (int i = 0; i < size; i++) { |
171 | 0 | ProjectMember projectMember = project.getMembers().get(i); |
172 | 0 | if (!(projectMember.getType().equalsIgnoreCase("xmi"))) { |
173 | 0 | if (LOG.isInfoEnabled()) { |
174 | 0 | LOG.info("Saving member: " |
175 | + project.getMembers().get(i).getZipName()); | |
176 | } | |
177 | 0 | String name = projectMember.getZipName(); |
178 | 0 | String originalName = name; |
179 | 0 | while (names.contains(name)) { |
180 | /* Issue 4806 explains why we need this! */ | |
181 | 0 | name = ++counter + originalName; |
182 | } | |
183 | 0 | names.add(name); |
184 | 0 | stream.putNextEntry(new ZipEntry(name)); |
185 | 0 | MemberFilePersister persister = |
186 | getMemberFilePersister(projectMember); | |
187 | 0 | persister.save(projectMember, stream); |
188 | 0 | stream.flush(); |
189 | 0 | stream.closeEntry(); |
190 | } | |
191 | } | |
192 | ||
193 | 0 | for (int i = 0; i < size; i++) { |
194 | 0 | ProjectMember projectMember = project.getMembers().get(i); |
195 | 0 | if (projectMember.getType().equalsIgnoreCase("xmi")) { |
196 | 0 | if (LOG.isInfoEnabled()) { |
197 | 0 | LOG.info("Saving member of type: " |
198 | + project.getMembers().get(i).getType()); | |
199 | } | |
200 | 0 | stream.putNextEntry( |
201 | new ZipEntry(projectMember.getZipName())); | |
202 | 0 | OldModelMemberFilePersister persister = |
203 | new OldModelMemberFilePersister(); | |
204 | 0 | persister.save(projectMember, stream); |
205 | 0 | stream.flush(); |
206 | } | |
207 | } | |
208 | ||
209 | ||
210 | ||
211 | // if save did not raise an exception | |
212 | // and name+"#" exists move name+"#" to name+"~" | |
213 | // this is the correct backup file | |
214 | 0 | if (lastArchiveFile.exists()) { |
215 | 0 | lastArchiveFile.delete(); |
216 | } | |
217 | 0 | if (tempFile.exists() && !lastArchiveFile.exists()) { |
218 | 0 | tempFile.renameTo(lastArchiveFile); |
219 | } | |
220 | 0 | if (tempFile.exists()) { |
221 | 0 | tempFile.delete(); |
222 | } | |
223 | ||
224 | 0 | progressMgr.nextPhase(); |
225 | ||
226 | 0 | } catch (Exception e) { |
227 | 0 | LOG.error("Exception occured during save attempt", e); |
228 | try { | |
229 | 0 | writer.close(); |
230 | 0 | } catch (Exception ex) { |
231 | // Do nothing. | |
232 | 0 | } |
233 | ||
234 | // frank: in case of exception | |
235 | // delete name and mv name+"#" back to name if name+"#" exists | |
236 | // this is the "rollback" to old file | |
237 | 0 | file.delete(); |
238 | 0 | tempFile.renameTo(file); |
239 | // we have to give a message to user and set the system to unsaved! | |
240 | 0 | throw new SaveException(e); |
241 | 0 | } |
242 | ||
243 | try { | |
244 | 0 | writer.close(); |
245 | 0 | } catch (IOException ex) { |
246 | 0 | LOG.error("Failed to close save output writer", ex); |
247 | 0 | } |
248 | 0 | } |
249 | ||
250 | /** | |
251 | * The .zargo save format is able to save. We must override | |
252 | * UmlFilePersister which has turned this off (suggests a need for some | |
253 | * refactoring here) | |
254 | * @see org.argouml.persistence.AbstractFilePersister#isSaveEnabled() | |
255 | * | |
256 | * @return boolean | |
257 | */ | |
258 | public boolean isLoadEnabled() { | |
259 | 0 | return false; |
260 | } | |
261 | } |