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 coras.interchange;
22  
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.IOException;
26  import java.io.InputStream;
27  import java.util.Collection;
28  import java.util.Enumeration;
29  import java.util.Iterator;
30  import java.util.List;
31  import java.util.zip.ZipEntry;
32  import java.util.zip.ZipFile;
33  
34  import no.sintef.file.FileSuffixFilter;
35  import no.sintef.lock.AlreadyLockedException;
36  import no.sintef.lock.LockException;
37  import no.sintef.xml.XmlHelper;
38  
39  import org.w3c.dom.Document;
40  import org.w3c.dom.Element;
41  import org.w3c.dom.Node;
42  import org.xml.sax.InputSource;
43  
44  import util.Base64;
45  import coras.client.SwingWorker;
46  import coras.common.CorasException;
47  import coras.representations.DiagramRepresentation;
48  import coras.representations.DocumentRepresentation;
49  import coras.representations.RepresentationFactory;
50  import coras.representations.RepresentationTypeEnum;
51  import coras.representations.TableRepresentation;
52  import coras.representations.UMLModelRepresentation;
53  import coras.riskanalysis.RiskAnalysisProject;
54  import coras.riskanalysis.TableResult;
55  import coras.structure.ConcernEnum;
56  import coras.structure.ViewpointEnum;
57  import coras.table.CorasTableModel;
58  import coras.types.SubtypeEnum;
59  
60  /***
61   * @author fvr
62   *
63   * TODO To change the template for this generated type comment go to
64   * Window - Preferences - Java - Code Style - Code Templates
65   */
66  public class RiskAnalysisProjectImporter extends SwingWorker {
67  
68  	private File importFile = null;
69      
70      public RiskAnalysisProjectImporter() {
71          
72      }
73      
74      public void setImportFile(File f) {
75      	importFile = f;
76      }
77      
78      private void importPackage(File importFile) throws CorasException {
79      	try {
80      		ZipFile zipFile = new ZipFile(importFile);
81      		Enumeration e = zipFile.entries();
82      		while (e.hasMoreElements()) {
83      			ZipEntry entry = (ZipEntry) e.nextElement();
84      			if (FileSuffixFilter.getSuffix(entry.getName()).equals("ci")) {
85      				InputStream is = zipFile.getInputStream(entry);
86      				importPackage(is);
87      				return;
88      			}
89      			throw new CorasException("Could not find project data in file " + importFile.getAbsolutePath());
90      		}
91      	} catch (IOException e) {
92      		try {
93  				importPackage(new FileInputStream(importFile));
94  			} catch (IOException e1) {
95  				throw new CorasException("Unable to read project data from file " + importFile.getAbsolutePath());
96  			}
97      	}
98      }
99  
100     private void importPackage(InputStream is) throws CorasException {
101         Node n = null;
102         try {
103             n = XmlHelper.parse(new InputSource(is));
104         } catch (Exception e) {
105             throw new CorasException("Error reading data: " + e.getMessage(), e);
106         }
107         Element rootElem = XmlHelper.getRootElement(n);
108         if (rootElem == null) {
109             throw new CorasException("No data found");
110         }
111         if (rootElem.getLocalName().equals(Constants.RISK_ASSESSMENT_PACKAGE_ELEM)
112         		&& rootElem.getNamespaceURI().equals(Constants.CORAS_V1_NAMESPACE_URI)) {
113         	importPackage(Constants.CORAS_V1_NAMESPACE_URI, rootElem);
114         } else if (rootElem.getLocalName().equals(Constants.RISK_ANALYSIS_PROJECT_ELEM)
115         		&& rootElem.getNamespaceURI().equals(Constants.CORAS_V2_NAMESPACE_URI)) {
116         	importPackage(Constants.CORAS_V2_NAMESPACE_URI, rootElem);
117         } else {
118         	throw new CorasException("Invalid data format");
119         }
120     }
121     
122     private void importPackage(String namespaceUri, Element rootElem) throws CorasException {
123         String backupdate = rootElem.getAttribute(Constants.BACKUPDATE_ATTR);
124 //        CategoryEnum category = CategoryEnum.forName(rootElem.getAttribute(CATEGORY_ATTR));
125         boolean finalised = Boolean.valueOf(rootElem.getAttribute(Constants.FINALISED_ATTR)).booleanValue();
126         String name = rootElem.getAttribute(Constants.NAME_ATTR);
127         
128         Collection results;
129         String id;
130         String shortDescription = null;
131         String fullDescription;
132         
133         Element metadataElem = XmlHelper.getFirstElement(rootElem, namespaceUri, Constants.METADATA_ELEM);
134         if (namespaceUri.equals(Constants.CORAS_V1_NAMESPACE_URI)) {
135         	id = rootElem.getAttribute(Constants.REFERENCE_ATTR);
136         	fullDescription = XmlHelper.getText(metadataElem, namespaceUri, Constants.DESCRIPTION_ELEM);
137         	results = XmlHelper.getElements(rootElem, namespaceUri, Constants.RISK_ASSESSMENT_RESULT_ELEM);
138         } else {
139         	id = rootElem.getAttribute(Constants.ID_ATTR);
140         	shortDescription = XmlHelper.getText(metadataElem, namespaceUri, Constants.SHORT_DESCRIPTION_ELEM);
141         	fullDescription = XmlHelper.getText(metadataElem, namespaceUri, Constants.FULL_DESCRIPTION_ELEM);
142         	results = XmlHelper.getElements(rootElem, namespaceUri, Constants.RISK_ANALYSIS_RESULT_ELEM);
143         }
144         if (shortDescription == null)
145         	shortDescription = "";
146         if (fullDescription == null)
147         	fullDescription = "";
148         
149         setTaskLength(results.size() + 1);
150         int taskNum = 0;
151         
152         setJobName("Importing Risk Analysis Project: " + name);
153         setCurrentTask("Importing Risk Analysis Project: " + name);
154         RiskAnalysisProject project = RiskAnalysisProject.createProject(name, shortDescription, fullDescription);
155         setProgress(++taskNum);
156         
157         for (Iterator i = results.iterator(); i.hasNext();) {
158         	if (Thread.currentThread().isInterrupted()) {
159         		setInterrupted(true);
160         		return;
161         	}
162             Element resultElem = (Element) i.next();
163 	        importResult(project, namespaceUri, resultElem);
164         	setProgress(++taskNum);
165         }
166         setFinished(true);
167     }
168 
169     /***
170      * @param project
171      * @param resultElem
172      * @throws CorasException
173      */
174     private void importResult(RiskAnalysisProject project, String namespaceUri, Element resultElem) throws CorasException {
175         if (project == null || resultElem == null) {
176             throw new CorasException("XML error");
177         }
178         
179         try {
180         	try {
181         		project.checkOut();
182         	} catch (AlreadyLockedException e) {
183         	}
184             String backupdate = resultElem.getAttribute(Constants.BACKUPDATE_ATTR);
185 //            CategoryEnum category = CategoryEnum.forName(resultElem.getAttribute(CATEGORY_ATTR));
186             boolean finalised = Boolean.valueOf(resultElem.getAttribute(Constants.FINALISED_ATTR)).booleanValue();
187             String name = resultElem.getAttribute(Constants.NAME_ATTR);
188             String typeString = resultElem.getAttribute(Constants.TYPE_ATTR);
189             String subtypeString = resultElem.getAttribute(Constants.SUBTYPE_ATTR);
190             
191             String shortDescription = "";
192             String fullDescription;
193             String id;
194             
195             Element metadataElem = XmlHelper.getFirstElement(resultElem, namespaceUri, Constants.METADATA_ELEM);
196             if (namespaceUri.equals(Constants.CORAS_V1_NAMESPACE_URI)) {
197             	id = resultElem.getAttribute(Constants.REFERENCE_ATTR);
198             	fullDescription = XmlHelper.getText(metadataElem, namespaceUri, Constants.DESCRIPTION_ELEM);
199             } else {
200             	id = resultElem.getAttribute(Constants.ID_ATTR);
201             	shortDescription = XmlHelper.getText(metadataElem, namespaceUri, Constants.SHORT_DESCRIPTION_ELEM);
202             	fullDescription = XmlHelper.getText(metadataElem, namespaceUri, Constants.FULL_DESCRIPTION_ELEM);
203             }
204             if (shortDescription == null)
205             	shortDescription = "";
206             if (fullDescription == null)
207             	fullDescription = "";
208 
209             String concernString = XmlHelper.getText(metadataElem, namespaceUri, Constants.CONCERN_ELEM);
210             ConcernEnum concern = ConcernEnum.forName(concernString);
211             String viewpointString = XmlHelper.getText(metadataElem, namespaceUri, Constants.VIEWPOINT_ELEM);
212             ViewpointEnum viewpoint = ViewpointEnum.forName(viewpointString);
213             /*
214             ArrayList viewpointsList = new ArrayList();
215             Element viewpointsElem = XmlHelper.getFirstElement(metadataElem, CORAS_V1_NAMESPACE_URI, VIEWPOINTS_ELEM);
216             Collection viewpointElems = XmlHelper.getElements(viewpointsElem, CORAS_V1_NAMESPACE_URI, VIEWPOINT_ELEM);
217             for (Iterator i = viewpointElems.iterator(); i.hasNext();) {
218                 Element viewpointElem = (Element) i.next();
219                 String viewpointString = XmlHelper.getText(viewpointElem);
220                 ViewpointEnum viewpoint = ViewpointEnum.forName(viewpointString);
221                 if (viewpoint != null) {
222                     viewpointsList.add(viewpoint);
223                 }
224             }
225             ViewpointEnum[] viewpoints = (ViewpointEnum[]) viewpointsList.toArray(new ViewpointEnum[0]);
226             */
227             
228             Element representationsElem = XmlHelper.getFirstElement(resultElem, namespaceUri, Constants.REPRESENTATIONS_ELEM);
229             Collection representationElems = XmlHelper.getElements(representationsElem, namespaceUri, Constants.REPRESENTATION_ELEM);
230             
231         	if (Constants.UML_MODEL_TYPE.equalsIgnoreCase(typeString)) {
232         		setCurrentTask("Importing UML Model: " + name);
233                 SubtypeEnum subtype = getUMLSubtype(subtypeString);
234                 UMLModelRepresentation xmiModel = getUMLModel(representationElems, namespaceUri);
235                 DiagramRepresentation diagram = getUMLDiagram(representationElems, namespaceUri);
236 //                System.out.println("XMI model: " + (xmiModel != null ? xmiModel.getFilename() : "null"));
237 //                System.out.println("Diagram: " + (diagram != null ? diagram.getFilename() : "null"));
238                 project.createUMLModel(subtype, name, shortDescription, fullDescription, concern, viewpoint, xmiModel, diagram);
239             } else if (Constants.EXTERNAL_DOCUMENT_TYPE.equals(typeString)
240             		|| Constants.DOCUMENT_TYPE.equals(typeString)) {
241         	    setCurrentTask("Importing Document: " + name);
242                 DocumentRepresentation document = getDocument(representationElems, namespaceUri);
243 //                System.out.println("Document: " + (document!= null ? document.getFilename() : "null"));
244                 project.createDocument(name, shortDescription, fullDescription, concern, viewpoint, document);
245             } else if (Constants.TABLE_TYPE.equals(typeString)) {
246         	    setCurrentTask("Importing Table: " + name);
247             	try {
248             		SubtypeEnum subtype;
249             		TableRepresentation r = null;
250             		if (namespaceUri.equals(Constants.CORAS_V2_NAMESPACE_URI)) {
251             			r = getV2Table(representationElems);
252             			subtype = SubtypeEnum.forName(subtypeString);
253             		} else {
254 						subtype = getTableSubtype(subtypeString);
255 					}
256             		TableResult result = project.createTable(subtype, name, shortDescription, fullDescription, concern, viewpoint, r);
257             		if (namespaceUri.equals(Constants.CORAS_V1_NAMESPACE_URI)) {
258             			setV1TableContent(result, representationElems);
259 					}
260             	} catch (LockException e) {
261             		setCurrentTask("Database locking error while importing Table: " + e.getMessage());
262             	} catch (Exception e) {
263             		setCurrentTask("Skipping Table of type " + subtypeString + ": " + name);
264             		project.unCheckOut();
265             	}
266             } else {
267         	    setCurrentTask("Skipping " + typeString + ": " + name);
268                 project.unCheckOut();
269             }
270         } catch (LockException e) {
271             throw new CorasException("Database locking error while importing data: " + e.getMessage(), e);
272         }
273     }
274 
275     private DocumentRepresentation getDocument(Collection representations, String namespaceUri) {
276         Element elem;
277         if (namespaceUri.equals(Constants.CORAS_V1_NAMESPACE_URI)) {
278 			elem = getRepresentation(representations, Constants.EXTERNAL_DOCUMENT_TYPE);
279 		} else {
280 			elem = getRepresentation(representations, Constants.DOCUMENT_TYPE);
281 		}
282         if (elem == null) {
283             return null;
284         }
285         String name = elem.getAttribute(Constants.NAME_ATTR);
286         String content = XmlHelper.getText(elem, namespaceUri, Constants.CONTENT_ELEM);
287         byte[] bytes = Base64.decode(content);
288         try {
289             return RepresentationFactory.createDocument(name, bytes);
290         } catch (IOException e) {
291             return null;
292         }
293     }
294     
295     /***
296      * @param representations
297      * @return
298      */
299     private DiagramRepresentation getUMLDiagram(Collection representations, String namespaceUri) {
300         Element elem = getRepresentation(representations, Constants.IMAGE_TYPE);
301         if (elem == null) {
302             return null;
303         }
304         String name = elem.getAttribute(Constants.NAME_ATTR); 
305         String format = elem.getAttribute(Constants.FORMAT_ATTR);
306         elem = XmlHelper.getFirstElement(elem, namespaceUri, Constants.CONTENT_ELEM);
307         if (Constants.BINARY_FORMAT.equals(format)) {
308             String content = XmlHelper.getText(elem);
309             byte[] bytes = Base64.decode(content);
310             try {
311                 return RepresentationFactory.createBitmapImage(name, bytes);
312             } catch (IOException e) {
313                 e.printStackTrace();
314                 return null;
315             }
316         } else { // XML
317             elem = XmlHelper.getFirstElement(elem, null, null); // XMI
318             Document doc = XmlHelper.createDocument(elem);
319             return RepresentationFactory.createSVGImage(name, doc);
320         }
321     }
322 
323     /***
324      * @param representations
325      * @return
326      */
327     private UMLModelRepresentation getUMLModel(Collection representations, String namespaceUri) {
328         Element elem = getRepresentation(representations, Constants.UML_MODEL_TYPE);
329         if (elem == null) {
330         	elem = getRepresentation(representations, RepresentationTypeEnum.XMI_MODEL.toString());
331         }
332         if (elem == null) {
333         	elem = getRepresentation(representations, RepresentationTypeEnum.DGM_MODEL.toString());
334         }
335         if (elem == null) {
336         	elem = getRepresentation(representations, RepresentationTypeEnum.ZUMLZARGO_MODEL.toString());
337         }
338         if (elem == null) {
339             return null;
340         }
341         String name = elem.getAttribute(Constants.NAME_ATTR); 
342         String format = elem.getAttribute(Constants.FORMAT_ATTR);
343         elem = XmlHelper.getFirstElement(elem, namespaceUri, Constants.CONTENT_ELEM);
344         if (format.equals(Constants.XML_FORMAT)) {
345         	elem = XmlHelper.getFirstElement(elem, null, null); // XMI
346         	Document doc = XmlHelper.createDocument(elem);
347         	return RepresentationFactory.createXmiOrDgmModel(name, doc);
348         } else {
349         	String s = XmlHelper.getText(elem);
350         	byte[] bytes = Base64.decode(s);
351         	return RepresentationFactory.createZumlZargoModel(name, bytes);
352         }
353     }
354     
355     private TableRepresentation getV2Table(Collection representations) {
356     	Element elem = getRepresentation(representations, Constants.TABLE_TYPE);
357     	if (elem == null) {
358     		return null;
359     	}
360     	String name = elem.getAttribute(Constants.NAME_ATTR); 
361     	elem = XmlHelper.getFirstElement(elem, Constants.CORAS_V2_NAMESPACE_URI, Constants.CONTENT_ELEM);
362     	elem = XmlHelper.getFirstElement(elem, null, null); // coras-table:table
363     	Document doc = XmlHelper.createDocument(elem);
364     	return RepresentationFactory.createTable(doc, name);
365     }
366 
367     private void setV1TableContent(TableResult table, Collection representations) throws LockException {
368     	table.checkOut();
369     	CorasTableModel model = table.getTableModel();
370     	Element elem = getRepresentation(representations, Constants.TABLE_TYPE);
371     	if (elem == null) {
372     		return;
373     	}
374         elem = XmlHelper.getFirstElement(elem, Constants.CORAS_V1_NAMESPACE_URI, Constants.CONTENT_ELEM);
375         elem = XmlHelper.getFirstElement(elem, null, null); // Table
376         elem = XmlHelper.getFirstElement(elem, null, null); // first rowgroup
377         List rows = XmlHelper.getElements(elem, null, null); // rows
378         int row = 0;
379         for (Iterator i = rows.iterator(); i.hasNext();) {
380 			Element rowElem = (Element) i.next();
381 			model.addRow(row);
382 			List columns = XmlHelper.getElements(rowElem, null, null); // columns
383 			int column = 0;
384 			for (Iterator j = columns.iterator(); j.hasNext();) {
385 				Element columnElem = (Element) j.next();
386 				String value = XmlHelper.getText(columnElem);
387 				model.setValueAt(value, row, column);
388 				column++;
389 			}
390 			row++;
391 		}
392         table.updateRepresentation();
393         table.checkIn("");
394     }
395     
396     /***
397      * @param string
398      * @return
399      */
400     private Element getRepresentation(Collection representations, String type) {
401         for (Iterator i = representations.iterator(); i.hasNext();) {
402             Element elem = (Element) i.next();
403             if (type.equalsIgnoreCase(elem.getAttribute(Constants.TYPE_ATTR))) {
404                 return elem;
405             }
406         }
407         return null;
408     }
409 
410     /***
411      * @param subtypeString
412      * @return
413      */
414     private SubtypeEnum getUMLSubtype(String subtypeString) {
415         SubtypeEnum subtype = SubtypeEnum.forName(subtypeString);
416         if (subtype == null) {
417             subtype = SubtypeEnum.OTHER_DIAGRAM;
418         }
419         return subtype;
420     }
421 
422     private SubtypeEnum getTableSubtype(String subtypeString) {
423     	if (subtypeString == null) return null;
424     	// FIXME check mapping of tables
425     	if (subtypeString.equals("AssessmentPlanTable")) return SubtypeEnum.ANALYSIS_PLAN_TABLE;
426     	if (subtypeString.equals("AssessmentMethodsTable")) return SubtypeEnum.ANALYSIS_METHODS_TABLE;
427     	if (subtypeString.equals("AssessmentRestrictionsTable")) return SubtypeEnum.ANALYSIS_RESTRICTIONS_TABLE;
428     	if (subtypeString.equals("AssessmentRolesTable")) return SubtypeEnum.ANALYSIS_ROLES_TABLE;
429     	if (subtypeString.equals("SWOTResultTable")) return SubtypeEnum.SWOT_RESULT_TABLE;
430 //    	if (subtypeString.equals("StakeholderTable")) return SubtypeEnum.STAKEHOLDER_TABLE;
431     	if (subtypeString.equals("AssetTable")) return SubtypeEnum.ASSET_TABLE;
432 //    	if (subtypeString.equals("StakeholderPolicyTable")) return SubtypeEnum.STAKEHOLDER_POLICY_TABLE;
433     	if (subtypeString.equals("RiskEvaluationCriteriaTable")) return SubtypeEnum.RISK_EVALUATION_CRITERIA_TABLE;
434     	if (subtypeString.equals("ApprovalRegistrationForm")) return SubtypeEnum.APPROVAL_REGISTRATION_FORM;
435     	if (subtypeString.equals("HazopTable")) return SubtypeEnum.HAZOP_TABLE;
436     	if (subtypeString.equals("FMECATable")) return SubtypeEnum.FMEA_TABLE;
437 //    	if (subtypeString.equals("FTATable")) return SubtypeEnum.FTA_TABLE;
438     	if (subtypeString.equals("VulnerabilityTable")) return SubtypeEnum.VULNERABILITY_TABLE;
439     	if (subtypeString.equals("UnwantedIncidentTable")) return SubtypeEnum.SCENARIO_TABLE;
440     	if (subtypeString.equals("ConsequenceTable")) return SubtypeEnum.CONSEQUENCE_AND_FREQUENCY_TABLE;
441     	if (subtypeString.equals("FrequencyTable")) return SubtypeEnum.CONSEQUENCE_AND_FREQUENCY_TABLE;
442     	if (subtypeString.equals("RiskEstimateTable")) return SubtypeEnum.RISK_EVALUATION_TABLE;
443     	if (subtypeString.equals("RiskPriorityTable")) return SubtypeEnum.RISK_EVALUATION_TABLE;
444     	if (subtypeString.equals("RiskThemesTable")) return SubtypeEnum.RISK_CATEGORY_TABLE;
445 //    	if (subtypeString.equals("RiskThemesRelationshipTable")) return SubtypeEnum.RISK_THEME_RELATIONSHIP_TABLE;
446 //    	if (subtypeString.equals("RiskThemesPriorityTable")) return SubtypeEnum.RISK_THEME_PRIORITY_TABLE;
447     	if (subtypeString.equals("RiskThemeTreatmentTable")) return SubtypeEnum.TREATMENT_IDENTIFICATION_TABLE;
448     	if (subtypeString.equals("RiskThemeTreatmentEvaluationTable")) return SubtypeEnum.TREATMENT_EVALUATION_TABLE;
449     	if (subtypeString.equals("RiskThemeTreatmentPriorityTable")) return SubtypeEnum.TREATMENT_EVALUATION_TABLE;
450     	
451     	/* Missing in new version :
452     	 * 
453     	 * Target of evaluation table
454     	 * Stakeholder & stakeholder policy tables
455     	 * Organisation table
456     	 * FTA table
457     	 * Markov tables
458     	 * Risk table
459     	 * Risk matrix
460     	 * Risk themes relationship & priority tables
461     	*/
462     	return null;
463     }
464     
465 	/* (non-Javadoc)
466 	 * @see coras.client.SwingWorker#construct()
467 	 */
468 	public Object construct() {
469         try {
470 			importPackage(importFile);
471 			return null;
472 		} catch (Exception e) {
473 			return e;
474 		}
475 	}
476     
477 }