KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > directwebremoting > dwrp > AbstractOutboundVariable


1 /*
2  * Copyright 2005 Joe Walker
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.directwebremoting.dwrp;
17
18 import java.util.Collection JavaDoc;
19 import java.util.Iterator JavaDoc;
20
21 import org.directwebremoting.extend.OutboundContext;
22 import org.directwebremoting.extend.OutboundVariable;
23
24 /**
25  * A helper class for people that want to implement {@link OutboundVariable}.
26  * @author Joe Walker [joe at getahead dot ltd dot uk]
27  */

28 public abstract class AbstractOutboundVariable implements OutboundVariable
29 {
30     /**
31      * @param outboundContext the OutboundContext to set
32      */

33     protected AbstractOutboundVariable(OutboundContext outboundContext)
34     {
35         this.outboundContext = outboundContext;
36     }
37
38     /**
39      * We might want to force us into predefined mode.
40      * @param inlineStatus The inline status to force
41      */

42     protected void forceInline(boolean inlineStatus)
43     {
44         setInline(inlineStatus);
45         forcedInlineStatus = true;
46     }
47
48     /**
49      * @param children the dependent children of this variable
50      */

51     protected void setChildren(Collection JavaDoc children)
52     {
53         this.children = children;
54     }
55
56     /* (non-Javadoc)
57      * @see org.directwebremoting.OutboundVariable#getDeclareCode()
58      */

59     public String JavaDoc getDeclareCode()
60     {
61         if (!calculated)
62         {
63             calculate();
64         }
65
66         if (inline)
67         {
68             return getChildDeclareCodes();
69         }
70         else
71         {
72             return notInlineDefinition.declareCode + getChildDeclareCodes();
73         }
74     }
75
76     /* (non-Javadoc)
77      * @see org.directwebremoting.OutboundVariable#getBuildCode()
78      */

79     public String JavaDoc getBuildCode()
80     {
81         if (!calculated)
82         {
83             calculate();
84         }
85
86         if (inline)
87         {
88             return getChildBuildCodes();
89         }
90         else
91         {
92             return notInlineDefinition.buildCode + getChildBuildCodes();
93         }
94     }
95
96     /* (non-Javadoc)
97      * @see org.directwebremoting.OutboundVariable#getAssignCode()
98      */

99     public String JavaDoc getAssignCode()
100     {
101         if (calculated)
102         {
103             if (inline)
104             {
105                 return assignCode;
106             }
107             else
108             {
109                 return varName;
110             }
111         }
112         else
113         {
114             // Someone is asking our name before we are calculated? This is
115
// likely to be because we are nested. calling calculate() is not
116
// possible because there might not be the data to make that work
117
// so we name ourselves, and return that.
118
if (forcedInlineStatus)
119             {
120                 if (inline)
121                 {
122                     return getInlineDefinition();
123                 }
124                 else
125                 {
126                     return getVariableName();
127                 }
128             }
129             else
130             {
131                 // log.debug("Moving outline. Do we need to? " + this);
132
setInline(false);
133                 return getVariableName();
134             }
135         }
136     }
137
138     /* (non-Javadoc)
139      * @see org.directwebremoting.OutboundVariable#getReference()
140      */

141     public OutboundVariable getReferenceVariable()
142     {
143         if (reference == null)
144         {
145             reference = new ReferenceOutboundVariable(getVariableName());
146             if (forcedInlineStatus)
147             {
148                 throw new IllegalStateException JavaDoc("Ignoring request to inline on reference for: " + this);
149             }
150             else
151             {
152                 setInline(false);
153             }
154         }
155
156         return reference;
157     }
158
159     /**
160      * Called at the last moment as the outputs are being read when we are
161      * sure if we are a reference or not.
162      */

163     private void calculate()
164     {
165         if (inline)
166         {
167             assignCode = getInlineDefinition();
168         }
169         else
170         {
171             notInlineDefinition = getNotInlineDefinition();
172         }
173
174         calculated = true;
175     }
176
177     /**
178      * Grab all the build codes together
179      * @return A build string
180      */

181     private String JavaDoc getChildBuildCodes()
182     {
183         if (children == null)
184         {
185             return "";
186         }
187
188         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
189
190         // Make sure the nested things are declared
191
for (Iterator JavaDoc it = children.iterator(); it.hasNext();)
192         {
193             OutboundVariable nested = (OutboundVariable) it.next();
194             buffer.append(nested.getBuildCode());
195         }
196
197         return buffer.toString();
198     }
199
200     /**
201      * Grab all the declare codes together
202      * @return A declare string
203      */

204     private String JavaDoc getChildDeclareCodes()
205     {
206         if (children == null)
207         {
208             return "";
209         }
210
211         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
212
213         // Make sure the nested things are declared
214
for (Iterator JavaDoc it = children.iterator(); it.hasNext();)
215         {
216             OutboundVariable nested = (OutboundVariable) it.next();
217             buffer.append(nested.getDeclareCode());
218         }
219
220         return buffer.toString();
221     }
222
223     /**
224      * @return the varName
225      */

226     protected String JavaDoc getVariableName()
227     {
228         if (varName == null)
229         {
230             varName = outboundContext.getNextVariableName();
231         }
232
233         return varName;
234     }
235
236     /**
237      * Define the definition we should use if we are being used not inline
238      * @return an out of line definition
239      */

240     protected abstract NotInlineDefinition getNotInlineDefinition();
241
242     /**
243      * Define the definition we should use if we are being used inline
244      * @return an inline definition
245      */

246     protected abstract String JavaDoc getInlineDefinition();
247
248     /**
249      * A helper struct to pass a build code and define code together
250      */

251     protected class NotInlineDefinition
252     {
253         protected NotInlineDefinition(String JavaDoc declareCode, String JavaDoc buildCode)
254         {
255             this.declareCode = declareCode;
256             this.buildCode = buildCode;
257         }
258
259         /**
260          * The code to be executed to do basic initialization
261          */

262         String JavaDoc declareCode;
263
264         /**
265          * The code to be executed to setup the data structure
266          */

267         String JavaDoc buildCode;
268     }
269
270     /**
271      * A helper to children get have definition info in {@link #toString()}
272      * @return For children to use in {@link #toString()}
273      */

274     protected String JavaDoc toStringDefinitionHint()
275     {
276         if (inline)
277         {
278             return "inline";
279         }
280         else
281         {
282             if (varName != null)
283             {
284                 return varName;
285             }
286             else
287             {
288                 return "?";
289             }
290         }
291     }
292
293     /**
294      * @param isInline The new inline status
295      */

296     private void setInline(boolean isInline)
297     {
298         if (calculated)
299         {
300             throw new IllegalStateException JavaDoc("Attempt to change inline status after calculation");
301         }
302
303         this.inline = isInline;
304     }
305
306     /**
307      * Does anything refer to us?
308      */

309     private OutboundVariable reference;
310
311     /**
312      * Are we known to be recursive
313      */

314     private boolean inline = true;
315
316     /**
317      * Have we forced an inline/outline status?
318      */

319     private boolean forcedInlineStatus = false;
320
321     /**
322      * Has calculate been run?
323      */

324     private boolean calculated = false;
325
326     /**
327      * The init code for the non-inline case
328      */

329     private NotInlineDefinition notInlineDefinition;
330
331     /**
332      * The code to be executed to get the value of the initialized data
333      */

334     private String JavaDoc assignCode;
335
336     /**
337      * If we get recursive, this is the variable name we declare
338      */

339     private String JavaDoc varName;
340
341     /**
342      * The conversion context
343      */

344     private OutboundContext outboundContext;
345
346     /**
347      * The OutboundVariables that we depend on
348      */

349     private Collection JavaDoc children;
350 }
351
Popular Tags