KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javolution > xml > XMLReferenceResolver


1 /*
2  * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
3  * Copyright (C) 2006 - Javolution (http://javolution.org/)
4  * All rights reserved.
5  *
6  * Permission to use, copy, modify, and distribute this software is
7  * freely granted, provided that this notice is preserved.
8  */

9 package javolution.xml;
10
11 import j2me.lang.CharSequence;
12 import javolution.Javolution;
13 import javolution.lang.Reusable;
14 import javolution.text.CharArray;
15 import javolution.text.TextBuilder;
16 import javolution.util.FastComparator;
17 import javolution.util.FastMap;
18 import javolution.util.FastTable;
19 import javolution.util.Index;
20 import javolution.xml.stream.XMLStreamException;
21
22 /**
23  * <p> This class represents a resolver for XML cross references during
24  * the marshalling/unmarshalling process.</p>
25  *
26  * <p> Instances of this class may only be shared by {@link XMLObjectReader}/
27  * {@link XMLObjectWriter} running sequentially (for cross references
28  * spawning multiple documents).</p>
29  *
30  * @author <a HREF="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
31  * @version 4.0, September 4, 2006
32  */

33 public class XMLReferenceResolver implements Reusable {
34
35     /**
36      * Holds object to identifier (FastTable.Index) mapping.
37      */

38     private FastMap _objectToId = new FastMap()
39             .setKeyComparator(FastComparator.IDENTITY);
40
41     /**
42      * Holds the objects (index to object mapping).
43      */

44     private FastTable _idToObject = new FastTable();
45
46     /**
47      * Holds the id counter.
48      */

49     private int _counter;
50
51     /**
52      * Holds the identifier attribute name.
53      */

54     private String JavaDoc _idName = "id";
55
56     /**
57      * Holds the identifier attribute URI if any.
58      */

59     private String JavaDoc _idURI = null;
60
61     /**
62      * Holds the reference attribute name.
63      */

64     private String JavaDoc _refName = "ref";
65
66     /**
67      * Holds the reference attribute URI if any.
68      */

69     private String JavaDoc _refURI = null;
70
71     /**
72      * Default constructor.
73      */

74     public XMLReferenceResolver() {
75     }
76
77     /**
78      * Sets the name of the identifier attribute (by default<code>"id"</code>).
79      * If the name is <code>null</code> then the identifier attribute
80      * is never read/written (which may prevent unmarshalling).
81      *
82      * @param name the name of the attribute or <code>null</code>.
83      */

84     public void setIdentifierAttribute(String JavaDoc name) {
85         setIdentifierAttribute(name, null);
86     }
87
88     /**
89      * Sets the local name and namespace URI of the identifier attribute.
90      *
91      * @param localName the local name of the attribute or <code>null</code>.
92      * @param uri the URI of the attribute or <code>null</code> if the attribute
93      * has no namespace URI.
94      */

95     public void setIdentifierAttribute(String JavaDoc localName, String JavaDoc uri) {
96         _idName = localName;
97         _idURI = uri;
98     }
99
100     /**
101      * Sets the name of the reference attribute (by default<code>"ref"</code>).
102      * If the name is <code>null</code> then the reference attribute
103      * is never read/written (which may prevent unmarshalling).
104      *
105      * @param name the name of the attribute or <code>null</code>.
106      */

107     public void setReferenceAttribute(String JavaDoc name) {
108         setReferenceAttribute(name, null);
109     }
110
111     /**
112      * Sets the local name and namespace URI of the identifier attribute.
113      *
114      * @param localName the local name of the attribute or <code>null</code>.
115      * @param uri the URI of the attribute or <code>null</code> if the attribute
116      * has no namespace URI.
117      */

118     public void setReferenceAttribute(String JavaDoc localName, String JavaDoc uri) {
119         _refName = localName;
120         _refURI = uri;
121     }
122
123     /**
124      * Writes a reference to the specified object into the specified XML
125      * element. The default implementation writes the reference into the
126      * reference attribute and for the first occurences an identifier
127      * (counter starting at 1) is written into the identifier attribute.
128      *
129      * @param obj the object for which the reference is written.
130      * @param xml the output XML element.
131      * @return <code>true</code> if a reference is written;
132      * <code>false</code> if a new identifier is written.
133      */

134     public boolean writeReference(Object JavaDoc obj, XMLFormat.OutputElement xml)
135             throws XMLStreamException {
136         Index id = (Index) _objectToId.get(obj);
137         if (id == null) { // New identifier.
138
id = Index.valueOf(_counter++);
139             _objectToId.put(obj, id);
140             _tmp.clear().append(id.intValue());
141             if (_idURI == null) {
142                 xml.getStreamWriter().writeAttribute(toCsq(_idName),
143                         _tmp);
144             } else {
145                 xml.getStreamWriter().writeAttribute(toCsq(_idURI),
146                         toCsq(_idName), _tmp);
147             }
148             return false;
149         }
150         _tmp.clear().append(id.intValue());
151         if (_refURI == null) {
152             xml._writer
153                     .writeAttribute(toCsq(_refName), _tmp);
154         } else {
155             xml._writer.writeAttribute(toCsq(_refURI),
156                     toCsq(_refName), _tmp);
157         }
158         return true;
159     }
160
161     private TextBuilder _tmp = new TextBuilder();
162
163     /**
164      * Reads the object referenced by the specified xml input element if any.
165      * The default implementation reads the reference attribute to retrieve
166      * the object.
167      *
168      * @param xml the input XML element.
169      * @return the referenced object or <code>null</code> if the specified
170      * XML input does not have a reference attribute.
171      */

172     public Object JavaDoc readReference(XMLFormat.InputElement xml)
173             throws XMLStreamException {
174         CharArray value = xml._reader.getAttributeValue(
175                 toCsq(_refURI), toCsq(_refName));
176         if (value == null)
177             return null;
178         int ref = value.toInt();
179         if (ref >= _idToObject.size())
180             throw new XMLStreamException("Reference: " + value + " not found");
181         return _idToObject.get(ref);
182     }
183
184     /**
185      * Creates a reference for the specified object (the identifier
186      * being specified by the input XML element).
187      * The default implementation reads the identifier attribute (if any)
188      * and associates it to the specified object.
189      *
190      * @param obj the object being referenced.
191      * @param xml the input XML element holding the reference identifier.
192      */

193     public void createReference(Object JavaDoc obj, XMLFormat.InputElement xml)
194             throws XMLStreamException {
195         CharArray value = xml._reader.getAttributeValue(
196                 toCsq(_idURI), toCsq(_idName));
197         if (value == null)
198             return;
199         int i = value.toInt();
200         if (_idToObject.size() != i)
201             throw new XMLStreamException("Identifier discontinuity detected "
202                     + "(expected " + _idToObject.size() + " found " + i + ")");
203         _idToObject.add(obj);
204     }
205
206     // Implements Reusable.
207
public void reset() {
208         _idName = "id";
209         _idURI = null;
210         _refName = "ref";
211         _refURI = null;
212         _idToObject.clear();
213         _objectToId.clear();
214         _counter = 0;
215     }
216
217     private static CharSequence JavaDoc toCsq/**/(Object JavaDoc str) {
218         return Javolution.j2meToCharSeq(str);
219     }
220
221 }
222
Popular Tags