KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > extractor > algebra > TypeInterpreter


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

23
24 package org.xquark.extractor.algebra;
25
26 import java.sql.Types JavaDoc;
27 import java.util.*;
28
29 import org.xquark.extractor.common.Debug;
30 import org.xquark.jdbc.typing.DbType;
31 import org.xquark.schema.*;
32 import org.xquark.xquery.parser.QName;
33 import org.xquark.xquery.parser.XQueryException;
34 import org.xquark.xquery.parser.XQueryExpression;
35 import org.xquark.xquery.typing.*;
36
37 /**
38  * This class is used by the GenAlgebraVisitor to perform a "quick" translation
39  * of XML typing coming from the query into an SQL (JDBC) data type. The mapping
40  * is defined statically and used by {@link org.xquark.extractor.algebra.GenAlgebraVisitor}
41  * to check the query is consistent from a SQL type point of view and mostly to
42  * guide algebra construction during operator generation, e.g. according to the
43  * fact that one operator is an atom or not (a constant or a column).
44  */

45 // TODO: check it is not redundant with front-end processing. Especially when multiplicity
46
// if set by the new QType flag.
47
public final class TypeInterpreter extends DefaultQTypeVisitor
48 {
49     private static final String JavaDoc RCSRevision = "$Revision: 1.10 $";
50     private static final String JavaDoc RCSName = "$Name: $";
51
52     /** The static type mapping table between XML and SQL atom types */
53     private static final int[] CODE_TABLE = { -1, Types.VARCHAR, Types.BIT, Types.DECIMAL, Types.DOUBLE, Types.FLOAT, -1, Types.TIMESTAMP, Types.TIME, Types.DATE, -1, -1, -1, -1, -1 - 1, -1, -1, -1, -1, -1 };
54
55     private SqlType _type = null;
56     
57     public TypeInterpreter() {}
58
59     private int sqlTypeCode(int schemaTypeCode) {
60         int retVal = -1;
61         if (schemaTypeCode < 1 || schemaTypeCode > 20)
62             retVal = -1;
63         else
64             retVal = CODE_TABLE[schemaTypeCode];
65
66         return retVal;
67     }
68
69     public SqlType interprete(QType qtype) throws XQueryException {
70         //Trace.enter(this, "interprete (QType qtype)");
71
Debug.assertTrue(null != qtype, "null != qtype");
72
73         qtype.accept(this);
74         
75         if (_type != null) {
76             if (qtype.isMultiple())
77                 _type.setMultiplicity(SqlType.MANY);
78             else
79                 _type.setMultiplicity(SqlType.ONE);
80         }
81
82         //Trace.exit(this, "interprete (QType qtype)");
83
return _type;
84     }
85
86     public void visit(QTypeAtom qtype) throws XQueryException {
87         //Trace.enter(this, "interprete (QTypeAtom qtype)");
88

89         _type = interprete(qtype.getSimpleType());
90
91         //Trace.exit(this, "interprete (QTypeAtom qtype)");
92
}
93
94     public void visit(QTypeText qtype) throws XQueryException {
95         //Trace.enter(this, "interprete (QTypeText qtype)");
96

97         _type = interprete(qtype.getSimpleType());
98
99         //Trace.exit(this, "interprete (QTypeText qtype)");
100
}
101
102     public void visit(QTypeElement qte) throws XQueryException {
103         //Trace.enter(this, "interprete(QTypeElement qte)");
104
Type type = qte.getType();
105         if (type instanceof SimpleType) { // qtype contains a SimpleType
106
SqlTypeAtom sqlAtom;
107             sqlAtom = (SqlTypeAtom) interprete((SimpleType) type);
108             if (null != sqlAtom) {
109                 // set name
110
XQueryExpression name = qte.getName();
111                 Debug.assertTrue((name instanceof QName), "(name instanceof QName)");
112                 sqlAtom.setName(((QName) name).getName());
113                 _type = sqlAtom;
114             }
115         }
116         else // QTypeElement contains a ComplexType
117
_type = interprete((ComplexType) type);
118
119         //Trace.exit(this, "interprete (QTypeElement qtype)");
120
}
121
122     public void visit(QTypeSequence qtype) throws XQueryException {
123         //Trace.enter(this, "interprete(QTypeSequence qtype)");
124

125         SqlType sqlType = interprete((QType) qtype.getList().get(0));
126         if (sqlType.isRelation()) {
127             _type = VerifyRelation(qtype);
128         } else if (sqlType.isAtom()) {
129             _type = VerifyColumn(qtype);
130         } else {
131             Debug.assertTrue(false, "NYI");
132         }
133
134         //Trace.enter(this, "interprete(QTypeSequence qtype)");
135
}
136
137     public void visit(QTypeDocument qtype) throws XQueryException {
138         //Trace.enter(this, "interprete(QTypeDocument qtype)");
139

140         // change LARS 29/06/04
141
if (qtype.isFromDocument())
142             throw new XQueryException("Function doc is not supported");
143         _type = interprete(qtype.getQType());
144
145         //Trace.exit(this, "interprete(QTypeDocument qtype)");
146
}
147
148     private SqlType VerifyColumn(QTypeSequence qtype) throws XQueryException {
149         //Trace.enter(this, "VerifyColumn(QTypeSequence qtype)");
150

151         SqlTypeStructure retVal = new SqlTypeStructure(null);
152
153         SqlType sqlType = null;
154         Iterator iter = qtype.getList().iterator();
155         while (iter.hasNext()) {
156             //Debug.assertTrue(.........);
157
sqlType = interprete((QType) iter.next());
158             if (null == sqlType) {
159                 retVal = null;
160                 break;
161             }
162             if (sqlType.isAtom()) {
163                 retVal.addAttribute((SqlTypeAtom) sqlType);
164             } else if (sqlType.isTuple()) {
165                 retVal.addAttributes(((SqlTypeStructure) sqlType).getAttributes());
166             } else {
167                 retVal = null;
168                 break;
169             }
170         }
171
172         //Trace.exit(this, "VerifyColumn(QTypeSequence qtype)");
173
return retVal;
174     }
175
176     private SqlType VerifyRelation(QTypeSequence qtype) throws XQueryException {
177         //Trace.enter(this, "VerifyRelation(QTypeSequence qtype)");
178
SqlType retVal = null;
179
180         SqlType sqlType = null;
181         Iterator iter = qtype.getList().iterator();
182         while (iter.hasNext()) {
183             //Debug.assertTrue(.........);
184
sqlType = interprete((QType) iter.next());
185             if (null == sqlType && !sqlType.isRelation()) {
186                 retVal = null;
187                 break;
188             } else if (null == retVal) {
189                 retVal = sqlType;
190             }
191
192         }
193
194         //Trace.exit(this, "VerifyRelation(QTypeSequence qtype)");
195
return retVal;
196     }
197
198     private SqlType interprete(SimpleType stype) {
199         //Trace.enter(this, "iinterprete(SimpleType stype)");
200
SqlTypeAtom retVal;
201         Debug.assertTrue(SimpleType.VARIETY_ATOMIC == stype.getVariety(), "SimpleType.VARIETY_ATOMIC==stype.getVariety()");
202
203         DbType dt = new DbType(sqlTypeCode(stype.getPrimitive().getType()));
204         retVal = new SqlTypeAtom(dt, null, SqlType.ONE);
205
206         //Trace.exit(this, "interprete", "SimpleType");
207
return retVal;
208     }
209
210     private SqlType interprete(ComplexType stype) {
211         //Trace.enter(this, "interprete(SimpleType stype)");
212

213         SqlTypeStructure retVal = null;
214         retVal = new SqlTypeStructure(null, SqlType.ONE);
215
216         Collection elements = getElementDeclarations(stype);
217         ElementDeclaration element;
218         SqlType elementType;
219         Iterator iter = elements.iterator();
220         Debug.assertTrue(iter.hasNext(), "iter.hasNext()");
221         while (iter.hasNext()) {
222             element = (ElementDeclaration) iter.next();
223             elementType = interprete(element);
224             if (elementType != null && elementType.isAtom()) {
225                 retVal.addAttribute((SqlTypeAtom) elementType);
226             } else {
227                 retVal = null;
228                 break;
229             }
230         }
231         //Trace.exit(this, "interprete(SimpleType stype)");
232
return retVal;
233     }
234
235     private SqlType interprete(ElementDeclaration stype) {
236         //Trace.enter(this, "interprete(ElementDeclaration stype)");
237

238         SqlType retVal = null;
239
240         Type schemaType = stype.getType();
241         if (schemaType.isSimpleType()) {
242             retVal = interprete((SimpleType) schemaType);
243             ((SqlTypeAtom) retVal).setName(stype.getName());
244         } else {
245             retVal = interprete((ComplexType) schemaType);
246         }
247
248         //Trace.exit(this, "interprete(ElementDeclaration stype)");
249
return retVal;
250     }
251
252     private List getElementDeclarations(ComplexType complextype) {
253         //Trace.enter(this, "getElementDeclarations(ComplexType complextype)");
254

255         List retVal = new ArrayList();
256         ContentModel contentmodel = complextype.getContentModel();
257         Particle particle = (Particle) contentmodel.getModel();
258         Object JavaDoc term = particle.getTerm();
259         if (term instanceof ElementDeclaration)
260             retVal.add(term);
261         else if (term instanceof ModelGroup) {
262             ModelGroup modelgroup = (ModelGroup) term;
263             int compositor = modelgroup.getCompositor();
264             Debug.assertTrue(compositor == ModelGroup.SEQUENCE, "compositor == ModelGroup.SEQUENCE");
265
266             for (int i = 0; i < modelgroup.size(); i++) {
267                 Particle part = (Particle) modelgroup.get(i);
268                 ElementDeclaration elemDecl = (ElementDeclaration) part.getTerm();
269                 retVal.add(elemDecl);
270             }
271         }
272
273         //Trace.exit(this, "getElementDeclarations(ComplexType complextype)");
274
return retVal;
275     }
276 }
277
Popular Tags