📄 whitespace.java
字号:
/* * Copyright 2001-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Id: Whitespace.java,v 1.5 2005/09/28 13:48:18 pvedula Exp $ */package com.sun.org.apache.xalan.internal.xsltc.compiler;import java.util.StringTokenizer;import java.util.Vector;import com.sun.org.apache.bcel.internal.generic.ALOAD;import com.sun.org.apache.bcel.internal.generic.BranchHandle;import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;import com.sun.org.apache.bcel.internal.generic.IF_ICMPEQ;import com.sun.org.apache.bcel.internal.generic.ILOAD;import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;import com.sun.org.apache.bcel.internal.generic.InstructionHandle;import com.sun.org.apache.bcel.internal.generic.InstructionList;import com.sun.org.apache.bcel.internal.generic.PUSH;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;/** * @author Morten Jorgensen */final class Whitespace extends TopLevelElement { // Three possible actions for the translet: public static final int USE_PREDICATE = 0; public static final int STRIP_SPACE = 1; public static final int PRESERVE_SPACE = 2; // The 3 different categories of strip/preserve rules (order important) public static final int RULE_NONE = 0; public static final int RULE_ELEMENT = 1; // priority 0 public static final int RULE_NAMESPACE = 2; // priority -1/4 public static final int RULE_ALL = 3; // priority -1/2 private String _elementList; private int _action; private int _importPrecedence; /** * Auxillary class for encapsulating a single strip/preserve rule */ private final static class WhitespaceRule { private final int _action; private String _namespace; // Should be replaced by NS type (int) private String _element; // Should be replaced by node type (int) private int _type; private int _priority; /** * Strip/preserve rule constructor */ public WhitespaceRule(int action, String element, int precedence) { // Determine the action (strip or preserve) for this rule _action = action; // Get the namespace and element name for this rule final int colon = element.lastIndexOf(':'); if (colon >= 0) { _namespace = element.substring(0,colon); _element = element.substring(colon+1,element.length()); } else { _namespace = Constants.EMPTYSTRING; _element = element; } // Determine the initial priority for this rule _priority = precedence << 2; // Get the strip/preserve type; either "NS:EL", "NS:*" or "*" if (_element.equals("*")) { if (_namespace == Constants.EMPTYSTRING) { _type = RULE_ALL; // Strip/preserve _all_ elements _priority += 2; // Lowest priority } else { _type = RULE_NAMESPACE; // Strip/reserve elements within NS _priority += 1; // Medium priority } } else { _type = RULE_ELEMENT; // Strip/preserve single element } } /** * For sorting rules depending on priority */ public int compareTo(WhitespaceRule other) { return _priority < other._priority ? -1 : _priority > other._priority ? 1 : 0; } public int getAction() { return _action; } public int getStrength() { return _type; } public int getPriority() { return _priority; } public String getElement() { return _element; } public String getNamespace() { return _namespace; } } /** * Parse the attributes of the xsl:strip/preserve-space element. * The element should have not contents (ignored if any). */ public void parseContents(Parser parser) { // Determine if this is an xsl:strip- or preserve-space element _action = _qname.getLocalPart().endsWith("strip-space") ? STRIP_SPACE : PRESERVE_SPACE; // Determine the import precedence _importPrecedence = parser.getCurrentImportPrecedence(); // Get the list of elements to strip/preserve _elementList = getAttribute("elements"); if (_elementList == null || _elementList.length() == 0) { reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "elements"); return; } final SymbolTable stable = parser.getSymbolTable(); StringTokenizer list = new StringTokenizer(_elementList); StringBuffer elements = new StringBuffer(Constants.EMPTYSTRING); while (list.hasMoreElements()) { String token = list.nextToken(); String prefix; String namespace; int col = token.indexOf(':'); if (col != -1) { namespace = lookupNamespace(token.substring(0,col)); if (namespace != null) { elements.append(namespace+":"+ token.substring(col+1,token.length())); } else { elements.append(token); } } else { elements.append(token); } if (list.hasMoreElements()) elements.append(" "); } _elementList = elements.toString(); } /** * De-tokenize the elements listed in the 'elements' attribute and * instanciate a set of strip/preserve rules. */ public Vector getRules() { final Vector rules = new Vector(); // Go through each element and instanciate strip/preserve-object final StringTokenizer list = new StringTokenizer(_elementList); while (list.hasMoreElements()) { rules.add(new WhitespaceRule(_action, list.nextToken(), _importPrecedence)); } return rules; } /** * Scans through the rules vector and looks for a rule of higher * priority that contradicts the current rule. */ private static WhitespaceRule findContradictingRule(Vector rules, WhitespaceRule rule) { for (int i = 0; i < rules.size(); i++) { // Get the next rule in the prioritized list WhitespaceRule currentRule = (WhitespaceRule)rules.elementAt(i); // We only consider rules with higher priority if (currentRule == rule) { return null; } /* * See if there is a contradicting rule with higher priority. * If the rules has the same action then this rule is redundant, * if they have different action then this rule will never win. */ switch (currentRule.getStrength()) { case RULE_ALL: return currentRule; case RULE_ELEMENT: if (!rule.getElement().equals(currentRule.getElement())) { break; } // intentional fall-through case RULE_NAMESPACE: if (rule.getNamespace().equals(currentRule.getNamespace())) { return currentRule; } break; } } return null; } /** * Orders a set or rules by priority, removes redundant rules and rules * that are shadowed by stronger, contradicting rules. */ private static int prioritizeRules(Vector rules) { WhitespaceRule currentRule; int defaultAction = PRESERVE_SPACE; // Sort all rules with regard to priority quicksort(rules, 0, rules.size()-1); // Check if there are any "xsl:strip-space" elements at all. // If there are no xsl:strip elements we can ignore all xsl:preserve // elements and signal that all whitespaces should be preserved boolean strip = false; for (int i = 0; i < rules.size(); i++) { currentRule = (WhitespaceRule)rules.elementAt(i); if (currentRule.getAction() == STRIP_SPACE) { strip = true; } } // Return with default action: PRESERVE_SPACE if (!strip) { rules.removeAllElements(); return PRESERVE_SPACE; } // Remove all rules that are contradicted by rules with higher priority for (int idx = 0; idx < rules.size(); ) { currentRule = (WhitespaceRule)rules.elementAt(idx); // Remove this single rule if it has no purpose if (findContradictingRule(rules,currentRule) != null) { rules.remove(idx); } else { // Remove all following rules if this one overrides all if (currentRule.getStrength() == RULE_ALL) { defaultAction = currentRule.getAction(); for (int i = idx; i < rules.size(); i++) { rules.removeElementAt(i); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -