1 package jfun.yan.xml; 2 3 import java.io.File ; 4 import java.io.FileInputStream ; 5 import java.io.IOException ; 6 import java.io.InputStream ; 7 import java.net.URL ; 8 import java.util.HashMap ; 9 import java.util.Map ; 10 11 import javax.xml.parsers.ParserConfigurationException ; 12 import javax.xml.parsers.SAXParser ; 13 import javax.xml.parsers.SAXParserFactory ; 14 15 import org.xml.sax.InputSource ; 16 import org.xml.sax.SAXException ; 17 import org.xml.sax.XMLReader ; 18 19 import jfun.util.Misc; 20 import jfun.util.dict.Dict; 21 import jfun.yan.Component; 22 import jfun.yan.ParameterBinder; 23 import jfun.yan.PropertyBinder; 24 import jfun.yan.lifecycle.DefaultLifecycleManager; 25 import jfun.yan.util.deserializer.Deserializer; 26 import jfun.yan.util.resource.ResourceLoader; 27 import jfun.yan.xml.nut.NutIntrospector; 28 29 30 final class Interpreter implements Runtime , java.io.Serializable { 31 private final File basedir; 33 private final HashMap module_cache; 39 private final Dict initial_frame; 41 private final Dict compile_context; 42 private final NutsProcessor processor; 45 private static final NutIntrospector introspector = new NutIntrospector(); 46 47 static NutIntrospector getIntrospector() { 48 return introspector; 49 } 50 public File getBaseDir() { 51 return basedir; 52 } 53 public ClassLoader getClassloader() { 54 return processor.getClassLoader(); 55 } 56 public ResourceLoader getResourceLoader(){ 57 return processor.getResourceLoader(); 58 } 59 Map getExternalNuts() { 60 return processor.getExternalNuts(); 61 } 62 ParameterBinder getParameterWiring() { 63 return processor.getParameterWiring(); 64 } 65 PropertyBinder getPropertyWiring() { 66 return processor.getPropertyWiring(); 67 } 68 AutoWiringMap getCustomWiringModes(){ 69 return processor.getCustomWiringModes(); 70 } 71 Map getServices() { 72 return processor.getServices(); 73 } 74 SingletonMode getSingletonMode() { 75 return processor.getSingletonMode(); 76 } 77 Interpreter(NutsProcessor processor, Dict initial_frame, Dict compile_context) { 78 this(processor, processor.getBaseDir(), initial_frame, compile_context, new HashMap ()); 79 } 80 81 private Interpreter(NutsProcessor processor, 82 File basedir, Dict initial_frame, Dict compile_context, 83 HashMap module_cache) { 84 this.basedir = basedir; 85 this.processor = processor; 88 this.initial_frame = initial_frame; 89 this.compile_context = compile_context; 90 this.module_cache = module_cache; 92 } 99 Interpreter setBaseDir(File newbase){ 100 return new Interpreter(processor, newbase, initial_frame, compile_context, module_cache); 101 } 102 private Module interpretInputSource(Object id, InputSource src) 103 throws IOException { 104 try{ 105 final XMLReader reader = getXMLReader(); 106 SimpleHandler handler = new SimpleHandler(); 108 reader.setContentHandler(handler); 109 reader.setEntityResolver(handler); 110 reader.setErrorHandler(handler); 111 reader.setDTDHandler(handler); 112 reader.parse(src); 113 final Node result = handler.getResult(); 114 Compiler compiler = new Compiler (this); 117 final Module module = compiler.compileModule(id, result); 118 119 120 return module; 121 } 124 125 catch(SAXException e){ 126 throw new IllegalArgumentException (e.getMessage()); 127 } 128 } 129 134 Module interpretResource(final String resourcename) 135 throws IOException { 136 return interpretResource(this.getResourceLoader(), resourcename); 137 } 138 Module interpretResource(ResourceLoader loader, String resource) 139 throws IOException { 140 return interpretResource(loader, resource, null); 141 } 142 Module interpretResource(ResourceLoader loader, String resource, 143 Location loc) 144 throws IOException { 145 final URL url = loader.getResource(resource); 146 final InputStream in = loader.getResourceAsStream(resource); 147 if(url==null || in == null){ 148 throw new ConfigurationException( 149 "failed to load resource " + resource, 150 loc); 151 } 152 try{ 153 return interpretResource(url, in, loc); 154 } 155 finally{ 156 in.close(); 157 } 158 } 159 164 Module interpretFile(String filename) 165 throws IOException , CyclicModuleDependencyException{ 166 filename = filename.trim(); 167 return interpretFile(new File (filename)); 168 } 169 170 Module interpretFile(File file) 171 throws IOException , CyclicModuleDependencyException{ 172 return interpretFile(file, null); 173 } 174 175 Module interpretFile(String filename, Location loc) 176 throws IOException , CyclicModuleDependencyException{ 177 return interpretFile(new File (filename), loc); 178 } 179 private Module interpretFile(File file, Location loc) 180 throws IOException , CyclicModuleDependencyException{ 181 file = Misc.getAbsolutePath(basedir, file); 182 final File newbase = file.getParentFile(); 183 final FileInputStream in = new FileInputStream (file); 184 try{ 185 return setBaseDir(newbase).interpret(file, in); 186 } 189 finally{ 190 in.close(); 191 } 192 } 193 Module interpret(Object id, InputStream in) 194 throws IOException { 195 return interpretResource(id, in, null); 196 } 197 Module interpretResource(Object id, InputStream in, Location loc) 198 throws IOException , CyclicModuleDependencyException{ 199 return interpret(id, new InputSource (in), loc); 200 } 201 Module interpret(Object id, InputSource src) 202 throws IOException , CyclicModuleDependencyException{ 203 return interpret(id, src, null); 204 } 205 private Module interpret(Object id, InputSource src, Location loc) 206 throws IOException , CyclicModuleDependencyException{ 207 synchronized(module_cache){ 208 final Object m = module_cache.get(id); 209 if(m==null){ 210 module_cache.put(id, Boolean.valueOf(true)); 211 final String idstr = id.toString(); 212 src.setPublicId(idstr); 213 src.setSystemId(idstr); 214 boolean ok = false; 215 try{ 216 final Module ret = interpretInputSource(id, src); 217 module_cache.put(id, ret); 218 processor.registerModuleImport(id); 219 ok = true; 220 return ret; 221 } 222 finally{ 223 if(!ok){ 224 module_cache.remove(id); 225 } 226 } 227 } 228 else if(m instanceof Module){ 229 return (Module)m; 231 } 232 else{ 233 throw new CyclicModuleDependencyException("cyclic import detected.", loc); 234 } 235 } 236 } 237 238 private XMLReader getXMLReader() 239 throws SAXException { 240 try{ 241 final SAXParserFactory factory = SAXParserFactory.newInstance(); 242 factory.setNamespaceAware(true); 243 final SAXParser parser = factory.newSAXParser(); 244 245 return parser.getXMLReader(); 246 } 247 catch(ParserConfigurationException e){ 248 e.printStackTrace(); 249 throw new IllegalStateException ("parser configuration error: "+e.getMessage()); 250 } 251 } 252 Dict getInitialCompileContext(){ 253 return compile_context.copy(); 255 } 256 public Dict getFrame() { 257 return initial_frame; 258 } 259 260 public DefaultLifecycleManager getLifecycleManager() { 261 return processor.getLifecycleManager(); 262 } 263 void registerEagerInstantiation(UID key, Component c){ 264 processor.registerEagerInstantiation(key, c); 265 } 266 void registerDynamic(Object key, Object val, 267 boolean overridable, boolean overriding, Location loc){ 268 processor.register(key, val, overridable, overriding, loc); 269 } 270 Object deserialize(Class type, String text) 271 throws Throwable { 272 return processor.deserialize(type, text); 273 } 274 boolean isDeserializable(Class type){ 275 return processor.isDeserializable(type); 276 } 277 void registerDeserializer(Class type, Deserializer deserializer, 278 boolean overriding, boolean mandatory){ 279 processor.registerDeserializer(type, deserializer, 280 overriding, mandatory); 281 } 282 } 283 | Popular Tags |