KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > mapper > storage > AbstractModelBuilder


1 /*
2  * This file belongs to the XQuark distribution.
3  * Copyright (C) 2003 Universite de Versailles Saint-Quentin.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307.
18  * You can also get it at http://www.gnu.org/licenses/lgpl.html
19  *
20  * For more information on this software, see http://www.xquark.org.
21  */

22
23 /*
24  * LogicalStructureBuilder.java
25  *
26  * Created on 25 juillet 2001, 11:45
27  */

28
29 package org.xquark.mapper.storage;
30
31 import java.sql.Connection JavaDoc;
32 import java.sql.SQLException JavaDoc;
33
34 import org.xml.sax.Locator JavaDoc;
35 import org.xquark.mapper.RepositoryException;
36 import org.xquark.mapper.dbms.AbstractConnection;
37 import org.xquark.mapper.dbms.JDBCBatcher;
38 import org.xquark.mapper.metadata.Node;
39 import org.xquark.mapper.metadata.RepositoryConstants;
40 import org.xquark.mapper.metadata.StoragePathMetadata;
41 import org.xquark.mapper.util.RecyclingStack;
42 import org.xquark.schema.SchemaConstants;
43 import org.xquark.schema.validation.ElementPSVInfoset;
44 import org.xquark.schema.validation.PSVInfoset;
45 import org.xquark.schema.validation.SchemaValidationContext;
46 import org.xquark.xml.xdbc.XMLDBCException;
47 import org.xquark.xml.xdbc.XMLErrorHandler;
48 import org.xquark.xpath.NodeKind;
49
50 /**
51  *
52  */

