KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > config > serverbeans > validation > VariableExpander


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 package com.sun.enterprise.config.serverbeans.validation;
25
26 import org.xml.sax.Attributes JavaDoc;
27 import org.xml.sax.SAXException JavaDoc;
28 import org.xml.sax.XMLReader JavaDoc;
29 import org.xml.sax.helpers.AttributesImpl JavaDoc;
30 import org.xml.sax.helpers.XMLFilterImpl JavaDoc;
31
32 /**
33    This class provides a variable expansion mechanism on a sax
34    stream. Variable references are strings that begin with "${" and
35    end with "}", with the variable name lying between the braces. For
36    example "${foo}" is a reference to a variable called "foo". From
37    some given set of definitions for these variables this class
38    expands these variables on the fly. For example, if the variable
39    foo is defined as having the value "27", then the following
40    element:
41    <pre>
42    <element attr="${foo}"/>
43    </pre>
44    would be expanded to:
45    <element attr="27"/>
46
47    In addition to providing a simple variable expansion mechanism the
48    class has to cope with the fact that the variable definitions to be
49    used depend upon where the variable reference is found. One
50    definition can come into scope for a while, and then go out of
51    scope. The scoping mechanism is handled by the {@link Framer}
52    class.
53
54  */

55
56 // This class operates by receiving SAX events from its parent
57
// XMLReader
58
class VariableExpander extends XMLFilterImpl JavaDoc
59 {
60
61     Framer framer = new Framer();
62     
63     private static final String JavaDoc START="${";
64     private static final String JavaDoc END="}";
65
66       // Characters can come in chunks, so we need to store them. When
67
// characters come in we can only eval them *after* the
68
// endElement event, which has already popped the frame off the
69
// stack - so while collecting characters we remember the frame
70
// present when the characters were sent, and then use that
71
// frame to eval the characters.
72
private StringBuffer JavaDoc characters = new StringBuffer JavaDoc();
73     private Frame frame;
74
75     VariableExpander(){
76         super();
77     }
78
79     
80     VariableExpander(Framer f){
81         framer = f;
82 // super.setParent(f);
83
}
84
85     void setFramer(Framer f){
86 // if (framer != null && framer.getParent() != null) {
87
// f.setParent(framer.getParent());
88
// }
89
// super.setParent(f);
90
framer = f;
91     }
92     
93 // public void setParent(XMLReader parent){
94
// framer.setParent(parent);
95
// }
96

97 // public XMLReader getParent(){
98
// return framer.getParent();
99
// }
100

101     public void characters(char [] ch, int start, int len) throws SAXException JavaDoc {
102         characters.append(ch, start, len);
103 // frame = framer.currentFrame();
104
}
105
106     public void endDocument() throws SAXException JavaDoc {
107         processCharacters();
108         framer.endDocument();
109         super.endDocument();
110     }
111     
112     public void endElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName) throws SAXException JavaDoc {
113         processCharacters();
114         framer.endElement(namespaceURI, localName, qName);
115         super.endElement(namespaceURI, localName, qName);
116     }
117
118     public void startElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName, Attributes JavaDoc atts) throws SAXException JavaDoc {
119         processCharacters();
120         framer.startElement(namespaceURI, localName, qName, atts);
121         final Attributes JavaDoc newAtts = processAttributes(atts);
122         super.startElement(namespaceURI, localName, qName, newAtts);
123     }
124     private void processCharacters() throws SAXException JavaDoc {
125         if (characters.length() > 0){
126             final String JavaDoc chars = expandVariables(characters.toString());
127             super.characters(chars.toCharArray(), 0, chars.length());
128             characters.setLength(0);
129 // frame = null;
130
}
131     }
132     
133
134     private String JavaDoc expandVariables(final String JavaDoc chars){
135         return expandVariables(chars, framer.currentFrame());
136     }
137
138     private String JavaDoc expandVariables(final String JavaDoc chars, final Frame f){
139         return ((chars.indexOf(START) < chars.indexOf(END)) ? eval(chars, f) : chars);
140     }
141     
142     private Attributes JavaDoc processAttributes(final Attributes JavaDoc atts){
143         final AttributesImpl JavaDoc newAtts = new AttributesImpl JavaDoc(atts);
144         for (int i = 0; i < newAtts.getLength(); i++){
145             newAtts.setValue(i, expandVariables(newAtts.getValue(i)));
146         }
147         return newAtts;
148     }
149     
150
151     String JavaDoc eval(final String JavaDoc chars, final Frame frame){
152         debug("expanding \""+chars+"\"");
153         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
154         int vs, ve = 0; // variable start, end
155
// loop invariant - i is at start of next part of string to
156
// be examined. sb contains all previous parts of string,
157
// including the translated portions
158
for (int i = 0; i < chars.length(); ){
159             if (((vs = chars.indexOf(START, i)) != -1) && ((ve = chars.indexOf(END, i)) != -1)) {
160                 sb.append(chars.substring(i, vs)); // copy prefix
161
sb.append(frame.lookup(chars.substring(vs+2, ve)));
162                 i = ve + 1;
163             } else { // No variable to be expanded
164
sb.append(chars.substring(i));
165                 i = chars.length();
166             }
167         }
168         return sb.toString();
169     }
170
171     private final boolean DEBUG = false;
172     
173     private final void debug(final String JavaDoc s){
174        if (DEBUG) System.err.println(s);
175     }
176     
177         
178 }
179
180     
181
Popular Tags