KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > style > XSLCharacterMap


1 package net.sf.saxon.style;
2 import net.sf.saxon.Err;
3 import net.sf.saxon.expr.Expression;
4 import net.sf.saxon.instruct.Executable;
5 import net.sf.saxon.om.*;
6 import net.sf.saxon.trans.XPathException;
7
8 import java.util.*;
9
10 /**
11 * An xsl:character-map declaration in the stylesheet. <br>
12 */

13
14 public class XSLCharacterMap extends StyleElement {
15
16     //int fingerprint;
17
// the name of this character map
18

19     String JavaDoc use;
20                 // the value of the use-character-maps attribute, as supplied
21

22     List characterMapElements = null;
23                 // list of XSLCharacterMap objects referenced by this one
24

25     boolean validated = false;
26                 // set to true once validate() has been called
27

28     boolean redundant = false;
29                 // set to true if another character-map overrrides this one
30

31     /**
32      * Get the fingerprint of the name of this character map
33      * @return the fingerprint value
34      */

35
36     public int getCharacterMapFingerprint() {
37         return getObjectNameCode() & 0xfffff;
38     }
39
40     /**
41      * Test whether this character map is redundant (because another with the
42      * same name has higher import precedence). Note that a character map is not
43      * considered redundant simply because it is not referenced in an xsl:output
44      * declaration; we allow character-maps to be selected at run-time using the
45      * setOutputProperty() API.
46      */

47
48     public boolean isRedundant() {
49         return redundant;
50     }
51
52     /**
53      * Validate the attributes on this instruction
54      * @throws XPathException
55      */

56
57     public void prepareAttributes() throws XPathException {
58
59         String JavaDoc name = null;
60         use = null;
61
62         AttributeCollection atts = getAttributeList();
63
64         for (int a=0; a<atts.getLength(); a++) {
65             int nc = atts.getNameCode(a);
66             String JavaDoc f = getNamePool().getClarkName(nc);
67             if (f==StandardNames.NAME) {
68                 name = atts.getValue(a).trim();
69             } else if (f==StandardNames.USE_CHARACTER_MAPS) {
70                 use = atts.getValue(a);
71             } else {
72                 checkUnknownAttribute(nc);
73             }
74         }
75
76         if (name==null) {
77             reportAbsence("name");
78             return;
79         }
80
81         try {
82             setObjectNameCode(makeNameCode(name.trim()));
83         } catch (NamespaceException err) {
84             compileError(err.getMessage(), "XTSE0280");
85         } catch (XPathException err) {
86             compileError(err.getMessage());
87         }
88
89     }
90
91     public void validate() throws XPathException {
92
93         if (validated) return;
94
95         // check that this is a top-level declaration
96

97         checkTopLevel(null);
98
99         // check that the only children are xsl:output-character elements
100

101         AxisIterator kids = iterateAxis(Axis.CHILD);
102         while (true) {
103             Item child = kids.next();
104             if (child == null) {
105                 break;
106             }
107             if (!(child instanceof XSLOutputCharacter)) {
108                 compileError("Only xsl:output-character is allowed within xsl:character-map", "XTSE0010");
109             }
110         }
111
112         // check that there isn't another character-map with the same name and import
113
// precedence
114

115         XSLStylesheet principal = getPrincipalStylesheet();
116         XSLCharacterMap other = principal.getCharacterMap(getObjectFingerprint());
117         if (other != this) {
118             if (this.getPrecedence() == other.getPrecedence()) {
119                 compileError("There are two character-maps with the same name and import precedence", "XTSE1580");
120             } else if (this.getPrecedence() < other.getPrecedence()) {
121                 redundant = true;
122             }
123         }
124
125         // validate the use-character-maps attribute
126

127         if (use!=null) {
128
129             // identify any character maps that this one refers to
130

131             characterMapElements = new ArrayList(5);
132             StringTokenizer st = new StringTokenizer(use);
133
134             while (st.hasMoreTokens()) {
135                 String JavaDoc displayname = st.nextToken();
136                 try {
137                     String JavaDoc[] parts = Name.getQNameParts(displayname);
138                     String JavaDoc uri = getURIForPrefix(parts[0], false);
139                     if (uri == null) {
140                         compileError("Undeclared namespace prefix " + Err.wrap(parts[0])
141                                 + " in character map name", "XTSE0280");
142                     }
143                     int nameCode = getTargetNamePool().allocate(parts[0], uri, parts[1]);
144                     XSLCharacterMap ref =
145                             principal.getCharacterMap(nameCode & 0xfffff);
146                     if (ref == null) {
147                         compileError("No character-map named '" + displayname + "' has been defined", "XTSE1590");
148                     } else {
149                         characterMapElements.add(ref);
150                     }
151                 } catch (QNameException err) {
152                     compileError("Invalid character-map name. " + err.getMessage(), "XTSE1590");
153                 }
154             }
155
156             // check for circularity
157

158             for (Iterator it=characterMapElements.iterator(); it.hasNext();) {
159                 ((XSLCharacterMap)it.next()).checkCircularity(this);
160             }
161         }
162
163         validated = true;
164     }
165
166     /**
167     * Check for circularity: specifically, check that this attribute set does not contain
168     * a direct or indirect reference to the one supplied as a parameter
169     */

170
171     private void checkCircularity(XSLCharacterMap origin) throws XPathException {
172         if (this==origin) {
173             compileError("The definition of the character map is circular", "XTSE1600");
174             characterMapElements = null; // for error recovery
175
} else {
176             if (!validated) {
177                 // if this attribute set isn't validated yet, we don't check it.
178
// The circularity will be detected when the last attribute set in the cycle
179
// gets validated
180
return;
181             }
182             if (characterMapElements != null) {
183                 for (Iterator it=characterMapElements.iterator(); it.hasNext();) {
184                     ((XSLCharacterMap)it.next()).checkCircularity(origin);
185                 }
186             }
187         }
188     }
189
190     /**
191      * Assemble all the mappings defined by this character map, adding them to a
192      * HashMap that maps integer codepoints to strings
193      */

194
195     public void assemble(HashMap map) {
196         if (characterMapElements != null) {
197             for (int i = 0; i < characterMapElements.size(); i++) {
198                 XSLCharacterMap charmap = (XSLCharacterMap) characterMapElements.get(i);
199                 charmap.assemble(map);
200             }
201         }
202         AxisIterator kids = iterateAxis(Axis.CHILD);
203         while (true) {
204             Item child = kids.next();
205             if (child == null) {
206                 return;
207             }
208             XSLOutputCharacter oc = (XSLOutputCharacter)child;
209             map.put(new Integer JavaDoc(oc.getCodePoint()), oc.getReplacementString());
210         }
211     }
212
213     public Expression compile(Executable exec) throws XPathException {
214         return null;
215     }
216
217 }
218
219 //
220
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
221
// you may not use this file except in compliance with the License. You may obtain a copy of the
222
// License at http://www.mozilla.org/MPL/
223
//
224
// Software distributed under the License is distributed on an "AS IS" basis,
225
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
226
// See the License for the specific language governing rights and limitations under the License.
227
//
228
// The Original Code is: all this file.
229
//
230
// The Initial Developer of the Original Code is Michael H. Kay
231
//
232
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
233
//
234
// Contributor(s): none.
235
//
236
Popular Tags