001package org.biojava.naming; 002 003import java.util.Hashtable; 004 005import javax.naming.Context; 006import javax.naming.Name; 007import javax.naming.NamingException; 008import javax.naming.directory.BasicAttributes; 009import javax.naming.spi.InitialContextFactory; 010import javax.xml.parsers.SAXParserFactory; 011 012import org.biojava.utils.ClassTools; 013import org.xml.sax.Attributes; 014import org.xml.sax.InputSource; 015import org.xml.sax.SAXException; 016import org.xml.sax.XMLReader; 017import org.xml.sax.helpers.DefaultHandler; 018 019/** 020 * 021 * 022 * @author Matthew Pocock 023 */ 024public class ObdaInitialContextFactory 025 implements InitialContextFactory 026{ 027 private static final String CORE = "obda/naming/core.xml"; 028 029 public Context getInitialContext(Hashtable environment) 030 throws NamingException 031 { 032 try { 033 InputSource iSource = new InputSource(ClassTools.getClassLoader(ObdaInitialContextFactory.class).getResourceAsStream(CORE)); 034 SAXParserFactory spf = SAXParserFactory.newInstance(); 035 spf.setValidating(false); 036 spf.setNamespaceAware(true); 037 XMLReader reader = spf.newSAXParser().getXMLReader(); 038 ObdaHandler handler = new ObdaHandler(environment); 039 reader.setContentHandler(handler); 040 reader.parse(iSource); 041 return handler.getRoot(); 042 } catch (Exception e) { 043 throw new Error(e); 044 } 045 } 046 047 private class ObdaHandler 048 extends DefaultHandler 049 { 050 Hashtable env; 051 ObdaContext root; 052 ObdaContext current; 053 StringBuffer description = null; 054 055 ObdaHandler(Hashtable env) 056 { 057 this.env = env; 058 } 059 060 public ObdaContext getRoot() 061 { 062 return root; 063 } 064 065 public void startDocument() 066 throws SAXException 067 { 068 root = new ObdaContext(null, null, 069 new Hashtable(), env, new BasicAttributes()); 070 } 071 072 public void startElement(String uri, String localName, 073 String qName, Attributes attributes) 074 throws SAXException 075 { 076 if(qName.equals("directory")) { 077 // do directory things 078 } else if(qName.equals("urn")) { 079 // unpack the URN, break it into words, make the contexts (if needed) 080 try { 081 Name name = ObdaUriParser.getInstance() 082 .parse(attributes.getValue("name")); 083 ObdaContext ctxt = root; 084 for(int i = 0; i < name.size(); i++) { 085 ctxt = resolve(ctxt, name.get(i)); 086 } 087 current = ctxt; 088 } catch (NamingException e) { 089 throw new SAXException(e); 090 } 091 } else if(qName.equals("description")) { 092 // add the description to the current context - we will first have to 093 // collect all the description text together and then set it on 094 // end element 095 description = new StringBuffer(); 096 } 097 } 098 099 public void endElement(String uri, String localName, String qName) 100 throws SAXException 101 { 102 if(qName.equals("description") && description != null) { 103 current.getAttrs().put("description", description.toString()); 104 description = null; 105 } 106 } 107 108 public void characters(char ch[], int start, int length) 109 throws SAXException 110 { 111 if(description != null) { 112 description.append(ch, start, length); 113 } 114 } 115 116 private ObdaContext resolve(ObdaContext parent, String name) 117 { 118 Hashtable bindings = parent.getBindings(); 119 ObdaContext child = (ObdaContext) bindings.get(name); 120 121 if(child == null) { 122 child = new ObdaContext( 123 parent, name, 124 new Hashtable(), new Hashtable(), new BasicAttributes()); 125 bindings.put(name, child); 126 } 127 128 return child; 129 } 130 } 131}