53 public abstract class AbstractModelBuilder
54 implements RepositoryConstants, _StorageContext, RecyclingStack.StackObjectFactory
55 {
56     private static final String JavaDoc RCSRevision = "$Revision: 1.2 $";
57     private static final String JavaDoc RCSName = "$Name: $";
58     
59     /** Backing stack
60      */

61     protected RecyclingStack stack = null;
62     
63     protected StorageBuffer storageBuffer; // Class buffering data storage to the database.
64
protected AbstractConnection connection;
65     protected JDBCBatcher batcher;
66     protected SchemaValidationContext validationContext;
67     
68     private boolean autoFlush = true;
69     
70     public AbstractModelBuilder(AbstractConnection connection, SchemaValidationContext schemaContext)
71     throws XMLDBCException
72     {
73         stack = new RecyclingStack(this);
74         this.connection = connection;
75         validationContext = schemaContext;
76         batcher = new JDBCBatcher(connection, autoFlush);
77      }
78     
79     protected abstract AbstractModelNode getLogicalStructureNode(byte type, StoragePathMetadata path, String JavaDoc data, Locator JavaDoc locator)
80     throws SQLException JavaDoc, XMLDBCException;
81     
82     protected abstract AbstractModelNode finalizeNode(Locator JavaDoc locator)
83     throws XMLDBCException, SQLException JavaDoc;
84     
85     /* return the last OID allocated */
86     public void endModel() throws XMLDBCException, SQLException JavaDoc
87     {
88         // Flush completed tuples
89
storageBuffer.flush();
90     }
91     
92     public void reset()
93     throws RepositoryException, SQLException JavaDoc
94     {
95         stack.clear();
96         storageBuffer.reset();
97     }
98     
99     public void close() throws RepositoryException, SQLException JavaDoc
100     {
101         if (batcher != null)
102         {
103             batcher.close();
104             batcher = null;
105             storageBuffer.close();
106             storageBuffer = null;
107             stack = null;
108         }
109     }
110     
111     public void setErrorHandler(XMLErrorHandler handler)
112     {
113         storageBuffer.setErrorHandler(handler);
114     }
115     
116     public XMLErrorHandler getXMLErrorHandler()
117     {
118         return storageBuffer.getXMLErrorHandler();
119     }
120     
121     public AbstractModelNode getCurrentNode()
122     {
123         return (AbstractModelNode)stack.top();
124     }
125     
126     ////////////////////////////////////////////////////////////////////
127
// Common features.
128
////////////////////////////////////////////////////////////////////
129
/**
130      * For root or element nodes.
131      **/

132     public AbstractModelNode newNode(StoragePathMetadata path, Locator JavaDoc locator)
133     throws SQLException JavaDoc, XMLDBCException
134     {
135         if (path == null)
136             return null;
137         return getLogicalStructureNode(path.getType(), path, "", locator); // "" ant not null because empty element will never have setData() called...
138
}
139     
140     /**
141      * For Text nodes, attributes
142      **/

143     public AbstractModelNode leafNode(byte type, StoragePathMetadata path, String JavaDoc data, Locator JavaDoc locator)
144     throws XMLDBCException, SQLException JavaDoc
145     {
146         getLogicalStructureNode(type, path, data, locator);
147         return finalizeNode(locator);
148     }
149     
150     public void setData(String JavaDoc data)
151     {
152         getCurrentNode().setData(data);
153     }
154     
155     public void setXSIinfo(String JavaDoc attName, String JavaDoc value)
156     throws RepositoryException
157     {
158         getCurrentNode().setXSIinfo(attName, value);
159     }
160     
161     public void incCharOffset(int length)
162     {
163         getCurrentNode().incCharOffset(length);
164     }
165     
166     public boolean empty()
167     {
168         return stack.isEmpty();
169     }
170     
171     public void flushBuffer() throws XMLDBCException
172     {
173         batcher.flush();
174     }
175     
176     public void clearBuffer() throws XMLDBCException
177     {
178         try {
179             batcher.reset();
180         }
181         catch (SQLException JavaDoc e) {
182             throw new RepositoryException(RepositoryException.DB_ERROR,
183             "Could not reset the JDBC Batcher");
184         }
185     }
186     
187     public void setAutoFlush(boolean mode) throws XMLDBCException
188     {
189         autoFlush = mode;
190         batcher.setAutoFlush(mode);
191     }
192     
193     public boolean getAutoFlush()
194     {
195         return autoFlush;
196     }
197     ////////////////////////////////////////////////////////////////////
198
// IMPLEMENTATION of StorageContext interface.
199
////////////////////////////////////////////////////////////////////
200
public long getBucketOID() { return -1;}
201     public short getPathOID() { return -1;}
202     public String JavaDoc getDocumentID() { return null;}
203     public long getDocumentOID() { return -1;}
204     public long getOID() { return -1;}
205     public long getUOID() { return -1;}
206     
207     public String JavaDoc getQName()
208     {
209         AbstractModelNode node = getCurrentNode();
210         return (node.getPath().getNamespace() == null ? node.getPath().getLocalName() : node.getPath().getNamespace() + ":" + node.getPath().getLocalName());
211     }
212     public int getNodeRank()
213     {
214         return getCurrentNode().rank;
215     }
216     public String JavaDoc getNodeData() { return getCurrentNode().data;}
217     public String JavaDoc getNormalizedNodeData()
218     {
219         String JavaDoc ret = null;
220         PSVInfoset nodeInfoSet = getNodeInfoSet();
221         if (nodeInfoSet == null)
222             return null;
223
224         // do not take default value coming from schema if node is an attribute
225
if ((nodeInfoSet.getSpecified() == null) || // no declaration
226
(
227             (nodeInfoSet.getSpecified() == PSVInfoset.SCHEMA) // constant equality
228
&& (getCurrentNode().getPath().getType() == NodeKind.ATTRIBUTE)
229             ))
230             ret = getNodeData();
231         else
232             ret = nodeInfoSet.getNormalizedValue();
233         
234         return ret;
235     }
236     
237     public Object JavaDoc getActualNodeData()
238     {
239         Object JavaDoc ret = null;
240         PSVInfoset nodeInfoSet = getNodeInfoSet();
241         if (nodeInfoSet == null)
242             return null;
243
244          // do not take default value coming from schema if node is an attribute
245
if ((nodeInfoSet.getSpecified() == null) || // no declaration
246
(
247             (nodeInfoSet.getSpecified() == PSVInfoset.SCHEMA) // constant equality
248
&& (getCurrentNode().getPath().getType() == NodeKind.ATTRIBUTE)
249             ))
250             ret = getNodeData();
251         else
252             ret = nodeInfoSet.getActualValue(); // default value
253

254         return ret;
255    }
256     public String JavaDoc getCanonicalString()
257     {
258         String JavaDoc ret = null;
259         PSVInfoset nodeInfoSet = getNodeInfoSet();
260         if (nodeInfoSet == null)
261             return null;
262
263         // do not take default value coming from schema if node is an attribute
264
if ((nodeInfoSet.getSpecified() == null) || // no declaration
265
(
266         (nodeInfoSet.getSpecified() == PSVInfoset.SCHEMA) // constant equality
267
&& (getCurrentNode().getPath().getType() == NodeKind.ATTRIBUTE)
268         ))
269             ret = getNodeData();
270         else
271             ret = nodeInfoSet.getDeclaration().getType().getValueType().toXMLString(
272                 nodeInfoSet.getActualValue(), null);
273         
274         return ret;
275     }
276     public String JavaDoc getLocalName() { return getCurrentNode().getPath().getLocalName();}
277     public String JavaDoc getNamespaceURI() { return getCurrentNode().getPath().getNamespace();}
278     public Object JavaDoc getRefValue(int tableIndex, int columnIndex)
279     {
280         return storageBuffer.getTupleFactory(tableIndex).getParameter(columnIndex);
281     }
282     public Connection JavaDoc getConnection()
283     {
284         return storageBuffer.getConnection().getConnection();
285     }
286     
287     public RecyclingStack.StackObject newStackObject()
288     {
289         return new AbstractModelNode();
290     }
291     
292     //
293
// PRIVATE UTILITIES
294
//
295

296     private PSVInfoset getNodeInfoSet()
297     {
298         AbstractModelBuilder.AbstractModelNode wNode = getCurrentNode();
299         if (wNode.data == null)
300             return null;
301         
302         StoragePathMetadata node = wNode.getPath();
303         ElementPSVInfoset infoSet = validationContext.getCurrentInfoset();
304         
305         PSVInfoset nodeInfoSet = null;
306         if (node.getType() == NodeKind.ELEMENT)
307             nodeInfoSet = infoSet;
308         else // attribute
309
nodeInfoSet = infoSet.getAttributePSVInfoset(node.getNamespace(), node.getLocalName());
310         
311         return nodeInfoSet;
312     }
313     
314     ////////////////////////////////////////////////////////////////////
315
// STORAGE MODEL NODE
316
////////////////////////////////////////////////////////////////////
317
public class AbstractModelNode extends Node
318     implements RecyclingStack.StackObject
319     {
320         protected StoragePathMetadata pathMetadata;
321         protected short childCount = 0; // child element count (attributes are discarded)
322
private short rank = 0; // position among siblings child element or text (attributes are discarded)
323
private String JavaDoc data = null;
324         protected StorageBuffer.BufferNode tupleNode = null;
325         
326         AbstractModelNode()
327         {}
328         void set(StoragePathMetadata path, byte type, String JavaDoc data, short rank)
329         {
330             pathMetadata = path;
331             this.type = type;
332             this.rank = rank;
333             this.path = path.getPathID();
334             setData(data);
335         }
336         public void clear()
337         {
338             super.clear();
339             pathMetadata = null;
340             childCount = 0;
341             rank = 0;
342             data = null;
343             tupleNode = null;
344         }
345
346         void setTupleNode(StorageBuffer.BufferNode node)
347         {
348             tupleNode = node;
349         }
350         
351         StorageBuffer.BufferNode getTupleNode()
352         {
353             return tupleNode;
354         }
355         
356         String JavaDoc getData()
357         {
358             return data;
359         }
360         
361         short getRank()
362         {
363             return rank;
364         }
365         
366         short incChildCount()
367         {
368             return ++childCount;
369         }
370         
371         /** not leaf to the storage model i.e., text OR attribute OR leaf element
372          */

373         boolean isLeaf()
374         {
375             return (childCount == 0);
376         }
377
378         public void setData(String JavaDoc data)
379         {
380             this.data = data;
381         }
382
383         StoragePathMetadata getPath()
384         {
385             return pathMetadata;
386         }
387         public void incCharOffset(int length)
388         {
389             // no op
390
}
391         
392         /**
393          * @return true if nil.
394          */

395         public boolean setXSIinfo(String JavaDoc attName, String JavaDoc value)
396         throws RepositoryException
397         {
398             if (attName.equals(SchemaConstants.XSI_NIL_ATTR)
399                 && (value.equals(SchemaConstants.TRUE_VALUE) || value.equals("1")))
400             {
401                 setData(null); // replaces "" to avoid setting "" on a Number column for instance
402
return true;
403             }
404             return false;
405         }
406     }
407 }
408
Popular Tags