1 /*
   2  * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
   3  */
   4 /*
   5  * Licensed to the Apache Software Foundation (ASF) under one or more
   6  * contributor license agreements.  See the NOTICE file distributed with
   7  * this work for additional information regarding copyright ownership.
   8  * The ASF licenses this file to You under the Apache License, Version 2.0
   9  * (the "License"); you may not use this file except in compliance with
  10  * the License.  You may obtain a copy of the License at
  11  *
  12  *     http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 /*
  21  * $Id: UnsupportedElement.java,v 1.2.4.1 2005/09/05 09:26:51 pvedula Exp $
  22  */
  23 
  24 package com.sun.org.apache.xalan.internal.xsltc.compiler;
  25 
  26 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
  27 import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC;
  28 import com.sun.org.apache.bcel.internal.generic.InstructionList;
  29 import com.sun.org.apache.bcel.internal.generic.PUSH;
  30 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
  31 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
  32 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
  33 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
  34 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
  35 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;
  36 import java.util.ArrayList;
  37 import java.util.List;
  38 
  39 /**
  40  * @author Morten Jorgensen
  41  * @LastModified: Oct 2017
  42  */
  43 final class UnsupportedElement extends SyntaxTreeNode {
  44 
  45     private List<SyntaxTreeNode> _fallbacks = null;
  46     private ErrorMsg _message = null;
  47     private boolean _isExtension = false;
  48 
  49     /**
  50      * Basic consutrcor - stores element uri/prefix/localname
  51      */
  52     public UnsupportedElement(String uri, String prefix, String local, boolean isExtension) {
  53         super(uri, prefix, local);
  54         _isExtension = isExtension;
  55     }
  56 
  57     /**
  58      * There are different categories of unsupported elements (believe it
  59      * or not): there are elements within the XSLT namespace (these would
  60      * be elements that are not yet implemented), there are extensions of
  61      * other XSLT processors and there are unrecognised extension elements
  62      * of this XSLT processor. The error message passed to this method
  63      * should describe the unsupported element itself and what category
  64      * the element belongs in.
  65      */
  66     public void setErrorMessage(ErrorMsg message) {
  67         _message = message;
  68     }
  69 
  70     /**
  71      * Displays the contents of this element
  72      */
  73     public void display(int indent) {
  74         indent(indent);
  75         Util.println("Unsupported element = " + _qname.getNamespace() +
  76                      ":" + _qname.getLocalPart());
  77         displayContents(indent + IndentIncrement);
  78     }
  79 
  80 
  81     /**
  82      * Scan and process all fallback children of the unsupported element.
  83      */
  84     private void processFallbacks(Parser parser) {
  85 
  86         List<SyntaxTreeNode> children = getContents();
  87         if (children != null) {
  88             final int count = children.size();
  89             for (int i = 0; i < count; i++) {
  90                 SyntaxTreeNode child = children.get(i);
  91                 if (child instanceof Fallback) {
  92                     Fallback fallback = (Fallback)child;
  93                     fallback.activate();
  94                     fallback.parseContents(parser);
  95                     if (_fallbacks == null) {
  96                         _fallbacks = new ArrayList<>();
  97                     }
  98                     _fallbacks.add(child);
  99                 }
 100             }
 101         }
 102     }
 103 
 104     /**
 105      * Find any fallback in the descendant nodes; then activate & parse it
 106      */
 107     public void parseContents(Parser parser) {
 108         processFallbacks(parser);
 109     }
 110 
 111     /**
 112      * Run type check on the fallback element (if any).
 113      */
 114     public Type typeCheck(SymbolTable stable) throws TypeCheckError {
 115         if (_fallbacks != null) {
 116             int count = _fallbacks.size();
 117             for (int i = 0; i < count; i++) {
 118                 Fallback fallback = (Fallback)_fallbacks.get(i);
 119                 fallback.typeCheck(stable);
 120             }
 121         }
 122         return Type.Void;
 123     }
 124 
 125     /**
 126      * Translate the fallback element (if any).
 127      */
 128     public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
 129         if (_fallbacks != null) {
 130             int count = _fallbacks.size();
 131             for (int i = 0; i < count; i++) {
 132                 Fallback fallback = (Fallback)_fallbacks.get(i);
 133                 fallback.translate(classGen, methodGen);
 134             }
 135         }
 136         // We only go into the else block in forward-compatibility mode, when
 137         // the unsupported element has no fallback.
 138         else {
 139             // If the unsupported element does not have any fallback child, then
 140             // at runtime, a runtime error should be raised when the unsupported
 141             // element is instantiated. Otherwise, no error is thrown.
 142             ConstantPoolGen cpg = classGen.getConstantPool();
 143             InstructionList il = methodGen.getInstructionList();
 144 
 145             final int unsupportedElem = cpg.addMethodref(BASIS_LIBRARY_CLASS, "unsupported_ElementF",
 146                                                          "(" + STRING_SIG + "Z)V");
 147             il.append(new PUSH(cpg, getQName().toString()));
 148             il.append(new PUSH(cpg, _isExtension));
 149             il.append(new INVOKESTATIC(unsupportedElem));
 150         }
 151     }
 152 }