001: // You can redistribute this software and/or modify it under the terms of
002: // the Ozone Core License version 1 published by ozone-db.org.
003: //
004: // The original code and portions created by SMB are
005: // Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
006: //
007: // $Id: Object2XML.java,v 1.1 2001/12/18 10:31:31 per_nyfelt Exp $
008:
009: package org.ozoneDB.core.xml;
010:
011: import java.util.*;
012: import java.io.*;
013: import java.lang.reflect.*;
014:
015: import org.xml.sax.*;
016: import org.xml.sax.helpers.*;
017:
018: import org.ozoneDB.OzoneProxy;
019: import org.ozoneDB.OzoneInterface;
020: import org.ozoneDB.core.ObjectContainer;
021:
022: /**
023: * This class transform an Object into XML.
024: *
025: * @version $Revision: 1.1 $
026: * @author <a href="http://www.softwarebuero.de">SMB</a>
027: */
028:
029: public class Object2XML implements Consts {
030:
031: //
032: // member
033: //
034:
035: /**
036: * ObjCache saves the references of the processed objects.
037: */
038: private Hashtable objCache = new Hashtable();
039:
040: /**
041: * This flag decides if transient member will be serialized or not.
042: */
043: private boolean serializeTransientFlag = false;
044:
045: /**
046: * ... for making SAX.
047: */
048: private ContentHandler ch;
049:
050: /**
051: * Factory for the attributes of the first obj-Tag.
052: */
053: private ObjAttsFactory oaf;
054:
055: //
056: // construcor
057: //
058:
059: /**
060: * @param docHandler
061: */
062: public Object2XML(ContentHandler contHandler) {
063: ch = contHandler;
064: oaf = new OzoneObjAttsFactory();
065: }
066:
067: /**
068: * @param docHandler
069: * @param serializeTransientFlag
070: */
071: public Object2XML(ContentHandler contHandler,
072: boolean serializeTransientFlag) {
073: this (contHandler);
074: this .serializeTransientFlag = serializeTransientFlag;
075: }
076:
077: //
078: // methods
079: //
080:
081: /**
082: * ToXML(obj) gets an object and serialize this object into XML.
083: *
084: * @param obj (the Object)
085: */
086: public void toXML(Object obj) throws SAXException {
087: // ch.startDocument();
088: writeObjStartTag(obj.getClass().getName(), getID(obj), oaf
089: .additionallyAtts(obj));
090: objCache.put(getID(obj), getID(obj));
091:
092: getMember(obj, obj.getClass());
093:
094: writeObjEndTag();
095: // ch.endDocument();
096: }
097:
098: /**
099: * GetMember gets the informations (name/type/value)
100: * of all members (private and protected too) !!
101: *
102: * @param obj (the Object)
103: * @param objClass (the Class of the Object)
104: */
105: protected void getMember(Object obj, Class objClass)
106: throws SAXException {
107: // System.out.println( "getMember(): " + objClass.getName() );
108:
109: Field[] fds = objClass.getDeclaredFields();
110:
111: AccessibleObject.setAccessible(fds, true);
112: for (int i = 0; i < fds.length; i++) {
113: Field fd = fds[i];
114:
115: // avoid converting the container of a database object
116: if (ObjectContainer.class.isAssignableFrom(fd.getType())) {
117: continue;
118: }
119: if (OzoneInterface.class.isAssignableFrom(fd.getType())) {
120: continue;
121: }
122: if (Modifier.isStatic(fd.getModifiers())) {
123: continue;
124: }
125: if (!serializeTransientFlag
126: && Modifier.isTransient(fd.getModifiers())) {
127: continue;
128: }
129:
130: String memberName = fd.getName();
131:
132: try {
133:
134: Object value = fd.get(obj);
135: if (value instanceof org.ozoneDB.OzoneProxy)
136: handleOzoneProxyMember(memberName,
137: (OzoneProxy) value);
138: else {
139: writeMemberStartTag(memberName);
140: getValue(value, fd.getType());
141: }
142:
143: writeMemberEndTag();
144:
145: } catch (IllegalAccessException iae) {
146: System.err.println("(getMember) EXCEPTION: " + iae);
147: }
148: }
149:
150: super Class(obj, objClass);
151: }
152:
153: /**
154: * SuperClass gets the informations about the Superclass of the Object.
155: *
156: * @param obj (the Object)
157: * @param objClass (the Class of the Object)
158: */
159: private void super Class(Object obj, Class objClass)
160: throws SAXException {
161:
162: Class super Class = objClass.getSuperclass();
163: if (super Class == null) {
164: return;
165: }
166:
167: writeSuperClStartTag(super Class.getName());
168:
169: getMember(obj, super Class);
170: writeSuperClEndTag();
171: }
172:
173: /**
174: * GetValue gets the value of the certain member.
175: *
176: * @param value (value of the member)
177: * @param valueType (the Class of the certain member)
178: */
179: protected void getValue(Object value, Class valueType)
180: throws SAXException {
181: if (value == null) {
182: return;
183: }
184:
185: if (objCache.containsKey(getID(value))) {
186: writeObjRefElement(getID(value));
187: return;
188: }
189:
190: objCache.put(getID(value), getID(value));
191:
192: if (valueType.isPrimitive()) {
193: writeValueStartTag(valueType.getName(), getID(value));
194: writeValue(value.toString());
195: writeValueEndTag();
196: return;
197: }
198:
199: if (value instanceof Boolean || value instanceof Byte
200: || value instanceof Character
201: || value instanceof Double || value instanceof Float
202: || value instanceof Long || value instanceof Integer
203: || value instanceof Short || value instanceof String) {
204:
205: writeValueStartTag(value.getClass().getName(), getID(value));
206: writeValue(value.toString());
207: writeValueEndTag();
208: return;
209: }
210:
211: if (valueType.isArray()) {
212: int length = Array.getLength(value);
213: Class subType = value.getClass().getComponentType();
214: writeArrayStartTag(valueType.getName(), getID(value));
215: for (int l = 0; l < length; l++) {
216:
217: Object subValue = Array.get(value, l);
218: if (subValue == null)
219: continue;
220:
221: if (subType.isPrimitive()) {
222: getValue(subValue, subType);
223: } else {
224: getValue(subValue, subValue.getClass());
225: }
226: }
227: writeArrayEndTag();
228:
229: } else {
230: writeValueObjStartTag(value.getClass().getName(),
231: getID(value));
232:
233: getMember(value, value.getClass());
234: writeValueObjEndTag();
235: }
236: }
237:
238: /**
239: * This methode handles an OzoneProxy member.
240: *
241: * @param memberName (name of the member)
242: * @param proxy (the OzoneProxy object)
243: */
244: protected void handleOzoneProxyMember(String memberName,
245: OzoneProxy proxy) throws SAXException {
246: String proxyType = proxy.getClass().getName();
247: String objectID;
248:
249: try {
250:
251: Field remoteID = proxy.getClass().getField(REMOTE_ID);
252: Object valueID = remoteID.get(proxy);
253: objectID = valueID.toString();
254:
255: writeMemberTagForOzoneProxy(memberName, proxyType, objectID);
256:
257: } catch (NoSuchFieldException nsfe) {
258: System.err.println("(handleOzoneProxyMember) EXCEPTION: "
259: + nsfe);
260: } catch (IllegalAccessException iae) {
261: System.err.println("(handleOzoneProxyMember) EXCEPTION: "
262: + iae);
263: }
264: }
265:
266: /**
267: * GetId gets the reference/address of the Object.
268: *
269: * @param obj (the Object)
270: * @return id
271: */
272: protected Integer getID(Object obj) {
273: Integer id = new Integer(System.identityHashCode(obj));
274: return id;
275: }
276:
277: //
278: // writeMethods
279: // The writeMethods helps to write XML/SAX.
280: //
281: protected void writeObjStartTag(String classname, Integer id,
282: Attributes additionallyAtts) throws SAXException {
283:
284: AttributesImpl atts;
285: if (additionallyAtts != null) {
286: atts = new AttributesImpl(additionallyAtts);
287: } else {
288: atts = new AttributesImpl();
289: }
290:
291: atts
292: .addAttribute("", ATTR_TYPE, ATTR_TYPE, "String",
293: classname);
294: atts.addAttribute("", ATTR_ID, ATTR_ID, "Integer", id + "");
295:
296: ch.startElement("", TAG_OBJ, TAG_OBJ, atts);
297: }
298:
299: protected void writeObjEndTag() throws SAXException {
300: ch.endElement("", TAG_OBJ, TAG_OBJ);
301: }
302:
303: protected void writeSuperClStartTag(String classname)
304: throws SAXException {
305: AttributesImpl atts = new AttributesImpl();
306: atts
307: .addAttribute("", ATTR_TYPE, ATTR_TYPE, "String",
308: classname);
309:
310: ch.startElement("", TAG_SUPERCLASS, TAG_SUPERCLASS, atts);
311: }
312:
313: protected void writeSuperClEndTag() throws SAXException {
314: ch.endElement("", TAG_SUPERCLASS, TAG_SUPERCLASS);
315: }
316:
317: protected void writeMemberStartTag(String name) throws SAXException {
318: AttributesImpl atts = new AttributesImpl();
319: atts.addAttribute("", ATTR_NAME, ATTR_NAME, "String", name);
320:
321: ch.startElement("", TAG_MEMBER, TAG_MEMBER, atts);
322: }
323:
324: protected void writeMemberEndTag() throws SAXException {
325: ch.endElement("", TAG_MEMBER, TAG_MEMBER);
326: }
327:
328: protected void writeMemberTagForOzoneProxy(String name,
329: String proxyType, String objectID) throws SAXException {
330: AttributesImpl atts = new AttributesImpl();
331: atts.addAttribute("", ATTR_NAME, ATTR_NAME, "String", name);
332: atts.addAttribute("", ATTR_PROXY_TYPE, ATTR_PROXY_TYPE,
333: "java.lang.Class", proxyType);
334: atts.addAttribute(ATTR_XLINK_NAMESPACE, ATTR_XLINK_TYPE_LOCAL,
335: ATTR_XLINK_TYPE_RAW, "String", ATTR_XLINK_TYPE_VALUE);
336: atts.addAttribute(ATTR_XLINK_NAMESPACE, ATTR_XLINK_HREF_LOCAL,
337: ATTR_XLINK_HREF_RAW, "long", objectID);
338:
339: ch.startElement("", TAG_MEMBER, TAG_MEMBER, atts);
340: }
341:
342: protected void writeValue(String value) throws SAXException {
343: ch.characters(value.toCharArray(), 0, value.length());
344: }
345:
346: protected void writeValueStartTag(String type, Integer id)
347: throws SAXException {
348: AttributesImpl atts = new AttributesImpl();
349: atts.addAttribute("", ATTR_TYPE, ATTR_TYPE, "String", type);
350: atts.addAttribute("", ATTR_ID, ATTR_ID, "Integer", id + "");
351:
352: ch.startElement("", TAG_VALUE, TAG_VALUE, atts);
353: }
354:
355: protected void writeValueEndTag() throws SAXException {
356: ch.endElement("", TAG_VALUE, TAG_VALUE);
357: }
358:
359: protected void writeValueObjStartTag(String type, Integer id)
360: throws SAXException {
361: AttributesImpl atts = new AttributesImpl();
362: atts.addAttribute("", ATTR_TYPE, ATTR_TYPE, "String", type);
363: atts.addAttribute("", ATTR_ID, ATTR_ID, "Integer", id + "");
364:
365: ch.startElement("", TAG_VALUEOBJ, TAG_VALUEOBJ, atts);
366: }
367:
368: protected void writeValueObjEndTag() throws SAXException {
369: ch.endElement("", TAG_VALUEOBJ, TAG_VALUEOBJ);
370: }
371:
372: protected void writeArrayStartTag(String type, Integer id)
373: throws SAXException {
374: AttributesImpl atts = new AttributesImpl();
375: atts.addAttribute("", ATTR_TYPE, ATTR_TYPE, "String", type);
376: atts.addAttribute("", ATTR_ID, ATTR_ID, "Integer", id + "");
377:
378: ch.startElement("", TAG_VALUEARRAY, TAG_VALUEARRAY, atts);
379: }
380:
381: protected void writeArrayEndTag() throws SAXException {
382: ch.endElement("", TAG_VALUEARRAY, TAG_VALUEARRAY);
383: }
384:
385: protected void writeObjRefElement(Integer sourceId)
386: throws SAXException {
387: AttributesImpl atts = new AttributesImpl();
388: atts.addAttribute("", ATTR_REF, ATTR_REF, "Integer", sourceId
389: + "");
390:
391: ch.startElement("", TAG_VALUE, TAG_VALUE, atts);
392: ch.endElement("", TAG_VALUE, TAG_VALUE);
393: }
394: }
|