View Javadoc

1   /*
2    * Copyright (c) 2003-2008, by Henrik Arro and Contributors
3    *
4    * This file is part of JSeq, a tool to automatically create
5    * sequence diagrams by tracing program execution.
6    *
7    * See <http://jseq.sourceforge.net> for more information.
8    *
9    * JSeq is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation, either version 3 of
12   * the License, or (at your option) any later version.
13   *
14   * JSeq is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17   * GNU Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public License
20   * along with JSeq. If not, see <http://www.gnu.org/licenses/>.
21   */
22  
23  package th.co.edge.jseq.argouml;
24  
25  import java.io.File;
26  import java.io.FileOutputStream;
27  import java.io.IOException;
28  import java.io.OutputStreamWriter;
29  import java.io.StringWriter;
30  import java.io.Writer;
31  import java.util.List;
32  import java.util.zip.ZipEntry;
33  import java.util.zip.ZipOutputStream;
34  
35  import org.w3c.dom.Document;
36  
37  import ru.novosoft.uml.model_management.MModel;
38  import ru.novosoft.uml.xmi.IncompleteXMIException;
39  import ru.novosoft.uml.xmi.XMIWriter;
40  import th.co.edge.jseq.Diagram;
41  import th.co.edge.jseq.util.XMLUtil;
42  
43  /**
44   * An <code>ArgoUMLDiagram</code> is a <code>Diagram</code> that can be used
45   * to generate sequence diagrams in .zargo format, readable by the tool <a
46   * href="http://argouml.tigris.org/" target="new">ArgoUML</a>.
47   *
48   * <p>
49   * The current version has only been verified to work with version 0.12 of
50   * ArgoUML, and it is a known problem that it does not work with version 0.24 (<a
51   * href=https://sourceforge.net/tracker/index.php?func=detail&aid=2046485&group_id=230519&atid=1080391"
52   * target="new">SourceForge issue 2046485</a>).
53   */
54  public class ArgoUMLDiagram implements Diagram {
55      private Document argo;
56      private MModel model;
57      private List<SequenceDiagram> diagrams;
58  
59      /**
60       * Creates a new <code>ArgoUMLDiagram</code>.
61       *
62       * @param argo
63       *            an XML <code>Document</code> defining the contents of this
64       *            file
65       * @param model
66       *            an <code>MModel</code> representation of an XMI document
67       *            defining the parts of this UML model
68       * @param diagrams
69       *            a list of <code>SequenceDiagram</code>s, one per root
70       *            activation
71       */
72      public ArgoUMLDiagram(Document argo, MModel model,
73              List<SequenceDiagram> diagrams) {
74          this.argo = argo;
75          this.model = model;
76          this.diagrams = diagrams;
77      }
78  
79      /**
80       * Writes this <code>ArgoUMLDiagram</code> to file in .zargo format, that
81       * is, as a zipped set of XML model files.
82       *
83       * @param file
84       *            the <code>File</code> to write to
85       *
86       * @throws IOException
87       *             if the diagram could not be saved
88       */
89      public void save(File file) throws IOException {
90          Writer writer = null;
91          try {
92              ZipOutputStream zip =
93                      new ZipOutputStream(new FileOutputStream(file));
94              writer = new OutputStreamWriter(zip);
95              writeXML(argo, "Untitled.argo", zip, writer);
96              writeModel(model, "Untitled.xmi", zip, writer);
97              int n = 0;
98              for (SequenceDiagram diagram : diagrams) {
99                  String name = "SequenceDiagram" + (n++) + ".pgml";
100                 writeXML(diagram.getDocument(), name, zip, writer);
101             }
102         } finally {
103             if (writer != null) {
104                 try {
105                     writer.close();
106                 } catch (IOException e) {
107                     System.err.println(e);
108                 }
109             }
110         }
111     }
112 
113     private void writeXML(Document xml, String name, ZipOutputStream zip,
114             Writer writer) throws IOException {
115         zip.putNextEntry(new ZipEntry(name));
116         writer.write(XMLUtil.toString(xml));
117         writer.flush();
118         zip.closeEntry();
119     }
120 
121     private void writeModel(MModel mModel, String name, ZipOutputStream zip,
122             Writer writer) throws IOException {
123         // It is necessary to write XMI to a StringWriter first, because
124         // XMIWriter.gen seems to close the stream, making it impossible
125         // to add more ZIP entries.
126         StringWriter stringWriter = new StringWriter();
127         XMIWriter xmiWriter = new XMIWriter(mModel, stringWriter);
128         try {
129             xmiWriter.gen();
130         } catch (IncompleteXMIException e) {
131             e.printStackTrace();
132             throw new IOException("Writing XMI failed: " + e.getMessage());
133         }
134         zip.putNextEntry(new ZipEntry(name));
135         writer.write(stringWriter.toString());
136         writer.flush();
137         zip.closeEntry();
138     }
139 }