View Javadoc
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   * SClassLoader for {@link SClass}es. 
20   *
21   *
22   * Created: Wed Apr 20 21:56:45 2005
23   *
24   * @author <a href="mailto:ernst.reissner@simuline.eu">Ernst Reissner</a>
25   * @version 1.0
26   */
27  public final class SClassLoader {
28  
29      /* -------------------------------------------------------------------- *
30       * attributes.                                                          *
31       * -------------------------------------------------------------------- */
32  
33      private final URL library;
34  
35      private final Map<ClassLocator, SClass> name2class;
36  
37      //private SClassParser scParser;
38  
39      /* -------------------------------------------------------------------- *
40       * constructors.                                                        *
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       * methods.                                                             *
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  	    // try to resolve path and remove step by step entry i-1
68  
69  	    path.remove(i);
70  
71  	    // i points to the first entry of locPath within path 
72  	    ClassLocator currLoc  = ClassLocator.getLocator(path);
73  
74  	    SClass sClass = this.name2class.get(currLoc);
75  	    if (sClass != null) {
76  		return sClass;
77  	    }
78  	    // Here, class currLoc may not yet be resolved. 
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// NOPMD
90  		    ("Could not locate file because no uri: " + 
91  		     url + ". ");
92  	    }
93  
94  	} // for 
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 } // SClassLoader