1 | /* $Id: UmlFilePersister.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 | * Bob Tarling | |
11 | * Thomas Neustupny | |
12 | * Michiel van der Wulp | |
13 | ***************************************************************************** | |
14 | * | |
15 | * Some portions of this file was previously release using the BSD License: | |
16 | */ | |
17 | ||
18 | // Copyright (c) 1996-2009 The Regents of the University of California. All | |
19 | // Rights Reserved. Permission to use, copy, modify, and distribute this | |
20 | // software and its documentation without fee, and without a written | |
21 | // agreement is hereby granted, provided that the above copyright notice | |
22 | // and this paragraph appear in all copies. This software program and | |
23 | // documentation are copyrighted by The Regents of the University of | |
24 | // California. The software program and documentation are supplied "AS | |
25 | // IS", without any accompanying services from The Regents. The Regents | |
26 | // does not warrant that the operation of the program will be | |
27 | // uninterrupted or error-free. The end-user understands that the program | |
28 | // was developed for research purposes and is advised not to rely | |
29 | // exclusively on the program for any reason. IN NO EVENT SHALL THE | |
30 | // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, | |
31 | // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, | |
32 | // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF | |
33 | // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF | |
34 | // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY | |
35 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
36 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE | |
37 | // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF | |
38 | // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, | |
39 | // UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | |
40 | package org.argouml.persistence; | |
41 | ||
42 | import java.io.BufferedInputStream; | |
43 | import java.io.BufferedReader; | |
44 | import java.io.BufferedWriter; | |
45 | import java.io.File; | |
46 | import java.io.FileNotFoundException; | |
47 | import java.io.FileOutputStream; | |
48 | import java.io.FilterOutputStream; | |
49 | import java.io.IOException; | |
50 | import java.io.InputStream; | |
51 | import java.io.InputStreamReader; | |
52 | import java.io.OutputStream; | |
53 | import java.io.OutputStreamWriter; | |
54 | import java.io.PrintWriter; | |
55 | import java.io.Reader; | |
56 | import java.io.UnsupportedEncodingException; | |
57 | import java.io.Writer; | |
58 | import java.net.MalformedURLException; | |
59 | import java.net.URL; | |
60 | import java.nio.ByteBuffer; | |
61 | import java.nio.CharBuffer; | |
62 | import java.nio.charset.Charset; | |
63 | import java.nio.charset.CharsetDecoder; | |
64 | import java.nio.charset.CoderResult; | |
65 | import java.nio.charset.CodingErrorAction; | |
66 | import java.util.Hashtable; | |
67 | import java.util.List; | |
68 | import java.util.logging.Level; | |
69 | import java.util.logging.Logger; | |
70 | import java.util.regex.Matcher; | |
71 | import java.util.regex.Pattern; | |
72 | ||
73 | import javax.xml.transform.Result; | |
74 | import javax.xml.transform.Transformer; | |
75 | import javax.xml.transform.TransformerException; | |
76 | import javax.xml.transform.TransformerFactory; | |
77 | import javax.xml.transform.stream.StreamResult; | |
78 | import javax.xml.transform.stream.StreamSource; | |
79 | ||
80 | import org.argouml.application.api.Argo; | |
81 | import org.argouml.application.helpers.ApplicationVersion; | |
82 | import org.argouml.i18n.Translator; | |
83 | import org.argouml.kernel.Project; | |
84 | import org.argouml.kernel.ProjectFactory; | |
85 | import org.argouml.kernel.ProjectMember; | |
86 | import org.argouml.model.UmlException; | |
87 | import org.argouml.util.ThreadUtils; | |
88 | import org.tigris.gef.ocl.ExpansionException; | |
89 | import org.tigris.gef.ocl.OCLExpander; | |
90 | import org.tigris.gef.ocl.TemplateReader; | |
91 | import org.xml.sax.InputSource; | |
92 | import org.xml.sax.SAXException; | |
93 | ||
94 | /** | |
95 | * To persist to and from argo (xml file) storage. | |
96 | * | |
97 | * @author Bob Tarling | |
98 | */ | |
99 | public class UmlFilePersister extends AbstractFilePersister { | |
100 | ||
101 | /** | |
102 | * The PERSISTENCE_VERSION is increased every time the persistence format | |
103 | * changes. This controls conversion of old persistence version files to be | |
104 | * converted to the current one, keeping ArgoUML backwards compatible. | |
105 | */ | |
106 | public static final int PERSISTENCE_VERSION = 6; | |
107 | ||
108 | /** | |
109 | * The TOTAL_PHASES_LOAD constant is the number of phases used by the load | |
110 | * process. | |
111 | */ | |
112 | protected static final int UML_PHASES_LOAD = 2; | |
113 | ||
114 | /** | |
115 | * Logger. | |
116 | */ | |
117 | private static final Logger LOG = | |
118 | Logger.getLogger(UmlFilePersister.class.getName()); | |
119 | ||
120 | private static final String ARGO_TEE = "/org/argouml/persistence/argo.tee"; | |
121 | ||
122 | /** | |
123 | * The constructor. | |
124 | */ | |
125 | public UmlFilePersister() { | |
126 | } | |
127 | ||
128 | /* | |
129 | * @see org.argouml.persistence.AbstractFilePersister#getExtension() | |
130 | */ | |
131 | public String getExtension() { | |
132 |
1
1. getExtension : mutated return of Object value for org/argouml/persistence/UmlFilePersister::getExtension to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return "uml"; |
133 | } | |
134 | ||
135 | /* | |
136 | * @see org.argouml.persistence.AbstractFilePersister#getDesc() | |
137 | */ | |
138 | protected String getDesc() { | |
139 |
1
1. getDesc : mutated return of Object value for org/argouml/persistence/UmlFilePersister::getDesc to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return Translator.localize("combobox.filefilter.uml"); |
140 | } | |
141 | ||
142 | /** | |
143 | * Save the project in ".uml" format. | |
144 | * | |
145 | * @param file The file to write. | |
146 | * @param project the project to save | |
147 | * @throws SaveException when anything goes wrong | |
148 | * @throws InterruptedException if the thread is interrupted | |
149 | * | |
150 | * @see org.argouml.persistence.ProjectFilePersister#save(org.argouml.kernel.Project, | |
151 | * java.io.File) | |
152 | */ | |
153 | public void doSave(Project project, File file) throws SaveException, | |
154 | InterruptedException { | |
155 | ||
156 | /* Retain the previous project file even when the save operation | |
157 | * crashes in the middle. Also create a backup file after saving. */ | |
158 | boolean doSafeSaves = useSafeSaves(); | |
159 | ||
160 | ProgressMgr progressMgr = new ProgressMgr(); | |
161 |
1
1. doSave : removed call to org/argouml/persistence/AbstractFilePersister$ProgressMgr::setNumberOfPhases → NO_COVERAGE |
progressMgr.setNumberOfPhases(4); |
162 |
1
1. doSave : removed call to org/argouml/persistence/AbstractFilePersister$ProgressMgr::nextPhase → NO_COVERAGE |
progressMgr.nextPhase(); |
163 | ||
164 | File lastArchiveFile = new File(file.getAbsolutePath() + "~"); | |
165 | File tempFile = null; | |
166 | ||
167 |
1
1. doSave : negated conditional → NO_COVERAGE |
if (doSafeSaves) { |
168 | try { | |
169 | tempFile = createTempFile(file); | |
170 | } catch (FileNotFoundException e) { | |
171 | throw new SaveException(Translator.localize( | |
172 | "optionpane.save-project-exception-cause1"), e); | |
173 | } catch (IOException e) { | |
174 | throw new SaveException(Translator.localize( | |
175 | "optionpane.save-project-exception-cause2"), e); | |
176 | } | |
177 | } | |
178 | ||
179 | try { | |
180 |
1
1. doSave : removed call to org/argouml/kernel/Project::setFile → NO_COVERAGE |
project.setFile(file); |
181 |
1
1. doSave : removed call to org/argouml/kernel/Project::setVersion → NO_COVERAGE |
project.setVersion(ApplicationVersion.getVersion()); |
182 |
1
1. doSave : removed call to org/argouml/kernel/Project::setPersistenceVersion → NO_COVERAGE |
project.setPersistenceVersion(PERSISTENCE_VERSION); |
183 | ||
184 | OutputStream stream = new FileOutputStream(file); | |
185 | ||
186 |
1
1. doSave : removed call to org/argouml/persistence/UmlFilePersister::writeProject → NO_COVERAGE |
writeProject(project, stream, progressMgr); |
187 | ||
188 |
1
1. doSave : removed call to java/io/OutputStream::close → NO_COVERAGE |
stream.close(); |
189 | ||
190 |
1
1. doSave : removed call to org/argouml/persistence/AbstractFilePersister$ProgressMgr::nextPhase → NO_COVERAGE |
progressMgr.nextPhase(); |
191 | ||
192 | String path = file.getParent(); | |
193 | ||
194 | LOG.log(Level.INFO, "Dir == {0}", path); | |
195 | ||
196 |
1
1. doSave : negated conditional → NO_COVERAGE |
if (doSafeSaves) { |
197 | // if save did not raise an exception | |
198 | // and name+"#" exists move name+"#" to name+"~" | |
199 | // this is the correct backup file | |
200 |
1
1. doSave : negated conditional → NO_COVERAGE |
if (lastArchiveFile.exists()) { |
201 | lastArchiveFile.delete(); | |
202 | } | |
203 |
2
1. doSave : negated conditional → NO_COVERAGE 2. doSave : negated conditional → NO_COVERAGE |
if (tempFile.exists() && !lastArchiveFile.exists()) { |
204 | tempFile.renameTo(lastArchiveFile); | |
205 | } | |
206 |
1
1. doSave : negated conditional → NO_COVERAGE |
if (tempFile.exists()) { |
207 | tempFile.delete(); | |
208 | } | |
209 | } | |
210 | ||
211 |
1
1. doSave : removed call to org/argouml/persistence/AbstractFilePersister$ProgressMgr::nextPhase → NO_COVERAGE |
progressMgr.nextPhase(); |
212 | ||
213 | } catch (Exception e) { | |
214 | LOG.log(Level.SEVERE, "Exception occured during save attempt", e); | |
215 | ||
216 |
1
1. doSave : negated conditional → NO_COVERAGE |
if (doSafeSaves) { |
217 | // frank: in case of exception | |
218 | // delete name and mv name+"#" back to name if name+"#" exists | |
219 | // this is the "rollback" to old file | |
220 | file.delete(); | |
221 | tempFile.renameTo(file); | |
222 | } | |
223 |
1
1. doSave : negated conditional → NO_COVERAGE |
if (e instanceof InterruptedException) { |
224 | throw (InterruptedException) e; | |
225 | } else { | |
226 | // we have to give a message to user and set the system | |
227 | // to unsaved! | |
228 | throw new SaveException(e); | |
229 | } | |
230 | } | |
231 | } | |
232 | ||
233 | /** | |
234 | * The .uml save format is no longer available to save. | |
235 | * | |
236 | * {@inheritDoc} | |
237 | */ | |
238 | @Override | |
239 | public boolean isSaveEnabled() { | |
240 |
1
1. isSaveEnabled : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return true; |
241 | } | |
242 | ||
243 | /** | |
244 | * Write the output for a project on the given stream. | |
245 | * | |
246 | * @param project The project to output. | |
247 | * @param stream The stream to write to. | |
248 | * @throws SaveException If something goes wrong. | |
249 | * @throws InterruptedException if the thread is interrupted | |
250 | */ | |
251 | void writeProject(Project project, OutputStream oStream, | |
252 | ProgressMgr progressMgr) throws SaveException, InterruptedException { | |
253 | OutputStreamWriter outputStreamWriter; | |
254 | try { | |
255 | outputStreamWriter = new OutputStreamWriter(oStream, Argo | |
256 | .getEncoding()); | |
257 | } catch (UnsupportedEncodingException e) { | |
258 | throw new SaveException(e); | |
259 | } | |
260 | PrintWriter writer = new PrintWriter(new BufferedWriter( | |
261 | outputStreamWriter)); | |
262 | ||
263 | XmlFilterOutputStream filteredStream = new XmlFilterOutputStream( | |
264 | oStream, Argo.getEncoding()); | |
265 | try { | |
266 |
1
1. writeProject : removed call to java/io/PrintWriter::println → NO_COVERAGE |
writer.println("<?xml version = \"1.0\" " + "encoding = \"" |
267 | + Argo.getEncoding() + "\" ?>"); | |
268 |
1
1. writeProject : removed call to java/io/PrintWriter::println → NO_COVERAGE |
writer.println("<uml version=\"" + PERSISTENCE_VERSION + "\">"); |
269 | // Write out header section | |
270 | try { | |
271 | Hashtable templates = TemplateReader.getInstance().read( | |
272 | ARGO_TEE); | |
273 | OCLExpander expander = new OCLExpander(templates); | |
274 |
1
1. writeProject : removed call to org/tigris/gef/ocl/OCLExpander::expand → NO_COVERAGE |
expander.expand(writer, project, " "); |
275 | } catch (ExpansionException e) { | |
276 | throw new SaveException(e); | |
277 | } | |
278 |
1
1. writeProject : removed call to java/io/PrintWriter::flush → NO_COVERAGE |
writer.flush(); |
279 | ||
280 |
1
1. writeProject : negated conditional → NO_COVERAGE |
if (progressMgr != null) { |
281 |
1
1. writeProject : removed call to org/argouml/persistence/AbstractFilePersister$ProgressMgr::nextPhase → NO_COVERAGE |
progressMgr.nextPhase(); |
282 | } | |
283 | ||
284 | // Note we assume members are ordered correctly already | |
285 |
1
1. writeProject : negated conditional → NO_COVERAGE |
for (ProjectMember projectMember : project.getMembers()) { |
286 | ||
287 | LOG.log(Level.INFO, "Saving member: {0}", projectMember); | |
288 | ||
289 | MemberFilePersister persister = getMemberFilePersister(projectMember); | |
290 |
1
1. writeProject : removed call to org/argouml/persistence/UmlFilePersister$XmlFilterOutputStream::startEntry → NO_COVERAGE |
filteredStream.startEntry(); |
291 |
1
1. writeProject : removed call to org/argouml/persistence/MemberFilePersister::save → NO_COVERAGE |
persister.save(projectMember, filteredStream); |
292 | try { | |
293 |
1
1. writeProject : removed call to org/argouml/persistence/UmlFilePersister$XmlFilterOutputStream::flush → NO_COVERAGE |
filteredStream.flush(); |
294 | } catch (IOException e) { | |
295 | throw new SaveException(e); | |
296 | } | |
297 | } | |
298 | ||
299 |
1
1. writeProject : removed call to java/io/PrintWriter::println → NO_COVERAGE |
writer.println("</uml>"); |
300 | ||
301 |
1
1. writeProject : removed call to java/io/PrintWriter::flush → NO_COVERAGE |
writer.flush(); |
302 | } finally { | |
303 |
2
1. writeProject : removed call to java/io/PrintWriter::close → NO_COVERAGE 2. writeProject : removed call to java/io/PrintWriter::close → NO_COVERAGE |
writer.close(); |
304 | try { | |
305 |
2
1. writeProject : removed call to org/argouml/persistence/UmlFilePersister$XmlFilterOutputStream::reallyClose → NO_COVERAGE 2. writeProject : removed call to org/argouml/persistence/UmlFilePersister$XmlFilterOutputStream::reallyClose → NO_COVERAGE |
filteredStream.reallyClose(); |
306 | } catch (IOException e) { | |
307 | throw new SaveException(e); | |
308 | } | |
309 | } | |
310 | } | |
311 | ||
312 | /* | |
313 | * @see org.argouml.persistence.ProjectFilePersister#doLoad(java.io.File) | |
314 | */ | |
315 | public Project doLoad(File file) throws OpenException, InterruptedException { | |
316 | // let's initialize the progressMgr | |
317 | ProgressMgr progressMgr = new ProgressMgr(); | |
318 |
1
1. doLoad : removed call to org/argouml/persistence/AbstractFilePersister$ProgressMgr::setNumberOfPhases → NO_COVERAGE |
progressMgr.setNumberOfPhases(UML_PHASES_LOAD); |
319 | ||
320 |
1
1. doLoad : removed call to org/argouml/util/ThreadUtils::checkIfInterrupted → NO_COVERAGE |
ThreadUtils.checkIfInterrupted(); |
321 |
1
1. doLoad : mutated return of Object value for org/argouml/persistence/UmlFilePersister::doLoad to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return doLoad(file, file, progressMgr); |
322 | } | |
323 | ||
324 | protected Project doLoad(File originalFile, File file, | |
325 | ProgressMgr progressMgr) throws OpenException, InterruptedException { | |
326 | ||
327 | XmlInputStream inputStream = null; | |
328 | try { | |
329 | Project p = ProjectFactory.getInstance() | |
330 | .createProject(file.toURI()); | |
331 | ||
332 | // Run through any stylesheet upgrades | |
333 | int fileVersion = getPersistenceVersionFromFile(file); | |
334 | ||
335 | LOG.log(Level.INFO, "Loading uml file of version {0}", fileVersion); | |
336 |
1
1. doLoad : negated conditional → NO_COVERAGE |
if (!checkVersion(fileVersion, getReleaseVersionFromFile(file))) { |
337 | // If we're about to upgrade the file lets take an archive | |
338 | // of it first. | |
339 | String release = getReleaseVersionFromFile(file); | |
340 | copyFile(originalFile, new File(originalFile.getAbsolutePath() | |
341 | + '~' + release)); | |
342 | ||
343 |
1
1. doLoad : removed call to org/argouml/persistence/AbstractFilePersister$ProgressMgr::setNumberOfPhases → NO_COVERAGE |
progressMgr.setNumberOfPhases(progressMgr.getNumberOfPhases() |
344 |
2
1. doLoad : Replaced integer subtraction with addition → NO_COVERAGE 2. doLoad : Replaced integer addition with subtraction → NO_COVERAGE |
+ (PERSISTENCE_VERSION - fileVersion)); |
345 | ||
346 |
2
1. doLoad : changed conditional boundary → NO_COVERAGE 2. doLoad : negated conditional → NO_COVERAGE |
while (fileVersion < PERSISTENCE_VERSION) { |
347 |
1
1. doLoad : Changed increment from 1 to -1 → NO_COVERAGE |
++fileVersion; |
348 | ||
349 | LOG.log(Level.INFO, "Upgrading to version {0}", fileVersion); | |
350 | ||
351 | long startTime = System.currentTimeMillis(); | |
352 | file = transform(file, fileVersion); | |
353 | ||
354 | long endTime = System.currentTimeMillis(); | |
355 | LOG.log(Level.INFO, "Upgrading took " + ((endTime - startTime) / 1000) | |
356 | + " seconds"); | |
357 |
1
1. doLoad : removed call to org/argouml/persistence/AbstractFilePersister$ProgressMgr::nextPhase → NO_COVERAGE |
progressMgr.nextPhase(); |
358 | } | |
359 | } | |
360 | ||
361 |
1
1. doLoad : removed call to org/argouml/persistence/AbstractFilePersister$ProgressMgr::nextPhase → NO_COVERAGE |
progressMgr.nextPhase(); |
362 | ||
363 | inputStream = new XmlInputStream(file.toURI().toURL().openStream(), | |
364 | "argo", file.length(), 100000); | |
365 | ||
366 | ArgoParser parser = new ArgoParser(); | |
367 | Reader reader = new InputStreamReader(inputStream, Argo | |
368 | .getEncoding()); | |
369 |
1
1. doLoad : removed call to org/argouml/persistence/ArgoParser::readProject → NO_COVERAGE |
parser.readProject(p, reader); |
370 | ||
371 | List memberList = parser.getMemberList(); | |
372 | ||
373 | LOG.log(Level.INFO,memberList.size() + " members"); | |
374 | ||
375 |
3
1. doLoad : changed conditional boundary → NO_COVERAGE 2. doLoad : Changed increment from 1 to -1 → NO_COVERAGE 3. doLoad : negated conditional → NO_COVERAGE |
for (int i = 0; i < memberList.size(); ++i) { |
376 | MemberFilePersister persister = getMemberFilePersister((String) memberList | |
377 | .get(i)); | |
378 | LOG.log(Level.INFO, "Loading member with "+ persister.getClass().getName()); | |
379 | ||
380 |
1
1. doLoad : removed call to org/argouml/persistence/XmlInputStream::reopen → NO_COVERAGE |
inputStream.reopen(persister.getMainTag()); |
381 | // TODO: Do we need to set the input encoding here? It was | |
382 | // done for ToDo parsing, but none of the other member types | |
383 | // InputSource inputSource = new InputSource( | |
384 | // new InputStreamReader(inputStream, Argo | |
385 | // .getEncoding())); | |
386 | InputSource inputSource = new InputSource(inputStream); | |
387 | // Don't use systemId here or it will get opened in preference | |
388 | // to inputStream. | |
389 |
1
1. doLoad : removed call to org/xml/sax/InputSource::setPublicId → NO_COVERAGE |
inputSource.setPublicId(originalFile.toURI().toURL() |
390 | .toExternalForm()); | |
391 | try { | |
392 |
1
1. doLoad : removed call to org/argouml/persistence/MemberFilePersister::load → NO_COVERAGE |
persister.load(p, inputSource); |
393 | } catch (OpenException e) { | |
394 | // UML 2.x files could also contain a profile model. | |
395 | // Try again with uml:Profile as main tag. | |
396 |
1
1. doLoad : negated conditional → NO_COVERAGE |
if ("uml:Model".equals(persister.getMainTag()) |
397 |
1
1. doLoad : negated conditional → NO_COVERAGE |
&& e.getCause() instanceof UmlException |
398 |
1
1. doLoad : negated conditional → NO_COVERAGE |
&& e.getCause().getCause() instanceof IOException) { |
399 |
1
1. doLoad : removed call to org/argouml/persistence/XmlInputStream::reopen → NO_COVERAGE |
inputStream.reopen("uml:Profile"); |
400 |
1
1. doLoad : removed call to org/argouml/persistence/MemberFilePersister::load → NO_COVERAGE |
persister.load(p, inputSource); |
401 |
1
1. doLoad : removed call to org/argouml/kernel/Project::setProjectType → NO_COVERAGE |
p.setProjectType(Project.PROFILE_PROJECT); |
402 | } else { | |
403 | throw e; | |
404 | } | |
405 | } | |
406 | } | |
407 | ||
408 | // let's update the progress | |
409 |
1
1. doLoad : removed call to org/argouml/persistence/AbstractFilePersister$ProgressMgr::nextPhase → NO_COVERAGE |
progressMgr.nextPhase(); |
410 |
1
1. doLoad : removed call to org/argouml/util/ThreadUtils::checkIfInterrupted → NO_COVERAGE |
ThreadUtils.checkIfInterrupted(); |
411 |
1
1. doLoad : removed call to org/argouml/persistence/XmlInputStream::realClose → NO_COVERAGE |
inputStream.realClose(); |
412 |
1
1. doLoad : removed call to org/argouml/kernel/Project::postLoad → NO_COVERAGE |
p.postLoad(); |
413 |
1
1. doLoad : mutated return of Object value for org/argouml/persistence/UmlFilePersister::doLoad to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return p; |
414 | } catch (InterruptedException e) { | |
415 | throw e; | |
416 | } catch (OpenException e) { | |
417 | throw e; | |
418 | } catch (IOException e) { | |
419 | throw new OpenException(e); | |
420 | } catch (SAXException e) { | |
421 | throw new OpenException(e); | |
422 | } | |
423 | } | |
424 | ||
425 | protected boolean checkVersion(int fileVersion, String releaseVersion) | |
426 | throws OpenException, VersionException { | |
427 | // If we're trying to load a file from a future version | |
428 | // complain and refuse. | |
429 |
2
1. checkVersion : changed conditional boundary → NO_COVERAGE 2. checkVersion : negated conditional → NO_COVERAGE |
if (fileVersion > PERSISTENCE_VERSION) { |
430 | throw new VersionException( | |
431 | "The file selected is from a more up to date version of " | |
432 | + "ArgoUML. It has been saved with ArgoUML version " | |
433 | + releaseVersion | |
434 | + ". Please load with that or a more up to date" | |
435 | + "release of ArgoUML"); | |
436 | } | |
437 |
4
1. checkVersion : changed conditional boundary → NO_COVERAGE 2. checkVersion : negated conditional → NO_COVERAGE 3. checkVersion : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE 4. checkVersion : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return fileVersion >= PERSISTENCE_VERSION; |
438 | } | |
439 | ||
440 | /** | |
441 | * Transform a string of XML data according to the service required. | |
442 | * | |
443 | * @param file The XML file to be transformed | |
444 | * @param version the version of the persistence format the XML is to be | |
445 | * transformed to. | |
446 | * @return the transformed XML file | |
447 | * @throws OpenException on XSLT transformation error or file read | |
448 | */ | |
449 | public final File transform(File file, int version) throws OpenException { | |
450 | ||
451 | try { | |
452 | String upgradeFilesPath = "/org/argouml/persistence/upgrades/"; | |
453 | String upgradeFile = "upgrade" + version + ".xsl"; | |
454 | ||
455 | String xsltFileName = upgradeFilesPath + upgradeFile; | |
456 | URL xsltUrl = UmlFilePersister.class.getResource(xsltFileName); | |
457 | ||
458 | LOG.log(Level.INFO, "Resource is {0}", xsltUrl); | |
459 | ||
460 | // Read xsltStream into a temporary file | |
461 | // Get url for temp file. | |
462 | // openStream from url and wrap in StreamSource | |
463 | StreamSource xsltStreamSource = new StreamSource(xsltUrl | |
464 | .openStream()); | |
465 |
1
1. transform : removed call to javax/xml/transform/stream/StreamSource::setSystemId → NO_COVERAGE |
xsltStreamSource.setSystemId(xsltUrl.toExternalForm()); |
466 | ||
467 | TransformerFactory factory = TransformerFactory.newInstance(); | |
468 | Transformer transformer = factory.newTransformer(xsltStreamSource); | |
469 | ||
470 | File transformedFile = File.createTempFile("upgrade_" + version | |
471 | + "_", ".uml"); | |
472 |
1
1. transform : removed call to java/io/File::deleteOnExit → NO_COVERAGE |
transformedFile.deleteOnExit(); |
473 | ||
474 | FileOutputStream stream = new FileOutputStream(transformedFile); | |
475 | Writer writer = new BufferedWriter(new OutputStreamWriter(stream, | |
476 | Argo.getEncoding())); | |
477 | Result result = new StreamResult(writer); | |
478 | ||
479 | StreamSource inputStreamSource = new StreamSource(file); | |
480 |
1
1. transform : removed call to javax/xml/transform/stream/StreamSource::setSystemId → NO_COVERAGE |
inputStreamSource.setSystemId(file); |
481 |
1
1. transform : removed call to javax/xml/transform/Transformer::transform → NO_COVERAGE |
transformer.transform(inputStreamSource, result); |
482 | ||
483 |
1
1. transform : removed call to java/io/Writer::close → NO_COVERAGE |
writer.close(); |
484 |
1
1. transform : mutated return of Object value for org/argouml/persistence/UmlFilePersister::transform to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return transformedFile; |
485 | } catch (IOException e) { | |
486 | throw new OpenException(e); | |
487 | } catch (TransformerException e) { | |
488 | throw new OpenException(e); | |
489 | } | |
490 | } | |
491 | ||
492 | /** | |
493 | * Read stream in .argo format and extracts the persistence version number | |
494 | * from the root tag. | |
495 | * | |
496 | * @param file the XML file | |
497 | * @return The version number | |
498 | * @throws OpenException on any error | |
499 | */ | |
500 | private int getPersistenceVersionFromFile(File file) throws OpenException { | |
501 | InputStream stream = null; | |
502 | try { | |
503 | stream = new BufferedInputStream(file.toURI().toURL().openStream()); | |
504 | int version = getPersistenceVersion(stream); | |
505 |
1
1. getPersistenceVersionFromFile : removed call to java/io/InputStream::close → NO_COVERAGE |
stream.close(); |
506 |
1
1. getPersistenceVersionFromFile : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return version; |
507 | } catch (MalformedURLException e) { | |
508 | throw new OpenException(e); | |
509 | } catch (IOException e) { | |
510 | throw new OpenException(e); | |
511 | } finally { | |
512 |
2
1. getPersistenceVersionFromFile : negated conditional → NO_COVERAGE 2. getPersistenceVersionFromFile : negated conditional → NO_COVERAGE |
if (stream != null) { |
513 | try { | |
514 |
2
1. getPersistenceVersionFromFile : removed call to java/io/InputStream::close → NO_COVERAGE 2. getPersistenceVersionFromFile : removed call to java/io/InputStream::close → NO_COVERAGE |
stream.close(); |
515 | } catch (IOException e) { | |
516 | // ignore | |
517 | } | |
518 | } | |
519 | } | |
520 | } | |
521 | ||
522 | /** | |
523 | * Reads an XML file of uml format and extracts the persistence version | |
524 | * number from the root tag. | |
525 | * | |
526 | * @param inputStream stream pointing to file to read. | |
527 | * @return The version number | |
528 | * @throws OpenException on any error | |
529 | */ | |
530 | protected int getPersistenceVersion(InputStream inputStream) | |
531 | throws OpenException { | |
532 | ||
533 | BufferedReader reader = null; | |
534 | try { | |
535 | reader = new BufferedReader(new InputStreamReader(inputStream, Argo | |
536 | .getEncoding())); | |
537 | String rootLine = reader.readLine(); | |
538 |
2
1. getPersistenceVersion : negated conditional → NO_COVERAGE 2. getPersistenceVersion : negated conditional → NO_COVERAGE |
while (rootLine != null && !rootLine.trim().startsWith("<argo ")) { |
539 | rootLine = reader.readLine(); | |
540 | } | |
541 |
1
1. getPersistenceVersion : negated conditional → NO_COVERAGE |
if (rootLine == null) { |
542 |
1
1. getPersistenceVersion : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return 1; |
543 | } | |
544 |
1
1. getPersistenceVersion : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return Integer.parseInt(getVersion(rootLine)); |
545 | } catch (IOException e) { | |
546 | throw new OpenException(e); | |
547 | } catch (NumberFormatException e) { | |
548 | throw new OpenException(e); | |
549 | } finally { | |
550 | try { | |
551 |
3
1. getPersistenceVersion : negated conditional → NO_COVERAGE 2. getPersistenceVersion : negated conditional → NO_COVERAGE 3. getPersistenceVersion : negated conditional → NO_COVERAGE |
if (reader != null) { |
552 |
3
1. getPersistenceVersion : removed call to java/io/BufferedReader::close → NO_COVERAGE 2. getPersistenceVersion : removed call to java/io/BufferedReader::close → NO_COVERAGE 3. getPersistenceVersion : removed call to java/io/BufferedReader::close → NO_COVERAGE |
reader.close(); |
553 | } | |
554 | } catch (IOException e) { | |
555 | // No more we can do here on failure | |
556 | } | |
557 | } | |
558 | } | |
559 | ||
560 | /** | |
561 | * Reads an XML file of uml format and extracts the persistence version | |
562 | * number from the root tag. | |
563 | * | |
564 | * @param file the XML file | |
565 | * @return The ArgoUML release number | |
566 | * @throws OpenException on any error | |
567 | */ | |
568 | private String getReleaseVersionFromFile(File file) throws OpenException { | |
569 | InputStream stream = null; | |
570 | try { | |
571 | stream = new BufferedInputStream(file.toURI().toURL().openStream()); | |
572 | String version = getReleaseVersion(stream); | |
573 |
1
1. getReleaseVersionFromFile : removed call to java/io/InputStream::close → NO_COVERAGE |
stream.close(); |
574 |
1
1. getReleaseVersionFromFile : mutated return of Object value for org/argouml/persistence/UmlFilePersister::getReleaseVersionFromFile to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return version; |
575 | } catch (MalformedURLException e) { | |
576 | throw new OpenException(e); | |
577 | } catch (IOException e) { | |
578 | throw new OpenException(e); | |
579 | } finally { | |
580 |
2
1. getReleaseVersionFromFile : negated conditional → NO_COVERAGE 2. getReleaseVersionFromFile : negated conditional → NO_COVERAGE |
if (stream != null) { |
581 | try { | |
582 |
2
1. getReleaseVersionFromFile : removed call to java/io/InputStream::close → NO_COVERAGE 2. getReleaseVersionFromFile : removed call to java/io/InputStream::close → NO_COVERAGE |
stream.close(); |
583 | } catch (IOException e) { | |
584 | // ignore | |
585 | } | |
586 | } | |
587 | } | |
588 | } | |
589 | ||
590 | /** | |
591 | * Reads an XML file of uml format and extracts the persistence version | |
592 | * number from the root tag. | |
593 | * | |
594 | * @param inputStream the stream point to the XML file | |
595 | * @return The ArgoUML release number | |
596 | * @throws OpenException on any error | |
597 | */ | |
598 | protected String getReleaseVersion(InputStream inputStream) | |
599 | throws OpenException { | |
600 | ||
601 | BufferedReader reader = null; | |
602 | try { | |
603 | reader = new BufferedReader(new InputStreamReader(inputStream, Argo | |
604 | .getEncoding())); | |
605 | String versionLine = reader.readLine(); | |
606 |
1
1. getReleaseVersion : negated conditional → NO_COVERAGE |
while (!versionLine.trim().startsWith("<version>")) { |
607 | versionLine = reader.readLine(); | |
608 |
1
1. getReleaseVersion : negated conditional → NO_COVERAGE |
if (versionLine == null) { |
609 | throw new OpenException( | |
610 | "Failed to find the release <version> tag"); | |
611 | } | |
612 | } | |
613 | versionLine = versionLine.trim(); | |
614 | int end = versionLine.lastIndexOf("</version>"); | |
615 |
1
1. getReleaseVersion : mutated return of Object value for org/argouml/persistence/UmlFilePersister::getReleaseVersion to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return versionLine.trim().substring(9, end); |
616 | } catch (IOException e) { | |
617 | throw new OpenException(e); | |
618 | } catch (NumberFormatException e) { | |
619 | throw new OpenException(e); | |
620 | } finally { | |
621 | try { | |
622 |
2
1. getReleaseVersion : negated conditional → NO_COVERAGE 2. getReleaseVersion : negated conditional → NO_COVERAGE |
if (inputStream != null) { |
623 |
2
1. getReleaseVersion : removed call to java/io/InputStream::close → NO_COVERAGE 2. getReleaseVersion : removed call to java/io/InputStream::close → NO_COVERAGE |
inputStream.close(); |
624 | } | |
625 |
2
1. getReleaseVersion : negated conditional → NO_COVERAGE 2. getReleaseVersion : negated conditional → NO_COVERAGE |
if (reader != null) { |
626 |
2
1. getReleaseVersion : removed call to java/io/BufferedReader::close → NO_COVERAGE 2. getReleaseVersion : removed call to java/io/BufferedReader::close → NO_COVERAGE |
reader.close(); |
627 | } | |
628 | } catch (IOException e) { | |
629 | // No more we can do here on failure | |
630 | } | |
631 | } | |
632 | } | |
633 | ||
634 | /** | |
635 | * Get the version attribute value from a string of XML. | |
636 | * | |
637 | * @param rootLine the line | |
638 | * @return the version | |
639 | */ | |
640 | protected String getVersion(String rootLine) { | |
641 | String version; | |
642 | int versionPos = rootLine.indexOf("version=\""); | |
643 |
2
1. getVersion : changed conditional boundary → NO_COVERAGE 2. getVersion : negated conditional → NO_COVERAGE |
if (versionPos > 0) { |
644 |
1
1. getVersion : Replaced integer addition with subtraction → NO_COVERAGE |
int startPos = versionPos + 9; |
645 | int endPos = rootLine.indexOf("\"", startPos); | |
646 | version = rootLine.substring(startPos, endPos); | |
647 | } else { | |
648 | version = "1"; | |
649 | } | |
650 |
1
1. getVersion : mutated return of Object value for org/argouml/persistence/UmlFilePersister::getVersion to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return version; |
651 | } | |
652 | ||
653 | /** | |
654 | * Returns true. All Argo specific files have an icon. | |
655 | * | |
656 | * {@inheritDoc} | |
657 | */ | |
658 | public boolean hasAnIcon() { | |
659 |
1
1. hasAnIcon : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return true; |
660 | } | |
661 | ||
662 | /** | |
663 | * Class to filter XML declaration and DOCTYPE declaration from an output | |
664 | * stream to allow use as nested XML files. | |
665 | * | |
666 | * @author Tom Morris | |
667 | */ | |
668 | class XmlFilterOutputStream extends FilterOutputStream { | |
669 | ||
670 | private CharsetDecoder decoder; | |
671 | ||
672 | private boolean headerProcessed = false; | |
673 | ||
674 | private static final int BUFFER_SIZE = 120; | |
675 | ||
676 | /** | |
677 | * The following three fields make up a doubly mapped buffer with two | |
678 | * sets of pointers (the ByteBuffer objects), one for input and one for | |
679 | * output. Bytes are written into the buffer using outBB which advances | |
680 | * the current position. The following ASCII art shows what the buffer | |
681 | * looks like.<code> | |
682 | * vp vl | |
683 | * xxxxxx++++.......... | |
684 | * ^p ^l | |
685 | * </code> vp & vl are the output (buffer writing) position and limit, | |
686 | * respectively and show the free space that can receive bytes. The ^p | |
687 | * and ^l pointers show the input (buffer reading) position and limit. | |
688 | * They point to valid bytes which have not yet been converted to | |
689 | * characters. The xxx bytes have been both written in and read back | |
690 | * out. The +++ bytes have been written into the buffer, but not read | |
691 | * out yet. | |
692 | */ | |
693 | private byte[] bytes = new byte[BUFFER_SIZE * 2]; | |
694 | ||
695 | private ByteBuffer outBB = ByteBuffer.wrap(bytes); | |
696 | ||
697 | private ByteBuffer inBB = ByteBuffer.wrap(bytes); | |
698 | ||
699 | // Buffer containing characters which have been decoded from the bytes | |
700 | // in inBB. | |
701 | private CharBuffer outCB = CharBuffer.allocate(BUFFER_SIZE); | |
702 | ||
703 | // RegEx pattern for XML declaration and, optionally, DOCTYPE | |
704 | // Backslashes are doubled up - one for Java, one for Regex | |
705 | private final Pattern xmlDeclarationPattern = Pattern | |
706 | .compile("\\s*<\\?xml.*\\?>\\s*(<!DOCTYPE.*>\\s*)?"); | |
707 | ||
708 | /** | |
709 | * Construct a filtered output stream using the given character set | |
710 | * name. | |
711 | * | |
712 | * @param outputStream source output stream to filter | |
713 | * @param charsetName name of character set to use for encoding | |
714 | */ | |
715 | public XmlFilterOutputStream(OutputStream outputStream, | |
716 | String charsetName) { | |
717 | this(outputStream, Charset.forName(charsetName)); | |
718 | } | |
719 | ||
720 | /** | |
721 | * Construct a filtered output stream using the given character set. | |
722 | * | |
723 | * @param outputStream source output stream to filter | |
724 | * @param charset character set to use for encoding | |
725 | */ | |
726 | public XmlFilterOutputStream(OutputStream outputStream, Charset charset) { | |
727 | super(outputStream); | |
728 | decoder = charset.newDecoder(); | |
729 | decoder.onMalformedInput(CodingErrorAction.REPORT); | |
730 | decoder.onUnmappableCharacter(CodingErrorAction.REPORT); | |
731 |
1
1. |
startEntry(); |
732 | } | |
733 | ||
734 | /** | |
735 | * Reset processing for the beginning of an entry. | |
736 | */ | |
737 | public void startEntry() { | |
738 | headerProcessed = false; | |
739 |
1
1. startEntry : removed call to org/argouml/persistence/UmlFilePersister$XmlFilterOutputStream::resetBuffers → NO_COVERAGE |
resetBuffers(); |
740 | } | |
741 | ||
742 | private void resetBuffers() { | |
743 | inBB.limit(0); | |
744 | outBB.position(0); | |
745 | outCB.position(0); | |
746 | } | |
747 | ||
748 | @Override | |
749 | public void write(byte[] b, int off, int len) throws IOException { | |
750 |
8
1. write : changed conditional boundary → NO_COVERAGE 2. write : Replaced bitwise OR with AND → NO_COVERAGE 3. write : Replaced integer addition with subtraction → NO_COVERAGE 4. write : Replaced integer subtraction with addition → NO_COVERAGE 5. write : Replaced bitwise OR with AND → NO_COVERAGE 6. write : Replaced integer addition with subtraction → NO_COVERAGE 7. write : Replaced bitwise OR with AND → NO_COVERAGE 8. write : negated conditional → NO_COVERAGE |
if ((off | len | (b.length - (len + off)) | (off + len)) < 0) { |
751 | throw new IndexOutOfBoundsException(); | |
752 | } | |
753 | ||
754 |
1
1. write : negated conditional → NO_COVERAGE |
if (headerProcessed) { |
755 |
1
1. write : removed call to java/io/OutputStream::write → NO_COVERAGE |
out.write(b, off, len); |
756 | } else { | |
757 | // TODO: Make this more efficient for large I/Os | |
758 |
3
1. write : changed conditional boundary → NO_COVERAGE 2. write : Changed increment from 1 to -1 → NO_COVERAGE 3. write : negated conditional → NO_COVERAGE |
for (int i = 0; i < len; i++) { |
759 |
2
1. write : Replaced integer addition with subtraction → NO_COVERAGE 2. write : removed call to org/argouml/persistence/UmlFilePersister$XmlFilterOutputStream::write → NO_COVERAGE |
write(b[off + i]); |
760 | } | |
761 | } | |
762 | ||
763 | } | |
764 | ||
765 | @Override | |
766 | public void write(int b) throws IOException { | |
767 | ||
768 |
1
1. write : negated conditional → NO_COVERAGE |
if (headerProcessed) { |
769 |
1
1. write : removed call to java/io/OutputStream::write → NO_COVERAGE |
out.write(b); |
770 | } else { | |
771 | outBB.put((byte) b); | |
772 | inBB.limit(outBB.position()); | |
773 | // Convert from bytes back to characters | |
774 | CoderResult result = decoder.decode(inBB, outCB, false); | |
775 |
1
1. write : negated conditional → NO_COVERAGE |
if (result.isError()) { |
776 | throw new RuntimeException( | |
777 | "Unknown character decoding error"); | |
778 | } | |
779 | ||
780 | // This will have problems if the smallest possible | |
781 | // data segment is smaller than the size of the buffer | |
782 | // needed for regex matching | |
783 |
1
1. write : negated conditional → NO_COVERAGE |
if (outCB.position() == outCB.limit()) { |
784 |
1
1. write : removed call to org/argouml/persistence/UmlFilePersister$XmlFilterOutputStream::processHeader → NO_COVERAGE |
processHeader(); |
785 | } | |
786 | ||
787 | } | |
788 | } | |
789 | ||
790 | private void processHeader() throws IOException { | |
791 | headerProcessed = true; | |
792 | outCB.position(0); // rewind our character buffer | |
793 | ||
794 | Matcher matcher = xmlDeclarationPattern.matcher(outCB); | |
795 | // Remove anything that matches our pattern | |
796 | String headerRemainder = matcher.replaceAll(""); | |
797 |
1
1. processHeader : Replaced integer subtraction with addition → NO_COVERAGE |
int index = headerRemainder.length() - 1; |
798 |
1
1. processHeader : negated conditional → NO_COVERAGE |
if (headerRemainder.charAt(index) == '\0') { |
799 | // Remove null characters at the end | |
800 | do { | |
801 |
1
1. processHeader : Changed increment from -1 to 1 → NO_COVERAGE |
index--; |
802 |
3
1. processHeader : changed conditional boundary → NO_COVERAGE 2. processHeader : negated conditional → NO_COVERAGE 3. processHeader : negated conditional → NO_COVERAGE |
} while (index >= 0 && headerRemainder.charAt(index) == '\0'); |
803 |
1
1. processHeader : Replaced integer addition with subtraction → NO_COVERAGE |
headerRemainder = headerRemainder.substring(0, index + 1); |
804 | } | |
805 | ||
806 | // Reencode the remaining characters as bytes again | |
807 | ByteBuffer bb = decoder.charset().encode(headerRemainder); | |
808 | ||
809 | // and write them to our output stream | |
810 | byte[] outBytes = new byte[bb.limit()]; | |
811 | bb.get(outBytes); | |
812 |
1
1. processHeader : removed call to java/io/OutputStream::write → NO_COVERAGE |
out.write(outBytes, 0, outBytes.length); |
813 | ||
814 | // Write any left over bytes in the input buffer | |
815 | // (perhaps from a partially decoded character) | |
816 |
2
1. processHeader : changed conditional boundary → NO_COVERAGE 2. processHeader : negated conditional → NO_COVERAGE |
if (inBB.remaining() > 0) { |
817 |
1
1. processHeader : removed call to java/io/OutputStream::write → NO_COVERAGE |
out.write(inBB.array(), inBB.position(), inBB.remaining()); |
818 | inBB.position(0); | |
819 | inBB.limit(0); | |
820 | } | |
821 | } | |
822 | ||
823 | /** | |
824 | * This method has no effect to keep sub-writers from closing it | |
825 | * accidently. The master can use the method {@link #reallyClose()} to | |
826 | * actually close the underlying stream. | |
827 | */ | |
828 | @Override | |
829 | public void close() throws IOException { | |
830 |
1
1. close : removed call to org/argouml/persistence/UmlFilePersister$XmlFilterOutputStream::flush → NO_COVERAGE |
flush(); |
831 | } | |
832 | ||
833 | /** | |
834 | * Close the stream. | |
835 | * | |
836 | * @throws IOException | |
837 | */ | |
838 | public void reallyClose() throws IOException { | |
839 |
1
1. reallyClose : removed call to java/io/OutputStream::close → NO_COVERAGE |
out.close(); |
840 | } | |
841 | ||
842 | /** | |
843 | * Flush the stream. If the stream is flushed before the header is | |
844 | * completely processed, whatever has been written so far will get | |
845 | * processed before the flush. | |
846 | */ | |
847 | @Override | |
848 | public void flush() throws IOException { | |
849 |
1
1. flush : negated conditional → NO_COVERAGE |
if (!headerProcessed) { |
850 |
1
1. flush : removed call to org/argouml/persistence/UmlFilePersister$XmlFilterOutputStream::processHeader → NO_COVERAGE |
processHeader(); |
851 | } | |
852 |
1
1. flush : removed call to java/io/OutputStream::flush → NO_COVERAGE |
out.flush(); |
853 | } | |
854 | ||
855 | } | |
856 | } | |
Mutations | ||
132 |
1.1 |
|
139 |
1.1 |
|
161 |
1.1 |
|
162 |
1.1 |
|
167 |
1.1 |
|
180 |
1.1 |
|
181 |
1.1 |
|
182 |
1.1 |
|
186 |
1.1 |
|
188 |
1.1 |
|
190 |
1.1 |
|
196 |
1.1 |
|
200 |
1.1 |
|
203 |
1.1 2.2 |
|
206 |
1.1 |
|
211 |
1.1 |
|
216 |
1.1 |
|
223 |
1.1 |
|
240 |
1.1 |
|
266 |
1.1 |
|
268 |
1.1 |
|
274 |
1.1 |
|
278 |
1.1 |
|
280 |
1.1 |
|
281 |
1.1 |
|
285 |
1.1 |
|
290 |
1.1 |
|
291 |
1.1 |
|
293 |
1.1 |
|
299 |
1.1 |
|
301 |
1.1 |
|
303 |
1.1 2.2 |
|
305 |
1.1 2.2 |
|
318 |
1.1 |
|
320 |
1.1 |
|
321 |
1.1 |
|
336 |
1.1 |
|
343 |
1.1 |
|
344 |
1.1 2.2 |
|
346 |
1.1 2.2 |
|
347 |
1.1 |
|
357 |
1.1 |
|
361 |
1.1 |
|
369 |
1.1 |
|
375 |
1.1 2.2 3.3 |
|
380 |
1.1 |
|
389 |
1.1 |
|
392 |
1.1 |
|
396 |
1.1 |
|
397 |
1.1 |
|
398 |
1.1 |
|
399 |
1.1 |
|
400 |
1.1 |
|
401 |
1.1 |
|
409 |
1.1 |
|
410 |
1.1 |
|
411 |
1.1 |
|
412 |
1.1 |
|
413 |
1.1 |
|
429 |
1.1 2.2 |
|
437 |
1.1 2.2 3.3 4.4 |
|
465 |
1.1 |
|
472 |
1.1 |
|
480 |
1.1 |
|
481 |
1.1 |
|
483 |
1.1 |
|
484 |
1.1 |
|
505 |
1.1 |
|
506 |
1.1 |
|
512 |
1.1 2.2 |
|
514 |
1.1 2.2 |
|
538 |
1.1 2.2 |
|
541 |
1.1 |
|
542 |
1.1 |
|
544 |
1.1 |
|
551 |
1.1 2.2 3.3 |
|
552 |
1.1 2.2 3.3 |
|
573 |
1.1 |
|
574 |
1.1 |
|
580 |
1.1 2.2 |
|
582 |
1.1 2.2 |
|
606 |
1.1 |
|
608 |
1.1 |
|
615 |
1.1 |
|
622 |
1.1 2.2 |
|
623 |
1.1 2.2 |
|
625 |
1.1 2.2 |
|
626 |
1.1 2.2 |
|
643 |
1.1 2.2 |
|
644 |
1.1 |
|
650 |
1.1 |
|
659 |
1.1 |
|
731 |
1.1 |
|
739 |
1.1 |
|
750 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 |
|
754 |
1.1 |
|
755 |
1.1 |
|
758 |
1.1 2.2 3.3 |
|
759 |
1.1 2.2 |
|
768 |
1.1 |
|
769 |
1.1 |
|
775 |
1.1 |
|
783 |
1.1 |
|
784 |
1.1 |
|
797 |
1.1 |
|
798 |
1.1 |
|
801 |
1.1 |
|
802 |
1.1 2.2 3.3 |
|
803 |
1.1 |
|
812 |
1.1 |
|
816 |
1.1 2.2 |
|
817 |
1.1 |
|
830 |
1.1 |
|
839 |
1.1 |
|
849 |
1.1 |
|
850 |
1.1 |
|
852 |
1.1 |