KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jdo > spi > persistence > support > sqlstore > query > jqlc > VariableTable


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * VariableTable.java
26  *
27  * Created on April 12, 2000
28  */

29
30 package com.sun.jdo.spi.persistence.support.sqlstore.query.jqlc;
31
32 import java.util.*;
33
34 import com.sun.jdo.spi.persistence.utility.I18NHelper;
35
36 import com.sun.jdo.api.persistence.support.JDOQueryException;
37 import com.sun.jdo.api.persistence.support.JDOUnsupportedOptionException;
38 import com.sun.jdo.api.persistence.support.JDOFatalInternalException;
39
40 /**
41  * The variable table
42  *
43  * @author Michael Bouschen
44  * @version 0.1
45  */

46 public class VariableTable
47 {
48     /**
49      * I18N support
50      */

51     protected final static ResourceBundle messages =
52         I18NHelper.loadBundle(VariableTable.class);
53
54     /**
55      * A VarInfo consists of two info fields:
56      * - constraint: the variable is constraint with the specified expr
57      * - used: the variable is used
58      */

59     static class VarInfo
60     {
61         /**
62          * The constraint expression.
63          */

64         JQLAST constraint;
65
66         /**
67          * Set of JQLAST nodes denoting an access of this variable.
68          */

69         Set used;
70
71         /**
72          * Dependency for this variable.
73          * The constraint for this variable may use another variable.
74          */

75         String JavaDoc dependsOn;
76
77         /**
78          * Flag whether this varInfo is checked already (see checkConstraints)
79          */

80         int status;
81
82         static final int UNCHECKED = 0;
83         static final int IN_PROGRESS = 1;
84         static final int CHECKED = 2;
85
86         VarInfo()
87         {
88             this.constraint = null;
89             this.used = new HashSet();
90             this.dependsOn = null;
91             this.status = UNCHECKED;
92         }
93
94         VarInfo(VarInfo other)
95         {
96             this.constraint = other.constraint;
97             this.used = new HashSet(other.used);
98             this.dependsOn = other.dependsOn;
99             this.status = other.status;
100         }
101     }
102
103     /** */
104     private ErrorMsg errorMsg;
105
106     /** List of names of declared variables. */
107     private List declaredVars;
108
109     /** Map of variable infos. */
110     private Map varInfos;
111
112     /**
113      * Create an empty variable table
114      */

115     public VariableTable(ErrorMsg errorMsg)
116     {
117         this.errorMsg = errorMsg;
118         declaredVars = new ArrayList();
119         varInfos = new HashMap();
120     }
121
122     /**
123      * Create a variable table initialized with the entries of the other variable table.
124      * The constructor creates copies of the values stored in the map (instances of class VarInfo).
125      */

126     public VariableTable(VariableTable other)
127     {
128         errorMsg = other.errorMsg;
129         declaredVars = other.declaredVars;
130         varInfos = new HashMap();
131         for (Iterator i = other.varInfos.entrySet().iterator(); i.hasNext();)
132         {
133             Map.Entry entry = (Map.Entry)i.next();
134             varInfos.put(entry.getKey(), new VarInfo((VarInfo)entry.getValue()));
135         }
136     }
137
138     /**
139      * Creates a new entry in the variable table with the specified name as key and
140      * an empty value.
141      */

142     public void add(String JavaDoc name)
143     {
144         declaredVars.add(name);
145         // init var entry as not constraint and unused
146
varInfos.put(name, new VarInfo());
147     }
148
149     /**
150      * Mark the specified variable as used.
151      * The method sets the info field of the VarInfo object to true.
152      */

153     public void markUsed(JQLAST variable, String JavaDoc dependendVar)
154     {
155         String JavaDoc name = variable.getText();
156         VarInfo entry = (VarInfo)varInfos.get(name);
157         if (entry == null)
158             throw new JDOFatalInternalException(I18NHelper.getMessage(messages,
159                 "jqlc.variabletable.markused.varnotfound", //NOI18N
160
name));
161         entry.used.add(variable);
162         if (dependendVar != null)
163         {
164             VarInfo dependendVarInfo = (VarInfo)varInfos.get(dependendVar);
165             if (dependendVarInfo.dependsOn != null)
166                 throw new JDOFatalInternalException(I18NHelper.getMessage(
167                     messages,
168                     "jqlc.variabletable.markused.multidep", //NOI18N
169
dependendVar, dependendVarInfo.dependsOn, name));
170             dependendVarInfo.dependsOn = name;
171         }
172     }
173
174     /**
175      * Mark the specified variable as constaint with the specified expr.
176      * The method sets the constraint field of the VarInfo object to true.
177      */

178     public void markConstraint(JQLAST variable, JQLAST expr)
179     {
180         String JavaDoc name = variable.getText();
181         VarInfo entry = (VarInfo)varInfos.get(name);
182         if (entry == null)
183             throw new JDOFatalInternalException(I18NHelper.getMessage(
184                 messages,
185                 "jqlc.variabletable.markconstraint.varnotfound", //NOI18N
186
name));
187         String JavaDoc old = (entry.constraint==null ? null : entry.constraint.getText());
188         if ((old != null) && !old.equals(expr.getText()))
189         {
190             errorMsg.unsupported(variable.getLine(), variable.getColumn(),
191                 I18NHelper.getMessage(messages, "jqlc.variabletable.markconstraint.multiple", //NOI18N
192
name));
193         }
194         entry.constraint = expr;
195     }
196
197     /**
198      * Merges the specified variable table (other) into this variable table.
199      */

200     public void merge(VariableTable other)
201     {
202         for (Iterator i = declaredVars.iterator(); i.hasNext();)
203         {
204             String JavaDoc name = (String JavaDoc)i.next();
205             VarInfo info = (VarInfo)varInfos.get(name);
206             VarInfo otherInfo = (VarInfo)other.varInfos.get(name);
207             
208             // copy other info if this info is empty
209
if ((info.constraint == null) && (info.used.size() == 0))
210             {
211                 info.constraint = otherInfo.constraint;
212                 info.used = otherInfo.used;
213                 info.dependsOn = otherInfo.dependsOn;
214                 info.status = otherInfo.status;
215                 continue;
216             }
217
218             // do nothing if otherInfo is empty
219
if ((otherInfo.constraint == null) && (otherInfo.used.size() == 0))
220             {
221                 continue;
222             }
223             
224             // constraint check
225
// If both variables tables include constraints they have to be the same
226
if ((info.constraint != null) && (otherInfo.constraint != null))
227             {
228                 if (!otherInfo.constraint.getText().equals(info.constraint.getText()))
229                 {
230                     throw new JDOUnsupportedOptionException(
231                         I18NHelper.getMessage(messages, "jqlc.variabletable.merge.different", name)); //NOI18N
232
}
233             }
234             // If at least one variable table does not define constraint,
235
// nullify the constaint in this variable table
236
else
237             {
238                 info.constraint = null;
239                 info.dependsOn = null;
240                 info.status = VarInfo.UNCHECKED;
241             }
242             
243             // copy otherInfo.used to this used list
244
info.used.addAll(otherInfo.used);
245         }
246     }
247
248     /**
249      *
250      */

251     public void checkConstraints()
252     {
253         // iterate declaredVars to check the variables in the order they are declared
254
for (Iterator i = declaredVars.iterator(); i.hasNext();)
255         {
256             String JavaDoc name = (String JavaDoc)i.next();
257             VarInfo info = (VarInfo)varInfos.get(name);
258             checkConstraint(name, info);
259         }
260     }
261
262     protected void checkConstraint(String JavaDoc variable, VarInfo info)
263     {
264         switch (info.status)
265         {
266         case VarInfo.UNCHECKED:
267             // if unchecked, start checking
268
info.status = VarInfo.IN_PROGRESS;
269             break;
270         case VarInfo.IN_PROGRESS:
271             // if this VarInfo is currently processed we have a cyclic dependency
272
throw new JDOUnsupportedOptionException(
273                 I18NHelper.getMessage(messages, "jqlc.variabletable.checkconstraint.cycle", // NOI18N
274
variable));
275         case VarInfo.CHECKED:
276             // if alreday checked just return
277
return;
278         }
279         
280         if (info.dependsOn != null)
281         {
282             VarInfo dependendVarInfo = (VarInfo)varInfos.get(info.dependsOn);
283             checkConstraint(info.dependsOn, dependendVarInfo);
284         }
285         
286         if ((info.constraint != null) && (info.used.size() == 0))
287         {
288             throw new JDOUnsupportedOptionException(
289                 I18NHelper.getMessage(messages, "jqlc.variabletable.checkconstraint.unused", //NOI18N
290
variable));
291         }
292         
293         attachConstraintToUsedAST(info);
294         info.status = VarInfo.CHECKED;
295     }
296     
297     /**
298      *
299      */

300     protected void attachConstraintToUsedAST(VarInfo info)
301     {
302         for (Iterator i = info.used.iterator(); i.hasNext();)
303         {
304             JQLAST varNode = (JQLAST)i.next();
305             if (varNode.getFirstChild() == null)
306                 varNode.setFirstChild(JQLAST.Factory.getInstance().dupTree(info.constraint));
307         }
308     }
309     
310 }
311
Popular Tags