001: /*
002: * Created on Oct 6, 2004
003: */
004: package uk.org.ponder.saxalizer;
005:
006: import java.io.InputStream;
007: import java.io.OutputStream;
008: import java.io.StringReader;
009:
010: import uk.org.ponder.saxalizer.mapping.MappableXMLProvider;
011: import uk.org.ponder.saxalizer.mapping.SAXalizerMapperEntry;
012: import uk.org.ponder.util.UniversalRuntimeException;
013:
014: /**
015: * @author Antranig Basman (antranig@caret.cam.ac.uk)
016: *
017: */
018: public class SAXalXMLProvider implements MappableXMLProvider {
019: private SAXalizerMappingContext mappingcontext;
020: private EntityResolverStash entityresolverstash;
021:
022: public void setEntityResolverStash(
023: EntityResolverStash entityresolverstash) {
024: this .entityresolverstash = entityresolverstash;
025: }
026:
027: public SAXalizerMappingContext getMappingContext() {
028: return mappingcontext;
029: }
030:
031: private ThreadLocal saxalizergetter = new ThreadLocal() {
032: public Object initialValue() {
033: SAXalizerHelper togo = new SAXalizerHelper(mappingcontext);
034: togo.setEntityResolverStash(entityresolverstash);
035: return togo;
036: }
037: };
038:
039: private DeSAXalizer getDeSAXalizer() {
040: return new DeSAXalizer(mappingcontext);
041: }
042:
043: public SAXalXMLProvider(SAXalizerMappingContext mappingcontext) {
044: this .mappingcontext = mappingcontext;
045: }
046:
047: public void writeXML(Object towrite, OutputStream os) {
048: DeSAXalizer desaxalizer = getDeSAXalizer();
049: String resourcename = mappingcontext.classnamemanager
050: .getClassName(towrite.getClass());
051: if (resourcename == null) {
052: throw new UniversalRuntimeException(
053: "Object of unknown type " + towrite.getClass()
054: + " supplied to writeXML");
055: }
056: try {
057: desaxalizer.serializeSubtree(towrite, resourcename, os);
058: } catch (Throwable t) {
059: throw UniversalRuntimeException.accumulate(t,
060: "Error writing object of class "
061: + towrite.getClass());
062: }
063: }
064:
065: public Object readXML(Object classorobject, InputStream is) {
066: SAXalizerHelper saxalizer = (SAXalizerHelper) saxalizergetter
067: .get();
068: Class objclass = classorobject == null ? null
069: : classorobject instanceof Class ? (Class) classorobject
070: : classorobject.getClass();
071: try {
072: Object toread = classorobject == null ? null
073: : classorobject == objclass ? objclass
074: .newInstance() : classorobject;
075: return saxalizer.produceSubtree(toread, is);
076: } catch (Throwable t) {
077: // Xerces appears to be crap and will not clear its parsing condition once it has
078: // been set - throw the whole helper away and start again.
079: saxalizergetter.set(new SAXalizerHelper(mappingcontext));
080: throw UniversalRuntimeException.accumulate(t,
081: "Error reading object of class " + objclass);
082: }
083: }
084:
085: public void loadMapping(InputStream is) {
086: SAXalizerMapperEntry entry = (SAXalizerMapperEntry) readXML(
087: SAXalizerMapperEntry.class, is);
088: mappingcontext.mapper.addEntry(entry);
089: }
090:
091: public void registerClass(String classname, Class resourceclass) {
092: mappingcontext.classnamemanager.registerClass(classname,
093: resourceclass);
094: }
095:
096: public String toString(Object towrite) {
097: return toString(towrite, true);
098: }
099:
100: public String toString(Object towrite, boolean compactmode) {
101: DeSAXalizer desaxalizer = getDeSAXalizer();
102: String resourcename = mappingcontext.classnamemanager
103: .getClassName(towrite.getClass());
104: if (resourcename == null) {
105: throw new UniversalRuntimeException(
106: "Object of unknown type " + towrite.getClass()
107: + " supplied to writeXML");
108: }
109: try {
110: return desaxalizer.toString(towrite, resourcename,
111: compactmode);
112: } catch (Throwable t) {
113: throw UniversalRuntimeException.accumulate(t,
114: "Error writing object of class "
115: + towrite.getClass());
116: }
117: }
118:
119: private Class findClass(String classname) {
120: Class objclass = mappingcontext.classnamemanager
121: .findClazz(classname);
122: if (objclass == null) {
123: throw new UniversalRuntimeException("Root tag " + classname
124: + " had no entry for object type");
125: }
126: return objclass;
127: }
128:
129: public Object fromString(String toread) {
130: int roottagi = toread.indexOf('<');
131: if (roottagi == -1) {
132: throw new UniversalRuntimeException(
133: "Couldn't find root tag in string " + toread);
134: }
135: int roottagt = roottagi + 1;
136:
137: int endtag = toread.indexOf('>', roottagi);
138: if (endtag == -1) {
139: throw new UniversalRuntimeException(
140: "Unterminated root tag in string " + toread);
141: }
142:
143: for (; roottagt < endtag; ++roottagt) {
144: char c = toread.charAt(roottagt);
145: // QQQQQ technically not correct, XML whitespace does not agree with Java.
146: if (Character.isWhitespace(c))
147: break;
148: }
149: String roottag = toread.substring(roottagi + 1, roottagt);
150: Class objclass = findClass(roottag);
151:
152: StringReader sr = new StringReader(toread);
153: SAXalizerHelper saxalizer = (SAXalizerHelper) saxalizergetter
154: .get();
155: try {
156: return saxalizer.produceSubtree(objclass.newInstance(), sr);
157: } catch (Throwable t) {
158: throw UniversalRuntimeException.accumulate(t,
159: "Error reading object of class " + objclass);
160: }
161: }
162:
163: }
|