1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package coras.internalmodel;
22
23 import java.io.ByteArrayInputStream;
24 import java.io.IOException;
25 import java.net.URL;
26 import java.util.Calendar;
27 import java.util.Collection;
28 import java.util.Iterator;
29
30 import javax.xml.parsers.ParserConfigurationException;
31 import javax.xml.transform.Transformer;
32 import javax.xml.transform.dom.DOMResult;
33 import javax.xml.transform.dom.DOMSource;
34
35 import no.sintef.assetrepository.Asset;
36 import no.sintef.assetrepository.Representation;
37 import no.sintef.assetrepository.interfaces.AssetRepresentationPK;
38 import no.sintef.assetrepository.interfaces.AssetRepresentationValue;
39 import no.sintef.assetrepository.interfaces.AssetServices;
40 import no.sintef.assetrepository.interfaces.AssetVersionValue;
41 import no.sintef.file.MimeTypeEnum;
42 import no.sintef.lock.AlreadyLockedException;
43 import no.sintef.umt.XmiLightTransformer;
44 import no.sintef.umt.XmiReader;
45 import no.sintef.xml.XmlException;
46 import no.sintef.xml.XmlHelper;
47
48 import org.apache.log4j.Logger;
49 import org.w3c.dom.Document;
50 import org.w3c.dom.Element;
51 import org.w3c.dom.Node;
52 import org.xml.sax.SAXException;
53
54 import coras.dgm.DgmTransformer;
55 import coras.representations.RepresentationTypeEnum;
56 import coras.types.ElementTypeEnum;
57 import coras.types.SubtypeEnum;
58
59
60 /***
61 * @author fvr
62 *
63 * To change the template for this generated type comment go to
64 * Window - Preferences - Java - Code Generation - Code and Comments
65 */
66 public class InternalModelFactory {
67
68
69 private static final Logger LOGGER = Logger.getLogger(InternalModelFactory.class);
70
71 private static final String NAMESPACE_URI = "http://coras.sourceforge.net/schemas/coras-internalmodel-1_0.xsd";
72 private static final String PREFIX = "ci";
73 private static final String ROOT_ELEM = "riskAssessmentDocuments";
74
75
76 private static InternalModelFactory theFactory = null;
77
78
79 private Transformer internalTransformer = null;
80
81
82 public static synchronized InternalModelFactory getInternalModelFactory() {
83 if (theFactory == null) {
84 try {
85 theFactory = new InternalModelFactory();
86 } catch (Exception e) {
87 LOGGER.warn("Could not create InternalModelFactory: " + e);
88 e.printStackTrace();
89 theFactory = null;
90 }
91 }
92 return theFactory;
93 }
94
95
96 private InternalModelFactory() throws ParserConfigurationException, IOException, SAXException {
97 ClassLoader cl = getClass().getClassLoader();
98 URL url = cl.getResource("coras/internalmodel/CorasXml2InternalXml.xsl");
99
100 try {
101
102 internalTransformer = XmlHelper.getTransformer(url, LOGGER);
103 } catch (XmlException e) {
104 LOGGER.fatal("Unable to create CorasXml2InternalXml transformer", e);
105 }
106 }
107
108
109 public Element getInternalRepresentation(Collection resultVersions, AssetServices services) {
110 if (resultVersions == null)
111 return null;
112
113 Document doc = XmlHelper.createDocument(NAMESPACE_URI, PREFIX, ROOT_ELEM, null);
114 Element rootElem = doc.getDocumentElement();
115
116 for (Iterator i = resultVersions.iterator(); i.hasNext(); ) {
117
118 AssetVersionValue resultVersion = (AssetVersionValue) i.next();
119 Node n = getInternalRepresentation(resultVersion, services);
120 n = XmlHelper.getRootElement(n);
121 if (n != null) {
122 rootElem.appendChild(doc.importNode(n, true));
123 }
124 }
125
126 if (LOGGER.isDebugEnabled()) {
127 LOGGER.debug("internal model source: " + new String(XmlHelper.xmlToUtf8(rootElem, true)));
128 }
129 DOMSource source = new DOMSource(rootElem);
130 DOMResult result = new DOMResult();
131 try {
132 synchronized (internalTransformer) {
133 internalTransformer.transform(source, result);
134 }
135 if (LOGGER.isDebugEnabled()) {
136 LOGGER.debug("internal model: " + new String(XmlHelper.xmlToUtf8(result.getNode(), true)));
137 }
138 return XmlHelper.getRootElement(result.getNode());
139 } catch (Exception e) {
140 LOGGER.warn("Could not create internal representation: " + e);
141 e.printStackTrace();
142 return null;
143 }
144 }
145
146
147 /***
148 * @param resultVersion
149 * @return
150 */
151 private Node getInternalRepresentation(AssetVersionValue resultVersion, AssetServices services) {
152 if (resultVersion == null)
153 return null;
154 ElementTypeEnum type = ElementTypeEnum.forName((String) resultVersion.getProperties().get("type"));
155 SubtypeEnum subtype = SubtypeEnum.forName((String) resultVersion.getProperties().get("subtype"));
156 if (type == null) {
157 return null;
158 }
159 if (type == ElementTypeEnum.TABLE || type == ElementTypeEnum.FAULT_TREE) {
160 Object content;
161 if (type == ElementTypeEnum.TABLE) {
162 content = getRepresentationContent(resultVersion, RepresentationTypeEnum.TABLE, services);
163 } else {
164 content = getRepresentationContent(resultVersion, RepresentationTypeEnum.FAULT_TREE_MODEL, services);
165 }
166 if (content instanceof Node) {
167 return (Node) content;
168 } else if (content == null) {
169 if (type == ElementTypeEnum.TABLE) {
170 LOGGER.error("No table content");
171 }
172 return null;
173 } else {
174 LOGGER.warn(type + " content not XML");
175 return null;
176 }
177 } else if (type == ElementTypeEnum.UML_MODEL) {
178 Node xmiLight = getXmiLight(resultVersion, services, subtype);
179 if (LOGGER.isDebugEnabled()) {
180 LOGGER.debug("XMI Light: " + new String(XmlHelper.xmlToUtf8(xmiLight, true)));
181 }
182 return xmiLight;
183 } else {
184 return null;
185 }
186 }
187
188
189 private Node getXmiLight(AssetVersionValue resultVersion, AssetServices services, SubtypeEnum subtype) {
190 Object content = getRepresentationContent(resultVersion, RepresentationTypeEnum.XMI_LIGHT, services);
191 if (content instanceof Node) {
192 if (LOGGER.isDebugEnabled()) {
193 LOGGER.debug("Found XMI Light representation for UML model asset " + resultVersion.getAsset());
194 }
195 return (Node) content;
196 }
197
198 Node xmiLight = generateXmiLight(resultVersion, services, subtype);
199 if (LOGGER.isDebugEnabled()) {
200 LOGGER.debug("Generated XMI Light representation for UML model asset " + resultVersion.getAsset()
201 + ":\n" + new String(XmlHelper.xmlToUtf8(xmiLight, true)));
202 }
203 if (xmiLight != null) {
204
205 try {
206 Representation xmiLightRepresentation =
207 Representation.create(RepresentationTypeEnum.XMI_LIGHT.toString(),
208 null,
209 MimeTypeEnum.TEXT_XML,
210 xmiLight,
211 Calendar.getInstance());
212 Asset asset = Asset.getAssetById(resultVersion.getAsset().getId());
213 boolean alreadyCheckedOut = false;
214 try {
215 asset.checkOut();
216 } catch (AlreadyLockedException e) {
217 alreadyCheckedOut = true;
218 }
219 asset.addRepresentation(xmiLightRepresentation);
220
221 asset.checkIn("Added XMI light representation");
222 if (alreadyCheckedOut) {
223 asset.checkOut();
224 }
225 } catch (Exception e) {
226 LOGGER.warn("Unable to add XMI light representation to UML model asset " + resultVersion.getAsset(), e);
227 }
228 }
229 return xmiLight;
230 }
231
232 private Node generateXmiLight(AssetVersionValue resultVersion, AssetServices services, SubtypeEnum subtype) {
233 Node xmiLight = null;
234 Object content = getRepresentationContent(resultVersion, RepresentationTypeEnum.DGM_MODEL, services);
235 if (content != null) {
236 if (!(content instanceof Node)) {
237 LOGGER.warn("CORAS UML model content not XML");
238 return null;
239 }
240 xmiLight = DgmTransformer.getTransformer().getXmiLight((Node) content);
241 } else {
242 content = getRepresentationContent(resultVersion, RepresentationTypeEnum.XMI_MODEL, services);
243 if (content != null) {
244 if (!(content instanceof Node)) {
245 LOGGER.warn("XMI model content not XML");
246 return null;
247 }
248 xmiLight = XmiLightTransformer.getTransformer().getXmiLight((Node) content);
249 } else {
250 content = getRepresentationContent(resultVersion, RepresentationTypeEnum.ZUMLZARGO_MODEL, services);
251 if (content instanceof byte[]) {
252 try {
253 Node xmi = XmiReader.getZumlZargoXmi(new ByteArrayInputStream((byte[]) content));
254 xmiLight = XmiLightTransformer.getTransformer().getXmiLight(xmi);
255 } catch (Exception e) {
256 LOGGER.warn("Unable to extract XMI from Poseidon/ArgoUML model", e);
257 }
258 } else {
259 return null;
260 }
261 }
262 }
263 Element rootElem = XmlHelper.getRootElement(xmiLight);
264 if (rootElem != null) {
265 rootElem.setAttribute("type", subtype.toString());
266 }
267 return rootElem;
268 }
269
270 /***
271 * @param resultVersion
272 * @param string
273 * @return
274 */
275 private Object getRepresentationContent(AssetVersionValue resultVersion, RepresentationTypeEnum type, AssetServices services) {
276
277 if (resultVersion == null || type == null)
278 return null;
279 Collection representations = resultVersion.getRepresentations();
280 if (representations == null)
281 return null;
282 for (Iterator i = representations.iterator(); i.hasNext(); ) {
283 AssetRepresentationPK representationPK = (AssetRepresentationPK) i.next();
284 try {
285 AssetRepresentationValue representation = services.getAssetRepresentation(representationPK);
286
287 if (type == RepresentationTypeEnum.forName(representation.getType())) {
288 return representation.getContent();
289 }
290 } catch (Exception e) {
291 e.printStackTrace();
292 }
293 }
294 return null;
295 }
296
297
298 }