1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package no.sintef.umt;
22
23 import java.io.ByteArrayInputStream;
24 import java.io.ByteArrayOutputStream;
25 import java.io.File;
26 import java.io.FileInputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.util.zip.ZipEntry;
30 import java.util.zip.ZipException;
31 import java.util.zip.ZipInputStream;
32
33 import no.sintef.file.MimeTypeEnum;
34 import no.sintef.util.Pair;
35 import no.sintef.xml.XmlException;
36 import no.sintef.xml.XmlHelper;
37
38 import org.w3c.dom.Document;
39 import org.xml.sax.InputSource;
40
41 /***
42 * Reads XMI from XML or zuml/zargo files (Poseidon/ArgoUML).
43 *
44 * @author Fredrik Vraalsen
45 */
46 public final class XmiReader {
47
48 private static final int BUF_LEN = 4096;
49
50 /***
51 * Prevent helper class from being instantiated.
52 */
53 private XmiReader() {
54 }
55
56 /***
57 * Reads XMI from XML or zuml/zargo files (Poseidon/ArgoUML) and return as
58 * XML Document.
59 *
60 * @param srcFile
61 * the file to read from
62 * @return the XMI Document
63 * @throws XmlException
64 * if error parsing XMI
65 * @throws IOException
66 * if IO error occurs, or zargo/zuml file does not contain XMI
67 */
68 public static Document readXmi(File srcFile) throws XmlException, IOException {
69 String name = srcFile.getName();
70 MimeTypeEnum mimeType = MimeTypeEnum.getMimeType(name);
71 InputStream is = new FileInputStream(srcFile);
72 if (mimeType == MimeTypeEnum.APPLICATION_BINARY) {
73 Pair pair = unpack(is);
74 if (pair == null) {
75 throw new ZipException("Unable to read Poseidon UML file");
76 }
77 name = (String) pair.getFirst();
78 is = new ByteArrayInputStream((byte[]) pair.getSecond());
79 }
80 return XmlHelper.parse(new InputSource(is));
81 }
82
83 public static Document getZumlZargoXmi(InputStream is) throws XmlException, IOException {
84 Pair pair = unpack(is);
85 if (pair == null) {
86 throw new ZipException("Unable to read Poseidon UML file");
87 }
88 is = new ByteArrayInputStream((byte[]) pair.getSecond());
89 return XmlHelper.parse(new InputSource(is));
90 }
91
92 /***
93 * Get the XMI filename and data (bytes) from a zargo/zuml file.
94 *
95 * @param is
96 * the file input stream
97 * @return the XMI filename and data (bytes) wrapped in a NameBytesPair, or
98 * null if file does not contain XMI
99 */
100 private static Pair unpack(InputStream is) {
101 ByteArrayOutputStream baos = new ByteArrayOutputStream();
102 ZipInputStream zis = new ZipInputStream(is);
103 try {
104 String name;
105 while (true) {
106 ZipEntry zipEntry;
107 zipEntry = zis.getNextEntry();
108 if (zipEntry == null) {
109 return null;
110 }
111 name = zipEntry.getName();
112 if (name != null && name.endsWith(".xmi")) {
113 break;
114 }
115 }
116 byte[] buf = new byte[BUF_LEN];
117 int length;
118 while ((length = zis.read(buf)) != -1) {
119 baos.write(buf, 0, length);
120 }
121 return new Pair(name, baos.toByteArray());
122 } catch (IOException e) {
123 e.printStackTrace();
124 return null;
125 }
126 }
127
128 }