1 package org.lcsim.material;
2
3 import java.io.IOException;
4 import java.util.HashMap;
5 import java.util.LinkedHashMap;
6 import java.util.List;
7 import java.util.Map;
8
9 import org.jdom.Document;
10 import org.jdom.Element;
11 import org.jdom.JDOMException;
12 import org.jdom.input.SAXBuilder;
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 public class XMLMaterialManager
36 {
37
38 private static final String elementResource = "elements.xml";
39
40
41 private static final String materialResource = "materials.xml";
42
43
44 private static MaterialManager mgr;
45
46
47 private static XMLMaterialManager elements;
48
49
50 private static XMLMaterialManager materials;
51
52
53 private XMLMaterialManager parent;
54
55
56 private Document currentDoc;
57
58
59 private HashMap<String, org.jdom.Element> materialMap = new LinkedHashMap<String, Element>();
60
61
62 private HashMap<String, org.jdom.Element> elementMap = new LinkedHashMap<String, Element>();
63
64
65
66
67
68
69 public static void setup()
70 {
71
72 MaterialManager.instance().clear();
73 mgr = MaterialManager.instance();
74
75
76 elements = createMaterialElements();
77 materials = createMaterials();
78 }
79
80
81
82
83
84
85
86 public XMLMaterialManager(Element materialsRoot)
87 {
88
89 if (elements == null)
90 {
91 setup();
92 }
93 parent = getDefaultMaterialManager();
94 setMaterialsRoot(materialsRoot);
95 loadMaterialsFromXML(materialsRoot);
96 }
97
98
99
100
101
102 public static XMLMaterialManager getDefaultMaterialManager()
103 {
104
105 if (elements == null)
106 {
107 setup();
108 }
109 return materials;
110 }
111
112
113
114
115
116 public static XMLMaterialManager getElementsManager()
117 {
118
119 if (elements == null)
120 {
121 setup();
122 }
123 return elements;
124 }
125
126
127
128
129
130 public Map<String, Element> getMaterialXMLMap()
131 {
132 return materialMap;
133 }
134
135
136
137
138
139 public Map<String, Element> getElementXMLMap()
140 {
141 return elementMap;
142 }
143
144
145
146
147
148
149 public void addMaterialRef(org.jdom.Element e)
150 {
151 materialMap.put(e.getAttributeValue("name"), e);
152 }
153
154
155
156
157
158
159 public void addMaterialElementRef(org.jdom.Element e)
160 {
161 elementMap.put(e.getAttributeValue("name"), e);
162 }
163
164
165
166
167
168
169 public org.jdom.Element getMaterialXML(String matName)
170 {
171 org.jdom.Element m = materialMap.get(matName);
172
173 if (m == null)
174 {
175 if (hasParentManager())
176 {
177 m = parent.getMaterialXML(matName);
178 }
179 }
180
181 return m;
182 }
183
184
185
186
187
188
189 public org.jdom.Element getMaterialElementXML(String elemName)
190 {
191 org.jdom.Element e = elementMap.get(elemName);
192
193 if (e == null)
194 {
195 if (hasParentManager())
196 {
197 e = parent.getMaterialElementXML(elemName);
198 }
199 }
200
201 return e;
202 }
203
204
205
206
207
208 public Element findMaterialElementXML(String elemName, Document d)
209 {
210 org.jdom.Element me = getMaterialsRoot(d);
211 org.jdom.Element fnd = null;
212 for (Object o : me.getChildren("element"))
213 {
214 org.jdom.Element curr = (org.jdom.Element)o;
215 if (curr.getAttributeValue("name").equals(elemName))
216 {
217 fnd = curr;
218 break;
219 }
220 }
221
222
223 if (fnd == null && hasParentManager())
224 {
225 fnd = parent.findMaterialElementXML(elemName);
226 }
227
228 return fnd;
229 }
230
231
232
233
234
235 public Document getCurrentDocument()
236 {
237 return currentDoc;
238 }
239
240
241
242
243
244
245
246 public org.jdom.Element findMaterialXML(String matName, Document d)
247 {
248 org.jdom.Element me = getMaterialsRoot(d);
249
250 org.jdom.Element fnd = null;
251 for (Object o : me.getChildren("material"))
252 {
253 org.jdom.Element curr = (org.jdom.Element)o;
254 if (curr.getAttributeValue("name").equals(matName))
255 {
256 fnd = curr;
257 break;
258 }
259 }
260
261
262 if (fnd == null && hasParentManager())
263 {
264 fnd = parent.findMaterialXML(matName);
265 }
266
267 return fnd;
268 }
269
270
271
272
273
274 static private XMLMaterialManager createMaterialElements()
275 {
276 elements = new XMLMaterialManager();
277 elements.loadElementsFromResource();
278 return elements;
279 }
280
281
282
283
284
285 static private XMLMaterialManager createMaterials()
286 {
287 materials = new XMLMaterialManager(elements);
288 materials.loadMaterialsFromResource(materialResource);
289 return materials;
290 }
291
292
293
294
295
296 private XMLMaterialManager()
297 {}
298
299
300
301
302
303 private XMLMaterialManager(XMLMaterialManager p)
304 {
305 parent = p;
306 }
307
308
309
310
311
312 private void setCurrentDocument(Document d)
313 {
314 currentDoc = d;
315 }
316
317
318
319
320
321 protected boolean hasParentManager()
322 {
323 return (parent != null);
324 }
325
326
327
328
329
330
331
332
333
334
335 private static org.jdom.Element getMaterialsRoot(Document d)
336 {
337 org.jdom.Element m = null;
338
339 if (d.getRootElement().getName() == "materials")
340 {
341 m = d.getRootElement();
342 }
343 else
344 {
345 m = d.getRootElement().getChild("materials");
346 }
347
348 return m;
349 }
350
351
352
353
354
355
356
357
358 private org.jdom.Element findMaterialElementXML(String elemName)
359 {
360 return findMaterialElementXML(elemName, currentDoc);
361 }
362
363
364
365
366
367
368 private org.jdom.Element findMaterialXML(String matName)
369 {
370 return findMaterialXML(matName, currentDoc);
371 }
372
373
374
375
376
377
378 private Document cloneMaterialsRoot(org.jdom.Element e)
379 {
380 org.jdom.Element matRoot = new org.jdom.Element("materials");
381 matRoot.setContent(e.cloneContent());
382 Document d = new Document();
383 d.setRootElement(matRoot);
384 setCurrentDocument(d);
385 return currentDoc;
386 }
387
388
389
390
391
392 public void setMaterialsRoot(org.jdom.Element e)
393 {
394 setCurrentDocument(cloneMaterialsRoot(e));
395 }
396
397
398
399
400
401 private void loadElementsFromResource()
402 {
403 SAXBuilder builder = new SAXBuilder();
404 Document doc = null;
405 try
406 {
407 doc = builder.build(XMLMaterialManager.class.getResourceAsStream(elementResource));
408 setCurrentDocument(doc);
409 }
410 catch (JDOMException e)
411 {
412 throw new RuntimeException(e);
413 }
414 catch (IOException e)
415 {
416 throw new RuntimeException(e);
417 }
418
419 Element root = doc.getRootElement();
420
421 setMaterialsRoot(root);
422
423 Map<String, Element> elementNodes = new HashMap();
424
425
426 for (Object x : root.getChildren())
427 {
428 Element node = (Element)x;
429
430
431 if (node.getName() == "element")
432 {
433 elementNodes.put(node.getAttributeValue("name"), node);
434
435
436 addMaterialElementRef(node);
437 }
438
439
440 if (node.getName() == "material")
441 {
442
443 addMaterialRef(node);
444
445
446 Element comp = node.getChild("composite");
447 String elemRef = comp.getAttributeValue("ref");
448 Element elemNode = elementNodes.get(elemRef);
449
450 if (elemNode == null)
451 throw new RuntimeException("Could not find element " + elemRef + " in map.");
452
453 String formula = elemNode.getAttributeValue("name");
454 double Z = Double.valueOf(elemNode.getAttributeValue("Z"));
455 Element anode = elemNode.getChild("atom");
456 double A = Double.valueOf(anode.getAttributeValue("value"));
457
458 Element radlenNode = node.getChild("RL");
459 double radlen = Double.valueOf(radlenNode.getAttributeValue("value"));
460 Element nilNode = node.getChild("NIL");
461 double nil = Double.valueOf(nilNode.getAttributeValue("value"));
462
463 Element densNode = node.getChild("D");
464 double density = Double.valueOf(densNode.getAttributeValue("value"));
465
466 String fullName = node.getAttributeValue("name");
467
468 MaterialState state = MaterialState.fromString(node.getAttributeValue("state"));
469
470 new org.lcsim.material.Material(fullName, formula, Z, A, density, radlen, nil, state);
471 }
472 }
473 }
474
475
476
477
478
479 private void loadMaterialsFromResource(String resource)
480 {
481
482 SAXBuilder builder = new SAXBuilder();
483 Document doc = null;
484 try
485 {
486 doc = builder.build(XMLMaterialManager.class.getResourceAsStream(resource));
487 }
488 catch (JDOMException e)
489 {
490 throw new RuntimeException(e);
491 }
492 catch (IOException e)
493 {
494 throw new RuntimeException(e);
495 }
496
497
498 Element root = doc.getRootElement();
499 setMaterialsRoot(root);
500
501
502 loadMaterialsFromXML(root);
503 }
504
505
506
507
508
509 private void loadMaterialsFromXML(Element materialsRoot)
510 {
511 for (Object o : materialsRoot.getChildren("material"))
512 {
513 makeMaterialFromXML((Element)o);
514 }
515 }
516
517
518
519
520
521 private void makeMaterialFromXML(Element matNode)
522 {
523
524 String name = matNode.getAttributeValue("name");
525
526
527 if (mgr.getMaterial(name) != null)
528 {
529
530
531 System.out.println("WARNING: Ignoring attempt to add material " + name + " that already exists!");
532 return;
533
534 }
535
536
537 addMaterialRef(matNode);
538
539
540 Element densNode = matNode.getChild("D");
541 if (densNode == null)
542 {
543 throw new RuntimeException("Missing required D element in material " + name + ".");
544 }
545 double density = Double.valueOf(densNode.getAttributeValue("value"));
546
547
548 MaterialState state = MaterialState.UNKNOWN;
549 if (matNode.getAttribute("state") != null)
550 {
551 String stateStr = matNode.getAttributeValue("state");
552 state = MaterialState.fromString(stateStr);
553 }
554
555
556 List fractions = matNode.getChildren("fraction");
557 List composites = matNode.getChildren("composite");
558
559
560 org.lcsim.material.Material mat = null;
561
562
563 int ncomp = 0;
564 if (fractions.size() > 0 && composites.size() > 0)
565 {
566 throw new RuntimeException("Cannot mix fraction and composite tags in material " + name + ".");
567 }
568 else if (fractions.size() > 0)
569 {
570 ncomp = fractions.size();
571 }
572 else
573 {
574 ncomp = composites.size();
575 }
576
577
578 mat = new org.lcsim.material.Material(name, ncomp, density, state);
579
580
581 if (matNode.getChildren("fraction").size() != 0)
582 {
583
584 for (Object oo : fractions)
585 {
586 Element fracNode = (Element)oo;
587 double frac = Double.valueOf(fracNode.getAttributeValue("n"));
588 String ref = fracNode.getAttributeValue("ref");
589 MaterialElement elem = mgr.getElement(ref);
590 if (elem != null)
591 {
592 mat.addElement(elem, frac);
593 }
594 else
595 {
596 org.lcsim.material.Material matFrac = mgr.getMaterial(ref);
597 if (matFrac == null)
598 {
599 throw new RuntimeException("Could not resolve ref to " + ref + ".");
600 }
601 mat.addMaterial(matFrac, frac);
602 }
603 }
604 }
605
606 else if (matNode.getChildren("composite").size() != 0)
607 {
608
609 for (Object oo : composites)
610 {
611 Element compNode = (Element)oo;
612 int n = Integer.valueOf(compNode.getAttributeValue("n"));
613 String ref = compNode.getAttributeValue("ref");
614 MaterialElement elem = mgr.getElement(ref);
615 if (elem == null)
616 {
617 throw new RuntimeException("Could not find referenced element " + ref + ".");
618 }
619 mat.addElement(elem, n);
620 }
621 }
622
623 else
624 {
625 throw new RuntimeException("Missing at least one fraction or composite element in material " + name + ".");
626 }
627 }
628
629
630 public void clearMaterialMap()
631 {
632 this.materialMap.clear();
633 }
634 }