1 package coras.interchange;
2
3 import java.io.File;
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.text.SimpleDateFormat;
7 import java.util.Calendar;
8 import java.util.Collection;
9 import java.util.Iterator;
10 import java.util.zip.ZipEntry;
11 import java.util.zip.ZipOutputStream;
12
13 import javax.xml.bind.JAXBContext;
14 import javax.xml.bind.JAXBException;
15 import javax.xml.bind.Marshaller;
16 import javax.xml.transform.Transformer;
17 import javax.xml.transform.TransformerException;
18 import javax.xml.transform.TransformerFactory;
19 import javax.xml.transform.dom.DOMResult;
20 import javax.xml.transform.dom.DOMSource;
21 import javax.xml.transform.sax.SAXResult;
22 import javax.xml.transform.sax.SAXTransformerFactory;
23 import javax.xml.transform.sax.TransformerHandler;
24 import javax.xml.transform.stream.StreamResult;
25
26 import no.sintef.file.FileSuffixFilter;
27 import no.sintef.xml.XmlHelper;
28
29 import org.w3c.dom.Node;
30 import org.xml.sax.Attributes;
31 import org.xml.sax.ContentHandler;
32 import org.xml.sax.SAXException;
33 import org.xml.sax.helpers.AttributesImpl;
34 import org.xml.sax.helpers.XMLFilterImpl;
35
36 import util.Base64;
37 import coras.client.SwingWorker;
38 import coras.common.CorasRepresentation;
39 import coras.representations.BinaryRepresentation;
40 import coras.representations.RepresentationTypeEnum;
41 import coras.representations.XmlRepresentation;
42 import coras.riskanalysis.RiskAnalysisProject;
43 import coras.riskanalysis.RiskAnalysisResult;
44 import coras.table.CorasTableModel;
45 import coras.table.jaxb.TableType;
46 import coras.types.IDocument;
47 import coras.types.IFaultTree;
48 import coras.types.ITable;
49 import coras.types.IUMLModel;
50
51 public class RiskAnalysisProjectExporter extends SwingWorker {
52
53 private RiskAnalysisProject _project = null;
54 private File exportFile = null;
55 private String backupDate = null;
56 private Collection selectedResults = null;
57
58 public void setExportFile(File exportFile) {
59 this.exportFile = exportFile;
60 }
61
62 public void setProject(RiskAnalysisProject project) {
63 this._project = project;
64 }
65
66 public void setSelectedResults(Collection selectedResults) {
67 this.selectedResults = selectedResults;
68 }
69
70 public Object construct() {
71 try {
72 backupDate = new SimpleDateFormat("yyyyMMdd HH:mm:ss").format(Calendar.getInstance().getTime());
73 TransformerHandler th = getTransformerHandler();
74 String filename = exportFile.getName();
75 FileOutputStream fos = new FileOutputStream(exportFile);
76 ZipOutputStream zos = new ZipOutputStream(fos);
77 ZipEntry entry = new ZipEntry(FileSuffixFilter.getPrefix(filename) + ".ci");
78 zos.putNextEntry(entry);
79 StreamResult sr = new StreamResult(zos);
80 th.setResult(sr);
81 th.startDocument();
82 exportProject(_project, th);
83 th.endDocument();
84 zos.closeEntry();
85 zos.close();
86 return null;
87 } catch (SAXException e) {
88 return e;
89 } catch (IOException e) {
90 return e;
91 }
92 }
93
94 private void exportProject(RiskAnalysisProject project, ContentHandler ch) throws SAXException {
95 Collection results = selectedResults;
96 if (results == null) {
97 results = project.getResults(null);
98 }
99 setTaskLength(results.size() + 1);
100 int taskNum = 0;
101
102 setJobName("Exporting Risk Analysis Project: " + project.getName());
103 setCurrentTask("Exporting Risk Analysis Project: " + project.getName());
104
105 AttributesImpl atts = new AttributesImpl();
106 addAttribute(atts, Constants.BACKUPDATE_ATTR, backupDate);
107 addAttribute(atts, Constants.ID_ATTR, project.getId());
108 addAttribute(atts, Constants.NAME_ATTR, project.getName());
109 atts.addAttribute("", Constants.PREFIX, "xmlns:" + Constants.PREFIX, Constants.CDATA_TYPE, Constants.CORAS_V2_NAMESPACE_URI);
110 startElement(ch, Constants.RISK_ANALYSIS_PROJECT_ELEM, atts);
111
112 startElement(ch, Constants.METADATA_ELEM);
113 outputTextElement(ch, Constants.FULL_DESCRIPTION_ELEM, project.getFullDescription());
114 outputTextElement(ch, Constants.SHORT_DESCRIPTION_ELEM, project.getShortDescription());
115 endElement(ch, Constants.METADATA_ELEM);
116
117 setProgress(++taskNum);
118 for (Iterator i = results.iterator(); i.hasNext();) {
119 if (Thread.currentThread().isInterrupted()) {
120 setInterrupted(true);
121 return;
122 }
123 RiskAnalysisResult result = (RiskAnalysisResult) i.next();
124 if (!result.isDeleted()) {
125 exportResult(result, ch);
126 }
127 setProgress(++taskNum);
128 }
129 endElement(ch, Constants.RISK_ANALYSIS_PROJECT_ELEM);
130 }
131
132 private void exportResult(RiskAnalysisResult result, ContentHandler ch) throws SAXException {
133 setCurrentTask("Exporting " + result.getType() + ": " + result.getName());
134
135 AttributesImpl atts = new AttributesImpl();
136 addAttribute(atts, Constants.BACKUPDATE_ATTR, backupDate);
137 addAttribute(atts, Constants.ID_ATTR, result.getId());
138 addAttribute(atts, Constants.NAME_ATTR, result.getName());
139 addAttribute(atts, Constants.TYPE_ATTR, result.getType());
140 addAttribute(atts, Constants.SUBTYPE_ATTR, result.getSubtype());
141 startElement(ch, Constants.RISK_ANALYSIS_RESULT_ELEM, atts);
142
143 startElement(ch, Constants.METADATA_ELEM);
144 outputTextElement(ch, Constants.FULL_DESCRIPTION_ELEM, result.getFullDescription());
145 outputTextElement(ch, Constants.SHORT_DESCRIPTION_ELEM, result.getShortDescription());
146 outputTextElement(ch, Constants.CONCERN_ELEM, result.getConcern());
147 outputTextElement(ch, Constants.VIEWPOINT_ELEM, result.getViewpoint());
148 endElement(ch, Constants.METADATA_ELEM);
149
150 startElement(ch, Constants.REPRESENTATIONS_ELEM);
151 if (result instanceof IDocument) {
152 IDocument doc = (IDocument) result;
153 exportRepresentation(ch, doc.getDocumentContent());
154 } else if (result instanceof IFaultTree) {
155 IFaultTree ft = (IFaultTree) result;
156 exportRepresentation(ch, ft.getFaultTreeModel());
157 exportRepresentation(ch, ft.getFaultTreeDiagram());
158 } else if (result instanceof ITable) {
159 ITable table = (ITable) result;
160 CorasTableModel tableModel = table.getTableModel();
161 try {
162 Marshaller m = JAXBContext.newInstance("coras.table.jaxb").createMarshaller();
163 TableType t = tableModel.getTable();
164 DOMResult r = new DOMResult();
165 m.marshal(t, r);
166 Node n = r.getNode();
167 exportRepresentation(ch, RepresentationTypeEnum.TABLE, t.getType().replaceAll(" ", "_") + ".xml", n);
168 } catch (JAXBException e) {
169
170 e.printStackTrace();
171 }
172 } else if (result instanceof IUMLModel) {
173 IUMLModel uml = (IUMLModel) result;
174 exportRepresentation(ch, uml.getUMLModel());
175 exportRepresentation(ch, uml.getUMLDiagram());
176 }
177 endElement(ch, Constants.REPRESENTATIONS_ELEM);
178
179 endElement(ch, Constants.RISK_ANALYSIS_RESULT_ELEM);
180 }
181
182 private void exportRepresentation(ContentHandler ch, CorasRepresentation rep) throws SAXException {
183 Object content;
184 if (rep instanceof XmlRepresentation) {
185 content = ((XmlRepresentation)rep).getXmlContent();
186 } else if (rep instanceof BinaryRepresentation) {
187 content = ((BinaryRepresentation)rep).getBinaryContent();
188 } else {
189 return;
190 }
191 exportRepresentation(ch, rep.getType(), rep.getFilename(), content);
192 }
193
194 private void exportRepresentation(ContentHandler ch, RepresentationTypeEnum type, String filename, Object content) throws SAXException {
195 AttributesImpl atts = new AttributesImpl();
196 addAttribute(atts, Constants.TYPE_ATTR, type.toString());
197 addAttribute(atts, Constants.NAME_ATTR, filename);
198 addAttribute(atts, Constants.FORMAT_ATTR, content instanceof byte[] ? Constants.BINARY_FORMAT : Constants.XML_FORMAT);
199 startElement(ch, Constants.REPRESENTATION_ELEM, atts);
200
201 startElement(ch, Constants.CONTENT_ELEM);
202 if (content instanceof Node) {
203 try {
204 XMLFilterImpl filter = new XMLFilterImpl() {
205 public void endDocument() throws SAXException {
206
207 }
208 public void startDocument() throws SAXException {
209
210 }
211 };
212 filter.setContentHandler(ch);
213 Node n = (Node) content;
214 Transformer t = XmlHelper.getIdentityTransformation();
215 DOMSource source = new DOMSource(n);
216 SAXResult result = new SAXResult(filter);
217 t.transform(source, result);
218 } catch (TransformerException e) {
219 e.printStackTrace();
220 }
221 } else if (content instanceof byte[]) {
222 byte[] bytes = (byte[]) content;
223 String s = Base64.encodeBytes(bytes);
224 ch.characters(s.toCharArray(), 0, s.length());
225 }
226 endElement(ch, Constants.CONTENT_ELEM);
227
228 endElement(ch, Constants.REPRESENTATION_ELEM);
229 }
230
231 private static final void startElement(ContentHandler ch, String localName) throws SAXException {
232 startElement(ch, localName, null);
233 }
234
235 private static final void startElement(ContentHandler ch, String localName, Attributes atts) throws SAXException {
236 if (atts == null) {
237 atts = Constants.EMPTY_ATTRIBUTES;
238 }
239 ch.startElement(Constants.CORAS_V2_NAMESPACE_URI, localName, Constants.PREFIX + ":" + localName, atts);
240 }
241
242 private static final void endElement(ContentHandler ch, String localName) throws SAXException {
243 ch.endElement(Constants.CORAS_V2_NAMESPACE_URI, localName, Constants.PREFIX + ":" + localName);
244 }
245
246 private static final void addAttribute(AttributesImpl atts, String name, Object value) {
247 if (value != null) {
248 atts.addAttribute("", "", name, Constants.CDATA_TYPE, value.toString());
249 }
250 }
251
252 private static void outputTextElement(ContentHandler ch, String localName, Object value) throws SAXException {
253 startElement(ch, localName);
254 String text = value != null ? value.toString() : null;
255 if (text != null) {
256 char[] chars = new char[text.length()];
257 text.getChars(0, text.length(), chars, 0);
258 ch.characters(chars, 0, chars.length);
259 }
260 endElement(ch, localName);
261 }
262
263 private static TransformerHandler getTransformerHandler() {
264 try {
265 TransformerFactory factory = TransformerFactory.newInstance();
266 if (factory.getFeature(SAXTransformerFactory.FEATURE)) {
267 SAXTransformerFactory saxFactory = (SAXTransformerFactory)factory;
268 return saxFactory.newTransformerHandler();
269 } else {
270
271 return null;
272 }
273 } catch (Exception e) {
274
275 return null;
276 }
277 }
278
279 }
280