KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ejen > EjenChildNode


1 //
2
// Ejen (code generation system)
3
// Copyright (C) 2001, 2002 François Wolff (ejen@noos.fr).
4
//
5
// This file is part of Ejen.
6
//
7
// Ejen is free software; you can redistribute it and/or modify
8
// it under the terms of the GNU General Public License as published by
9
// the Free Software Foundation; either version 2 of the License, or
10
// (at your option) any later version.
11
//
12
// Ejen is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
// GNU General Public License for more details.
16
//
17
// You should have received a copy of the GNU General Public License
18
// along with Ejen; if not, write to the Free Software
19
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
//
21
package org.ejen;
22
23 import org.ejen.util.XSLUtil;
24 import java.util.Properties JavaDoc;
25 import java.util.Vector JavaDoc;
26 import javax.xml.transform.dom.DOMSource JavaDoc;
27 import org.apache.xalan.transformer.TransformerImpl;
28 import org.apache.xalan.processor.StylesheetHandler;
29
30 /**
31  * Parent abstract class of all Ejen...Node classes.
32  * @author F. Wolff
33  * @version 1.0
34  */

35 public abstract class EjenChildNode implements EjenConstants {
36
37     /** Stack of contexts (current transformer,...) */
38     private static final EjenContextsStack _ejenContextsStack = new EjenContextsStack();
39
40     /** Current listener for message/error reporting. */
41     private static EjenListener _ejenListener = null;
42
43     /** Indentation string for message reporting. */
44     protected static String JavaDoc _messageIndent = "";
45
46     /**
47      * Current state of this EjenChildNode
48      * ({@link org.ejen.EjenConstants#STATE_IDLE}).
49      */

50     private int _state = STATE_IDLE;
51
52     /**
53      * Returns the name of this EjenChildNode.
54      * @return name of this EjenChildNode.
55      */

56     public abstract String JavaDoc nodeName();
57
58     /**
59      * Returns the attributes of this EjenChildNode (empty here).
60      * @return a Properties that contains all attributes of this EjenChildNode.
61      */

62     public Properties JavaDoc getAttributes() {
63         return new Properties JavaDoc();
64     }
65
66     /**
67      * Returns the children of this EjenChildNode (empty here).
68      * @return a Vector that contains all children of this EjenChildNode.
69      */

70     public Vector JavaDoc getChildren() {
71         return new Vector JavaDoc();
72     }
73
74     /**
75      * Check this EjenChildNode for mandatory attributes/child nodes.
76      * Only sends a state change event here ({@link org.ejen.EjenConstants#STATE_CHECK}).
77      */

78     public void check() {
79         _state = STATE_CHECK;
80         sendStateEvent();
81     }
82     
83     /**
84      * Prepares this EjenChildNode execution.
85      * Only sends a state change event here ({@link org.ejen.EjenConstants#STATE_BEFORE_PROCESS}).
86      */

87     public void beforeProcess() {
88         _state = STATE_BEFORE_PROCESS;
89         sendStateEvent();
90     }
91
92     /**
93      * Executes this EjenChildNode.
94      * Only sends a state change event here ({@link org.ejen.EjenConstants#STATE_PROCESS}).
95      */

96     public void process() {
97         _state = STATE_PROCESS;
98         sendStateEvent();
99     }
100
101     /**
102      * Does post-execution actions after this EjenChildNode execution.
103      * Only sends a state change event here ({@link org.ejen.EjenConstants#STATE_AFTER_PROCESS}).
104      */

105     public void afterProcess() {
106         _state = STATE_AFTER_PROCESS;
107         sendStateEvent();
108     }
109
110     /**
111      * Signals that this EjenChildNode has completly terminated its execution (including
112      * any post-execution actions).
113      * Only sends a state change event here ({@link org.ejen.EjenConstants#STATE_IDLE}).
114      */

115     public final void idle() {
116         _state = STATE_IDLE;
117         sendStateEvent();
118     }
119     
120     /**
121      * Returns the current state of this EjenChildNode.
122      * @return the current state (see {@link org.ejen.EjenConstants}).
123      */

124     public final int getState() {
125         return _state;
126     }
127
128     /**
129      * Sets the listener for all EjenChildNode classes (the listener is static).
130      * @param ejenListener the new EjenListener.
131      */

132     public static final void setListener(EjenListener ejenListener) {
133         _ejenListener = ejenListener;
134     }
135
136     /**
137      * Returns the current listener for all EjenChildNode classes (the listener is static).
138      * @return the current EjenListener.
139      */

140     public static final EjenListener getListener() {
141         return _ejenListener;
142     }
143
144     /**
145      * Sends a state change event (according to the current state of this EjenChildNode).
146      * Does nothing if there is no listener.
147      */

148     public final void sendStateEvent() {
149         if (_ejenListener != null) {
150             _ejenListener.stateChanged(new EjenEvent(this, STATES[_state],
151                     MSG_VERBOSE));
152         }
153     }
154
155     /**
156      * Sends a message event from this EjenChildNode (with level
157      * Does nothing if there is no listener.
158      * {@link org.ejen.EjenConstants#MSG_INFO}).
159      * @param msg the message to send to the listener.
160      */

161     public final void sendMessageEvent(String JavaDoc msg) {
162         sendMessageEvent(msg, MSG_INFO);
163     }
164
165     /**
166      * Sends a message event from this EjenChildNode (with a specific level).
167      * Does nothing if there is no listener.
168      * @param msg the message to send to the listener.
169      * @param level level of the message (see {@link org.ejen.EjenConstants}).
170      */

171     public final void sendMessageEvent(String JavaDoc msg, int level) {
172         if (_ejenListener != null) {
173             _ejenListener.nodeMessageSent(new EjenEvent(this,
174                     _messageIndent + msg, level));
175         }
176     }
177
178     /**
179      * Sends a message event from an XSL file (via the
180      * {@link org.ejen.ext.Messenger#send(XSLProcessorContext context, ElemExtensionCall elem)}
181      * extension function).
182      * Does nothing if there is no listener.
183      * @param msg the message to send to the listener.
184      */

185     public static final void sendXSLMessageEvent(String JavaDoc msg) {
186         sendXSLMessageEvent(msg, MSG_INFO);
187     }
188
189     /**
190      * Sends a message event from an XSL file (via the
191      * {@link org.ejen.ext.Messenger#send(XSLProcessorContext context, ElemExtensionCall elem)}
192      * extension function), with specific level.
193      * Does nothing if there is no listener.
194      * @param msg the message to send to the listener.
195      * @param level level of the message (see {@link org.ejen.EjenConstants}).
196      */

197     public static final void sendXSLMessageEvent(String JavaDoc msg, int level) {
198         if (_ejenListener != null) {
199             _ejenListener.xslMessageSent(new EjenEvent("(xsl)",
200                     _messageIndent + "[xsl] " + msg, level));
201         }
202     }
203
204     /**
205      * Returns the String representation of this EjenChildNode, in the form of
206      * "<node_name> {[<attribute_name_1>=<attribute_value_1>[, <attribute_name_2>=<attribute_value_2> ...]]}".
207      * @return the String representation of this EjenChildNode.
208      */

209     public final String JavaDoc toString() {
210         return nodeName() + " " + getAttributes();
211     }
212     
213     /**
214      * Returns an Object (whose name is 'name') from the current context stack.
215      * @param name name of the Object to be returned.
216      * @return the Object (may be null if there is no such name).
217      */

218     protected final Object JavaDoc getFromContext(String JavaDoc name) {
219         return _ejenContextsStack.peekContext().get(name);
220     }
221     
222     /**
223      * Returns an Object (whose name is 'name') from the current context stack.
224      * @param name name of the value to be returned.
225      * @param offset a negative value or zero (to access any context in the stack).
226      * @return the Object (may be null if there is no such name).
227      * @throws java.util.EmptyStackException if the stack is empty.
228      */

229     protected final Object JavaDoc getFromContext(String JavaDoc name, int offset) {
230         return _ejenContextsStack.peekContext(_ejenContextsStack.size() + offset - 1).get(name);
231     }
232     
233     /**
234      * Returns an Object (whose name is 'name') from the global (shared) context.
235      * @param name name of the value to be returned.
236      * @return the Object (may be null if there is no such name).
237      */

238     protected final Object JavaDoc getFromGlobalContext(String JavaDoc name) {
239         return _ejenContextsStack.globalGet(name);
240     }
241     
242     /**
243      * Puts an Object (whose name is 'name') in the current context (on the top
244      * of the stack).
245      * @param name name of the Object to be put in the context.
246      * @param value the Object.
247      * @return the previous Object mapped to the name (may be null).
248      */

249     protected final Object JavaDoc putInContext(String JavaDoc name, Object JavaDoc value) {
250         return _ejenContextsStack.peekContext().put(name, value);
251     }
252     
253     /**
254      * Puts an Object (whose name is 'name') in the global (shared) context.
255      * @param name name of the Object to be put in the context.
256      * @param value the Object.
257      * @return the previous Object mapped to the name (may be null).
258      */

259     protected final Object JavaDoc putInGlobalContext(String JavaDoc name, Object JavaDoc value) {
260         return _ejenContextsStack.globalPut(name, value);
261     }
262     
263     /**
264      * Pops the current context from the contexts stack.
265      * @return the current EjenContext (may not be null).
266      * @throws java.util.EmptyStackException if the stack is empty.
267      */

268     protected final EjenContext popContext() {
269         return _ejenContextsStack.popContext();
270     }
271     
272     /**
273      * Pushes a new EjenContext onto the top of the contexts stack.
274      * @param ejenContext the new EjenContext to be pushed.
275      * @throws java.util.EmptyStackException if the stack is empty.
276      */

277     protected final EjenContext pushContext(EjenContext ejenContext) {
278         return _ejenContextsStack.pushContext(ejenContext);
279     }
280     
281     /**
282      * Duplicates the current context (or creates a new one if the stack is empty).
283      * @return the cloned context.
284      */

285     protected final EjenContext cloneContext() {
286         if (!_ejenContextsStack.isEmpty()) {
287             return new EjenContext(_ejenContextsStack.peekContext());
288         } else {
289             return new EjenContext();
290         }
291     }
292     
293     /**
294      * Returns the evaluation of an Attribute Value Template.
295      * @param avt the Attribute Value Template.
296      * @return the evaluation of the Attribute Value Template.
297      * @throws org.ejen.EjenException if something goes wrong.
298      */

299     protected final String JavaDoc evaluateAVT(String JavaDoc avt) {
300         TransformerImpl ti = null;
301
302         try {
303             ti = (TransformerImpl) (getFromGlobalContext(CTX_TRANSFORMER_IMPL));
304         } catch (Exception JavaDoc e) {
305             throw new EjenException(this, null, e);
306         }
307         if (ti == null) {
308             throw new EjenException(this,
309                     "no '" + CTX_TRANSFORMER_IMPL + "' in global context");
310         }
311         
312         return evaluateAVT(ti, avt);
313     }
314     
315     /**
316      * Returns the evaluation of an Attribute Value Template, using the provided
317      * TransformerImpl object.
318      * @param ti a TransformerImpl instance.
319      * @param avt the Attribute Value Template.
320      * @return the evaluation of the Attribute Value Template.
321      * @throws org.ejen.EjenException if something goes wrong.
322      */

323     protected final String JavaDoc evaluateAVT(TransformerImpl ti, String JavaDoc avt) {
324         StylesheetHandler sh = null;
325         DOMSource JavaDoc src = null;
326
327         try {
328             src = (DOMSource JavaDoc) (getFromGlobalContext(CTX_DOM_SOURCE));
329             sh = (StylesheetHandler) (getFromGlobalContext(CTX_STYLESHEET_HANDLER));
330         } catch (Exception JavaDoc e) {
331             throw new EjenException(this, null, e);
332         }
333         if (sh == null) {
334             throw new EjenException(this,
335                     "no '" + CTX_STYLESHEET_HANDLER + "' in global context");
336         }
337         if (src == null) {
338             throw new EjenException(this,
339                     "no '" + CTX_DOM_SOURCE + "' in global context");
340         }
341         try {
342             String JavaDoc s = XSLUtil.evaluateAttribute(sh, ti.getXPathContext(),
343                     src.getNode(), avt);
344
345             if (!s.equals(avt)) {
346                 sendMessageEvent("Resolved '" + avt + "' into '" + s + "'");
347             }
348             return s;
349         } catch (Exception JavaDoc e) {
350             throw new EjenException(this, null, e);
351         }
352     }
353 }
354
Popular Tags