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.ArrayList;
28  import java.util.Collection;
29  import java.util.Enumeration;
30  import java.util.Iterator;
31  import java.util.zip.ZipEntry;
32  import java.util.zip.ZipFile;
33  
34  import no.sintef.file.FileSuffixFilter;
35  import no.sintef.lock.LockException;
36  import no.sintef.xml.XmlHelper;
37  
38  import org.w3c.dom.Document;
39  import org.w3c.dom.Element;
40  import org.w3c.dom.Node;
41  import org.xml.sax.InputSource;
42  
43  import util.Base64;
44  import coras.client.SwingWorker;
45  import coras.common.CorasException;
46  import coras.representations.DiagramRepresentation;
47  import coras.representations.DocumentRepresentation;
48  import coras.representations.RepresentationFactory;
49  import coras.representations.RepresentationTypeEnum;
50  import coras.representations.UMLModelRepresentation;
51  import coras.reuse.CategoryEnum;
52  import coras.reuse.ExperiencePackage;
53  import coras.structure.ConcernEnum;
54  import coras.structure.ViewpointEnum;
55  import coras.types.SubtypeEnum;
56  
57  /***
58   * @author fvr
59   *
60   * TODO To change the template for this generated type comment go to
61   * Window - Preferences - Java - Code Style - Code Templates
62   */
63  public class ExperiencePackageImporter extends SwingWorker {
64  
65  	private File importFile = null;
66      
67      public ExperiencePackageImporter() {
68          
69      }
70      
71      public void setImportFile(File f) {
72      	importFile = f;
73      }
74      
75      private void importPackage(File importFile) throws CorasException {
76      	try {
77      		ZipFile zipFile = new ZipFile(importFile);
78      		Enumeration e = zipFile.entries();
79      		while (e.hasMoreElements()) {
80      			ZipEntry entry = (ZipEntry) e.nextElement();
81      			if (FileSuffixFilter.getSuffix(entry.getName()).equals("ci")) {
82      				InputStream is = zipFile.getInputStream(entry);
83      				importPackage(is);
84      				return;
85      			}
86      			throw new CorasException("Could not find experience package data in file " + importFile.getAbsolutePath());
87      		}
88      	} catch (IOException e) {
89      		try {
90  				importPackage(new FileInputStream(importFile));
91  			} catch (IOException e1) {
92  				throw new CorasException("Unable to read experience package data from file " + importFile.getAbsolutePath());
93  			}
94      	}
95      }
96      
97      private void importPackage(InputStream is) throws CorasException {
98          Node n = null;
99          try {
100             n = XmlHelper.parse(new InputSource(is));
101         } catch (Exception e) {
102             throw new CorasException("Error reading data: " + e.getMessage(), e);
103         }
104         Element rootElem = XmlHelper.getRootElement(n);
105         if (rootElem == null) {
106             throw new CorasException("No data found");
107         }
108         if (rootElem.getLocalName().equals(Constants.EXPERIENCE_PACKAGE_ELEM) 
109         		&& rootElem.getNamespaceURI().equals(Constants.CORAS_V1_NAMESPACE_URI)) {
110             importPackage(Constants.CORAS_V1_NAMESPACE_URI, rootElem);
111         } else if (rootElem.getLocalName().equals(Constants.EXPERIENCE_PACKAGE_ELEM)
112         		&& rootElem.getNamespaceURI().equals(Constants.CORAS_V2_NAMESPACE_URI)) {
113         	importPackage(Constants.CORAS_V2_NAMESPACE_URI, rootElem);
114         } else {
115         	throw new CorasException("Invalid data format");
116         }
117     }
118     
119     private void importPackage(String namespaceUri, Element rootElem) throws CorasException {
120         String backupdate = rootElem.getAttribute(Constants.BACKUPDATE_ATTR);
121         CategoryEnum category = CategoryEnum.forName(rootElem.getAttribute(Constants.CATEGORY_ATTR));
122         boolean finalised = Boolean.valueOf(rootElem.getAttribute(Constants.FINALISED_ATTR)).booleanValue();
123         String name = rootElem.getAttribute(Constants.NAME_ATTR);
124         
125         String id;
126         String shortDescription = "";
127         String fullDescription;
128         Collection experiences;
129         
130         Element metadataElem = XmlHelper.getFirstElement(rootElem, namespaceUri, Constants.METADATA_ELEM);
131         String domain = XmlHelper.getText(metadataElem, namespaceUri, Constants.DOMAIN_ELEM);
132         if (namespaceUri.equals(Constants.CORAS_V1_NAMESPACE_URI)) {
133         	id = rootElem.getAttribute(Constants.REFERENCE_ATTR);
134         	fullDescription = XmlHelper.getText(metadataElem, namespaceUri, Constants.DESCRIPTION_ELEM);
135         	experiences = XmlHelper.getElements(rootElem, namespaceUri, Constants.REUSABLE_ELEMENT_ELEM);
136         } else {
137         	id = rootElem.getAttribute(Constants.ID_ATTR);
138         	shortDescription = XmlHelper.getText(metadataElem, namespaceUri, Constants.SHORT_DESCRIPTION_ELEM);
139         	fullDescription = XmlHelper.getText(metadataElem, namespaceUri, Constants.FULL_DESCRIPTION_ELEM);
140         	experiences = XmlHelper.getElements(rootElem, namespaceUri, Constants.EXPERIENCE_ELEM);
141         }
142         if (shortDescription == null)
143         	shortDescription = "";
144         if (fullDescription == null)
145         	fullDescription = "";
146 
147         setTaskLength(experiences.size() + 1);
148         int taskNum = 0;
149         
150         setJobName("Importing Experience Package: " + name);
151         setCurrentTask("Importing Experience Package: " + name);
152         ExperiencePackage thePackage = ExperiencePackage.createPackage(name, shortDescription, category, domain, fullDescription);
153         setProgress(++taskNum);
154         
155         for (Iterator i = experiences.iterator(); i.hasNext();) {
156         	if (Thread.currentThread().isInterrupted()) {
157         		setInterrupted(true);
158         		return;
159         	}
160             Element experienceElem = (Element) i.next();
161 	        importExperience(thePackage, namespaceUri, experienceElem);
162         	setProgress(++taskNum);
163         }
164         setFinished(true);
165     }
166 
167     /***
168      * @param thePackage
169      * @param experienceElem
170      * @throws CorasException
171      */
172     private void importExperience(ExperiencePackage thePackage, String namespaceUri, Element experienceElem) throws CorasException {
173         if (thePackage == null || experienceElem == null) {
174             throw new CorasException("XML error");
175         }
176         
177         try {
178             thePackage.checkOut();
179             String backupdate = experienceElem.getAttribute(Constants.BACKUPDATE_ATTR);
180             CategoryEnum category = CategoryEnum.forName(experienceElem.getAttribute(Constants.CATEGORY_ATTR));
181             boolean finalised = Boolean.valueOf(experienceElem.getAttribute(Constants.FINALISED_ATTR)).booleanValue();
182             String name = experienceElem.getAttribute(Constants.NAME_ATTR);
183             
184             String typeString = experienceElem.getAttribute(Constants.TYPE_ATTR);
185             String subtypeString = experienceElem.getAttribute(Constants.SUBTYPE_ATTR);
186             
187             String id;
188             String shortDescription = "";
189             String fullDescription;
190             
191             Element metadataElem = XmlHelper.getFirstElement(experienceElem, namespaceUri, Constants.METADATA_ELEM);
192             if (namespaceUri.equals(Constants.CORAS_V1_NAMESPACE_URI)) {
193             	id = experienceElem.getAttribute(Constants.REFERENCE_ATTR);
194             	fullDescription = XmlHelper.getText(metadataElem, namespaceUri, Constants.DESCRIPTION_ELEM);
195             } else {
196             	id = experienceElem.getAttribute(Constants.ID_ATTR);
197             	shortDescription = XmlHelper.getText(metadataElem, namespaceUri, Constants.SHORT_DESCRIPTION_ELEM);
198             	fullDescription = XmlHelper.getText(metadataElem, namespaceUri, Constants.FULL_DESCRIPTION_ELEM);
199             }
200             if (shortDescription == null)
201             	shortDescription = "";
202             if (fullDescription == null)
203             	fullDescription = "";
204 
205             String domain = XmlHelper.getText(metadataElem, namespaceUri, Constants.DOMAIN_ELEM);
206             String concernString = XmlHelper.getText(metadataElem, namespaceUri, Constants.CONCERN_ELEM);
207             ConcernEnum concern = ConcernEnum.forName(concernString);
208             ArrayList viewpointsList = new ArrayList();
209             Element viewpointsElem = XmlHelper.getFirstElement(metadataElem, namespaceUri, Constants.VIEWPOINTS_ELEM);
210             Collection viewpointElems = XmlHelper.getElements(viewpointsElem, namespaceUri, Constants.VIEWPOINT_ELEM);
211             for (Iterator i = viewpointElems.iterator(); i.hasNext();) {
212                 Element viewpointElem = (Element) i.next();
213                 String viewpointString = XmlHelper.getText(viewpointElem);
214                 ViewpointEnum viewpoint = ViewpointEnum.forName(viewpointString);
215                 if (viewpoint != null) {
216                     viewpointsList.add(viewpoint);
217                 }
218             }
219             ViewpointEnum[] viewpoints = (ViewpointEnum[]) viewpointsList.toArray(new ViewpointEnum[0]);
220             
221             Element representationsElem = XmlHelper.getFirstElement(experienceElem, namespaceUri, Constants.REPRESENTATIONS_ELEM);
222             Collection representationElems = XmlHelper.getElements(representationsElem, namespaceUri, Constants.REPRESENTATION_ELEM);
223             
224         	if (Constants.UML_MODEL_TYPE.equalsIgnoreCase(typeString)) {
225         		setCurrentTask("Importing UML Experience: " + name);
226                 SubtypeEnum subtype = getUMLSubtype(subtypeString);
227                 UMLModelRepresentation umlModel = getUMLModel(representationElems, namespaceUri);
228                 DiagramRepresentation diagram = getUMLDiagram(representationElems, namespaceUri);
229 //                System.out.println("XMI model: " + (xmiModel != null ? xmiModel.getFilename() : "null"));
230 //                System.out.println("Diagram: " + (diagram != null ? diagram.getFilename() : "null"));
231                 thePackage.createUMLModel(subtype, name, shortDescription, fullDescription, category, domain, concern, viewpoints, umlModel, diagram);
232             } else if (Constants.EXTERNAL_DOCUMENT_TYPE.equals(typeString)
233             		|| Constants.DOCUMENT_TYPE.equals(typeString)) {
234         	    setCurrentTask("Importing Document Experience: " + name);
235                 DocumentRepresentation document = getDocument(representationElems, namespaceUri);
236 //                System.out.println("Document: " + (document!= null ? document.getFilename() : "null"));
237                 thePackage.createDocument(name, shortDescription, fullDescription, category, domain, concern, viewpoints, document);
238             } else {
239         	    setCurrentTask("Skipping Experience of type " + typeString + ": " + name);
240                 thePackage.unCheckOut();
241             }
242         } catch (LockException e) {
243             throw new CorasException("Database locking error while importing data: " + e.getMessage(), e);
244         }
245     }
246 
247     private DocumentRepresentation getDocument(Collection representations, String namespaceUri) {
248         Element elem;
249         if (namespaceUri.equals(Constants.CORAS_V1_NAMESPACE_URI)) {
250         	elem = getRepresentation(representations, Constants.EXTERNAL_DOCUMENT_TYPE);
251         } else {
252         	elem = getRepresentation(representations, Constants.DOCUMENT_TYPE);
253         }
254         if (elem == null) {
255             return null;
256         }
257         String name = elem.getAttribute(Constants.NAME_ATTR);
258         String content = XmlHelper.getText(elem, namespaceUri, Constants.CONTENT_ELEM);
259         byte[] bytes = Base64.decode(content);
260         try {
261             return RepresentationFactory.createDocument(name, bytes);
262         } catch (IOException e) {
263             return null;
264         }
265     }
266     
267     /***
268      * @param representations
269      * @return
270      */
271     private DiagramRepresentation getUMLDiagram(Collection representations, String namespaceUri) {
272         Element elem = getRepresentation(representations, Constants.IMAGE_TYPE);
273         if (elem == null) {
274             return null;
275         }
276         String name = elem.getAttribute(Constants.NAME_ATTR); 
277         String format = elem.getAttribute(Constants.FORMAT_ATTR);
278         elem = XmlHelper.getFirstElement(elem, namespaceUri, Constants.CONTENT_ELEM);
279         if (Constants.BINARY_FORMAT.equals(format)) {
280             String content = XmlHelper.getText(elem);
281             byte[] bytes = Base64.decode(content);
282             try {
283                 return RepresentationFactory.createBitmapImage(name, bytes);
284             } catch (IOException e) {
285                 e.printStackTrace();
286                 return null;
287             }
288         } else { // XML
289             elem = XmlHelper.getFirstElement(elem, null, null); // XMI
290             Document doc = XmlHelper.createDocument(elem);
291             return RepresentationFactory.createSVGImage(name, doc);
292         }
293     }
294 
295     /***
296      * @param representations
297      * @param namespaceUri 
298      * @return
299      */
300     private UMLModelRepresentation getUMLModel(Collection representations, String namespaceUri) {
301         Element elem = getRepresentation(representations, Constants.UML_MODEL_TYPE);
302         if (elem == null) {
303         	elem = getRepresentation(representations, RepresentationTypeEnum.XMI_MODEL.toString());
304         }
305         if (elem == null) {
306         	elem = getRepresentation(representations, RepresentationTypeEnum.DGM_MODEL.toString());
307         }
308         if (elem == null) {
309         	elem = getRepresentation(representations, RepresentationTypeEnum.ZUMLZARGO_MODEL.toString());
310         }
311         if (elem == null) {
312         	return null;
313         }
314         String name = elem.getAttribute(Constants.NAME_ATTR); 
315         String format = elem.getAttribute(Constants.FORMAT_ATTR);
316         elem = XmlHelper.getFirstElement(elem, namespaceUri, Constants.CONTENT_ELEM);
317         if (format.equals(Constants.XML_FORMAT)) {
318         	elem = XmlHelper.getFirstElement(elem, null, null); // XMI
319         	Document doc = XmlHelper.createDocument(elem);
320         	return RepresentationFactory.createXmiOrDgmModel(name, doc);
321         } else {
322         	String s = XmlHelper.getText(elem);
323         	byte[] bytes = Base64.decode(s);
324         	return RepresentationFactory.createZumlZargoModel(name, bytes);
325         }
326     }
327 
328     /***
329      * @param string
330      * @return
331      */
332     private Element getRepresentation(Collection representations, String type) {
333         for (Iterator i = representations.iterator(); i.hasNext();) {
334             Element elem = (Element) i.next();
335             if (type.equalsIgnoreCase(elem.getAttribute(Constants.TYPE_ATTR))) {
336                 return elem;
337             }
338         }
339         return null;
340     }
341 
342     /***
343      * @param subtypeString
344      * @return
345      */
346     private SubtypeEnum getUMLSubtype(String subtypeString) {
347         SubtypeEnum subtype = SubtypeEnum.forName(subtypeString);
348         if (subtype == null) {
349             subtype = SubtypeEnum.OTHER_DIAGRAM;
350         }
351         return subtype;
352     }
353 
354 	/* (non-Javadoc)
355 	 * @see coras.client.SwingWorker#construct()
356 	 */
357 	public Object construct() {
358         try {
359 			importPackage(importFile);
360 			return null;
361 		} catch (Exception e) {
362 			return e;
363 		}
364 	}
365     
366 }