1 package coras.fta;
2
3 import java.io.BufferedReader;
4 import java.io.EOFException;
5 import java.io.File;
6 import java.io.FileReader;
7 import java.io.IOException;
8 import java.io.OutputStream;
9 import java.util.HashMap;
10 import java.util.Map;
11 import java.util.StringTokenizer;
12
13 import javax.xml.bind.JAXBContext;
14 import javax.xml.bind.JAXBException;
15 import javax.xml.bind.Marshaller;
16
17 import no.sintef.file.FileSuffixFilter;
18 import no.sintef.file.IOUtils;
19 import coras.fta.jaxb.BasicInitiatingEventType;
20 import coras.fta.jaxb.EventType;
21 import coras.fta.jaxb.ExternalEventType;
22 import coras.fta.jaxb.FaultTree;
23 import coras.fta.jaxb.FaultTreeType;
24 import coras.fta.jaxb.GateType;
25 import coras.fta.jaxb.IntermediateNodeType;
26 import coras.fta.jaxb.ObjectFactory;
27 import coras.fta.jaxb.UndevelopedEventType;
28 import coras.representations.RepresentationTypeEnum;
29
30 public class OpenFTAParser {
31
32 private static final boolean DEBUG = false;
33 private ObjectFactory of;
34 private Marshaller marshaller;
35
36 public static void main(String[] args) throws JAXBException, IOException {
37 OpenFTAParser parser = new OpenFTAParser();
38 File inputFile = IOUtils.showOpenDialog("C://MyApps//OpenFTA//examples//", RepresentationTypeEnum.FAULT_TREE_MODEL.getFileFilters(), null);
39 FaultTree ft = parser.parse(inputFile);
40 parser.serialize(ft, System.out);
41 }
42
43 public OpenFTAParser() throws JAXBException {
44 of = new ObjectFactory();
45 JAXBContext context = JAXBContext.newInstance("coras.fta.jaxb");
46 marshaller = context.createMarshaller();
47 }
48
49 public void serialize(FaultTreeType ft, OutputStream os) throws JAXBException {
50 marshaller.marshal(ft, os);
51 }
52
53 public FaultTree parse(File f) throws JAXBException, IOException {
54 if (f == null || !f.exists() || !f.isFile() || !f.canRead()) {
55 return null;
56 }
57 File dir = f.getParentFile();
58 Map eventMap = null;
59 FaultTree result = of.createFaultTree();
60 BufferedReader br = new BufferedReader(new FileReader(f));
61 String s = br.readLine();
62 if (! "NULL".equals(s)) {
63 eventMap = parseEvents(result, new File(dir, s));
64 }
65
66 br.readLine();
67
68
69 s = br.readLine();
70 if (!s.trim().equals("0")) {
71 int length = Integer.parseInt(s.substring(0, s.indexOf(' ')));
72 String description = s.substring(s.indexOf(' '));
73 while (length > description.length()) {
74 description += "\n" + br.readLine();
75 }
76 result.setDescription(description);
77 }
78
79 IntermediateNodeType topItem = parseIntermediateNode(br, br.readLine(), eventMap);
80 result.setTopItem(topItem);
81 String prefix = FileSuffixFilter.getPrefix(f.getName());
82 File reportFile = new File(dir, prefix + ".mrp");
83 if (reportFile.exists()) {
84 try {
85 topItem.setProbability(parseMonteCarloReport(reportFile));
86 } catch (Exception e) {
87 System.err.println("Error reading Monte Carlo report: " + e);
88 }
89 }
90 return result;
91 }
92
93 private double parseMonteCarloReport(File reportFile) throws IOException {
94 BufferedReader br = new BufferedReader(new FileReader(reportFile));
95 String s;
96 while ((s = br.readLine()) != null) {
97 if (s.startsWith("Probability of top event")) {
98 s = s.substring(s.indexOf('=') + 1).trim();
99 s = s.substring(0, s.indexOf(' '));
100 return Double.parseDouble(s);
101 }
102 }
103 throw new EOFException();
104 }
105
106 private IntermediateNodeType parseIntermediateNode(BufferedReader br, String s, Map eventMap) throws IOException, JAXBException {
107 if (DEBUG) {
108 System.out.println("Parsing intermediate node: " + s);
109 }
110 while (s.trim().length() == 0) {
111 s = br.readLine();
112 }
113 char type = s.charAt(0);
114 StringTokenizer tokenizer = new StringTokenizer(s.substring(2), " ");
115 IntermediateNodeType node = of.createIntermediateNodeType();
116 String id = tokenizer.nextToken();
117 int numChildren = Integer.parseInt(tokenizer.nextToken());
118 if (! "NULL".equals(id)) {
119 node.setId("I" + id);
120 }
121
122
123 s = br.readLine();
124 if (!s.trim().equals("0")) {
125 int length = Integer.parseInt(s.substring(0, s.indexOf(' ')));
126 String description = s.substring(s.indexOf(' ') + 1);
127 while (description.length() < length) {
128 description += "\n" + br.readLine();
129 }
130 if (! "NULL".equals(description)) {
131 node.setDescription(description);
132 }
133 }
134 for (int i = 0; i < numChildren; i++) {
135 s = br.readLine();
136 type = s.charAt(0);
137 switch (type) {
138 case 'M' :
139 node.setIntermediateNode(parseIntermediateNode(br, s, eventMap));
140 break;
141 case 'B' :
142 node.setBasicEvent(parseBasicEvent(br, s, eventMap));
143 break;
144 case 'U' :
145 node.setUndevelopedEvent(parseUndevelopedEvent(br, s, eventMap));
146 break;
147 case 'E' :
148 node.setExternalEvent(parseExternalEvent(br, s, eventMap));
149 break;
150 default :
151 GateType gate = parseGate(br, s, eventMap);
152 if (gate != null) {
153 node.setGate(gate);
154 }
155 }
156 }
157 return node;
158 }
159
160 private BasicInitiatingEventType parseBasicEvent(BufferedReader br, String s, Map eventMap) throws JAXBException, IOException {
161 if (DEBUG) {
162 System.out.println("Parsing basic event: " + s);
163 }
164 char type = s.charAt(0);
165 BasicInitiatingEventType basicEvent = of.createBasicInitiatingEventType();
166 StringTokenizer tokenizer = new StringTokenizer(s.substring(2), " ");
167 String id = tokenizer.nextToken();
168 if (eventMap != null) {
169 basicEvent.setEvent(eventMap.get(id));
170 }
171 return basicEvent;
172 }
173
174 private UndevelopedEventType parseUndevelopedEvent(BufferedReader br, String s, Map eventMap) throws JAXBException, IOException {
175 if (DEBUG) {
176 System.out.println("Parsing undeveloped event: " + s);
177 }
178 char type = s.charAt(0);
179 UndevelopedEventType undevelopedEvent = of.createUndevelopedEventType();
180 StringTokenizer tokenizer = new StringTokenizer(s.substring(2), " ");
181 String id = tokenizer.nextToken();
182 if (eventMap != null) {
183 undevelopedEvent.setEvent(eventMap.get(id));
184 }
185 return undevelopedEvent;
186 }
187
188 private ExternalEventType parseExternalEvent(BufferedReader br, String s, Map eventMap) throws JAXBException, IOException {
189 if (DEBUG) {
190 System.out.println("Parsing undeveloped event: " + s);
191 }
192 char type = s.charAt(0);
193 ExternalEventType externalEvent = of.createExternalEventType();
194 StringTokenizer tokenizer = new StringTokenizer(s.substring(2), " ");
195 String id = tokenizer.nextToken();
196 if (eventMap != null) {
197 externalEvent.setEvent(eventMap.get(id));
198 }
199 return externalEvent;
200 }
201
202 private GateType parseGate(BufferedReader br, String s, Map eventMap) throws JAXBException, IOException {
203 if (DEBUG) {
204 System.out.println("Parsing gate: " + s);
205 }
206 char type = s.charAt(0);
207 GateType gate = of.createGateType();
208 switch (type) {
209 case 'A' :
210 gate.setType("AND");
211 break;
212 case 'O' :
213 gate.setType("OR");
214 break;
215 default :
216 System.err.println("Unknown gate type: " + type);
217 return null;
218 }
219 StringTokenizer tokenizer = new StringTokenizer(s.substring(2), " ");
220 String id = tokenizer.nextToken();
221 if (! "NULL".equals(id)) {
222 gate.setId("I" + id);
223 }
224 int numChildren = Integer.parseInt(tokenizer.nextToken());
225 for (int i = 0; i < numChildren; i++) {
226 s = br.readLine();
227 type = s.charAt(0);
228 switch (type) {
229 case 'M' :
230 gate.getIntermediateNode().add(parseIntermediateNode(br, s, eventMap));
231 break;
232 case 'B' :
233 gate.getBasicEvent().add(parseBasicEvent(br, s, eventMap));
234 break;
235 case 'U' :
236 gate.getUndevelopedEvent().add(parseUndevelopedEvent(br, s, eventMap));
237 break;
238 case 'E' :
239 gate.getExternalEvent().add(parseExternalEvent(br, s, eventMap));
240 break;
241 default :
242 GateType child = parseGate(br, s, eventMap);
243 if (child != null) {
244 gate.getGate().add(child);
245 }
246 }
247 }
248 return gate;
249 }
250
251 private Map parseEvents(FaultTree ft, File f) throws IOException, JAXBException {
252 Map eventMap = new HashMap();
253 BufferedReader br = new BufferedReader(new FileReader(f));
254 String s;
255 while ((s = br.readLine()) != null) {
256 if (DEBUG) {
257 System.out.println("Parsing event: " + s);
258 }
259 EventType event = of.createEventType();
260 StringTokenizer tokenizer = new StringTokenizer(s, ";", true);
261 String id = tokenizer.nextToken();
262 eventMap.put(id, event);
263 event.setId("I" + id);
264
265 tokenizer.nextToken();
266 String tok = tokenizer.nextToken();
267 if (!";".equals(tok)) {
268 tokenizer.nextToken();
269 }
270
271 String type = tokenizer.nextToken();
272 if (type.charAt(0) == 'U') {
273 event.setUndeveloped(true);
274 }
275
276 tokenizer.nextToken();
277
278 String description = tokenizer.nextToken();
279 if (";".equals(description)) {
280 description = null;
281 } else {
282 tokenizer.nextToken();
283 }
284
285
286 String probabilityString;
287 if (tokenizer.hasMoreTokens()) {
288 probabilityString = tokenizer.nextToken();
289 } else {
290 int index;
291 do {
292 s = br.readLine();
293 index = s.indexOf(';');
294 description += "\n" + (index != -1 ? s.substring(0, index) : s);
295 } while (index == -1);
296 s = s.substring(index + 1);
297 probabilityString = s.substring(0, s.indexOf(';'));
298 }
299 if (description != null) {
300 event.setDescription(description);
301 }
302 double probability = Double.parseDouble(probabilityString);
303 event.setProbability(probability);
304 ft.getEvent().add(event);
305 }
306 return eventMap;
307 }
308
309 }