View Javadoc

1   /*
2    *  Copyright (C) 2003-2005 SINTEF
3    *  Author:  Fredrik Vraalsen (fredrik dot vraalsen at sintef dot no)
4    *  Webpage: http://coras.sourceforge.net/
5    *
6    *  This program is free software; you can redistribute it and/or
7    *  modify it under the terms of the GNU Lesser General Public License
8    *  as published by the Free Software Foundation; either version 2.1
9    *  of the License, or (at your option) any later version.
10   *
11   *  This program is distributed in the hope that it will be useful,
12   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   *  Lesser General Public License for more details.
15   *
16   *  You should have received a copy of the GNU Lesser General Public
17   *  License along with this program; if not, write to the Free
18   *  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19   *  02111-1307 USA
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 }