001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 /*
019 * $Id: UnsupportedElement.java 468650 2006-10-28 07:03:30Z minchau $
020 */
021
022 package org.apache.xalan.xsltc.compiler;
023
024 import java.util.Vector;
025
026 import org.apache.bcel.generic.ConstantPoolGen;
027 import org.apache.bcel.generic.INVOKESTATIC;
028 import org.apache.bcel.generic.InstructionList;
029 import org.apache.bcel.generic.PUSH;
030
031 import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
032 import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
033 import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
034 import org.apache.xalan.xsltc.compiler.util.Type;
035 import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
036 import org.apache.xalan.xsltc.compiler.util.Util;
037
038 /**
039 * @author Morten Jorgensen
040 */
041 final class UnsupportedElement extends SyntaxTreeNode {
042
043 private Vector _fallbacks = null;
044 private ErrorMsg _message = null;
045 private boolean _isExtension = false;
046
047 /**
048 * Basic consutrcor - stores element uri/prefix/localname
049 */
050 public UnsupportedElement(String uri, String prefix, String local, boolean isExtension) {
051 super(uri, prefix, local);
052 _isExtension = isExtension;
053 }
054
055 /**
056 * There are different categories of unsupported elements (believe it
057 * or not): there are elements within the XSLT namespace (these would
058 * be elements that are not yet implemented), there are extensions of
059 * other XSLT processors and there are unrecognised extension elements
060 * of this XSLT processor. The error message passed to this method
061 * should describe the unsupported element itself and what category
062 * the element belongs in.
063 */
064 public void setErrorMessage(ErrorMsg message) {
065 _message = message;
066 }
067
068 /**
069 * Displays the contents of this element
070 */
071 public void display(int indent) {
072 indent(indent);
073 Util.println("Unsupported element = " + _qname.getNamespace() +
074 ":" + _qname.getLocalPart());
075 displayContents(indent + IndentIncrement);
076 }
077
078
079 /**
080 * Scan and process all fallback children of the unsupported element.
081 */
082 private void processFallbacks(Parser parser) {
083
084 Vector children = getContents();
085 if (children != null) {
086 final int count = children.size();
087 for (int i = 0; i < count; i++) {
088 SyntaxTreeNode child = (SyntaxTreeNode)children.elementAt(i);
089 if (child instanceof Fallback) {
090 Fallback fallback = (Fallback)child;
091 fallback.activate();
092 fallback.parseContents(parser);
093 if (_fallbacks == null) {
094 _fallbacks = new Vector();
095 }
096 _fallbacks.addElement(child);
097 }
098 }
099 }
100 }
101
102 /**
103 * Find any fallback in the descendant nodes; then activate & parse it
104 */
105 public void parseContents(Parser parser) {
106 processFallbacks(parser);
107 }
108
109 /**
110 * Run type check on the fallback element (if any).
111 */
112 public Type typeCheck(SymbolTable stable) throws TypeCheckError {
113 if (_fallbacks != null) {
114 int count = _fallbacks.size();
115 for (int i = 0; i < count; i++) {
116 Fallback fallback = (Fallback)_fallbacks.elementAt(i);
117 fallback.typeCheck(stable);
118 }
119 }
120 return Type.Void;
121 }
122
123 /**
124 * Translate the fallback element (if any).
125 */
126 public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
127 if (_fallbacks != null) {
128 int count = _fallbacks.size();
129 for (int i = 0; i < count; i++) {
130 Fallback fallback = (Fallback)_fallbacks.elementAt(i);
131 fallback.translate(classGen, methodGen);
132 }
133 }
134 // We only go into the else block in forward-compatibility mode, when
135 // the unsupported element has no fallback.
136 else {
137 // If the unsupported element does not have any fallback child, then
138 // at runtime, a runtime error should be raised when the unsupported
139 // element is instantiated. Otherwise, no error is thrown.
140 ConstantPoolGen cpg = classGen.getConstantPool();
141 InstructionList il = methodGen.getInstructionList();
142
143 final int unsupportedElem = cpg.addMethodref(BASIS_LIBRARY_CLASS, "unsupported_ElementF",
144 "(" + STRING_SIG + "Z)V");
145 il.append(new PUSH(cpg, getQName().toString()));
146 il.append(new PUSH(cpg, _isExtension));
147 il.append(new INVOKESTATIC(unsupportedElem));
148 }
149 }
150 }