1 package eu.simuline.relana.model;
2
3 import eu.simuline.relana.parser.SClassParser;
4 import org.antlr.v4.runtime.RecognitionException;
5
6 import java.net.URL;
7 import java.net.URISyntaxException;
8
9 import java.io.File;
10 import java.io.IOException;
11 import java.io.InputStream;
12
13 import java.util.List;
14 import java.util.ArrayList;
15 import java.util.Map;
16 import java.util.HashMap;
17
18
19
20
21
22
23
24
25
26
27 public final class SClassLoader {
28
29
30
31
32
33 private final URL library;
34
35 private final Map<ClassLocator, SClass> name2class;
36
37
38
39
40
41
42
43 public SClassLoader(URL library) {
44 this.library = library;
45 this.name2class = new HashMap<ClassLocator, SClass>();
46 this.name2class.put(new ClassLocator(SClass.BOOL_S_CLASS_NAME,
47 Package.BUILD_IN),
48 SClass.BOOLEAN);
49 }
50
51
52
53
54
55 public SClass loadSClass(ClassLocator loc,
56 Package pkg,
57 Map<ClassLocator, ClassLocator> subclassDep)
58 throws IOException, RecognitionException {
59
60 URL url = null;
61 List<String> pkgPath = pkg.getPath();
62 List<String> path = new ArrayList<String>(pkgPath);
63 path.add("_");
64 path.addAll(loc.getPath());
65
66 for (int i = pkgPath.size(); i >= 0; i--) {
67
68
69 path.remove(i);
70
71
72 ClassLocator currLoc = ClassLocator.getLocator(path);
73
74 SClass sClass = this.name2class.get(currLoc);
75 if (sClass != null) {
76 return sClass;
77 }
78
79 try {
80 url = new URL(this.library +
81 currLoc.getPackage().getPathName()
82 .replace('.', '/') +
83 currLoc.getName() + ".scl");
84 File clsDoc = new File(url.toURI());
85 if (clsDoc.exists()) {
86 return resolveSClass(currLoc, subclassDep);
87 }
88 } catch (URISyntaxException e) {
89 throw new IOException
90 ("Could not locate file because no uri: " +
91 url + ". ");
92 }
93
94 }
95
96 throw new IOException("Found no class file for " +
97 loc + " in " + pkg + ". ");
98 }
99
100
101 public SClass loadSClass(ClassLocator loc,
102 Package pkg)
103 throws IOException, RecognitionException {
104 return loadSClass(loc, pkg, new HashMap<ClassLocator, ClassLocator>());
105 }
106
107 private SClass resolveSClass(ClassLocator loc,
108 Map<ClassLocator, ClassLocator> subclassDep)
109 throws IOException, RecognitionException {
110 InputStream str = new URL(this.library +
111 loc.getPackage().getPathName()
112 .replace('.', '/') +
113 loc.getName() + ".scl")
114 .openStream();
115 SClassParser scParser = new SClassParser(str);
116 scParser.setClassLoader(this);
117 SClass sClass = scParser.getSClass(loc, subclassDep);
118
119 sClass.verify();
120 this.name2class.put(loc, sClass);
121 return sClass;
122 }
123
124 }