1 /*
   2  * Copyright (c) 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 package com.sun.org.apache.xalan.internal.xsltc.runtime.output;
  22 
  23 import java.io.IOException;
  24 import java.io.OutputStream;
  25 import java.io.Writer;
  26 
  27 import javax.xml.parsers.ParserConfigurationException;
  28 import javax.xml.stream.XMLEventWriter;
  29 import javax.xml.stream.util.XMLEventConsumer;
  30 import javax.xml.stream.XMLStreamWriter;
  31 
  32 import com.sun.org.apache.xalan.internal.xsltc.trax.SAX2DOM;
  33 import com.sun.org.apache.xalan.internal.xsltc.trax.SAX2StAXEventWriter;
  34 import com.sun.org.apache.xalan.internal.xsltc.trax.SAX2StAXStreamWriter;
  35 
  36 import com.sun.org.apache.xml.internal.serializer.ToHTMLSAXHandler;
  37 import com.sun.org.apache.xml.internal.serializer.ToHTMLStream;
  38 import com.sun.org.apache.xml.internal.serializer.ToTextSAXHandler;
  39 import com.sun.org.apache.xml.internal.serializer.ToTextStream;
  40 import com.sun.org.apache.xml.internal.serializer.ToUnknownStream;
  41 import com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler;
  42 import com.sun.org.apache.xml.internal.serializer.ToXMLStream;
  43 import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
  44 import org.w3c.dom.Node;
  45 
  46 import org.xml.sax.ContentHandler;
  47 import org.xml.sax.ext.LexicalHandler;
  48 
  49 /**
  50  * @author Santiago Pericas-Geertsen
  51  * @LastModified: Oct 2017
  52  */
  53 public class TransletOutputHandlerFactory {
  54 
  55     public static final int STREAM = 0;
  56     public static final int SAX    = 1;
  57     public static final int DOM    = 2;
  58     public static final int STAX   = 3;
  59 
  60     private String _encoding                        = "utf-8";
  61     private String _method                          = null;
  62     private int    _outputType                      = STREAM;
  63     private OutputStream _ostream                   = System.out;
  64     private Writer _writer                          = null;
  65     private Node _node                              = null;
  66     private Node   _nextSibling                     = null;
  67     private XMLEventWriter _xmlStAXEventWriter      = null;
  68     private XMLStreamWriter _xmlStAXStreamWriter    = null;
  69     private int _indentNumber                       = -1;
  70     private ContentHandler _handler                 = null;
  71     private LexicalHandler _lexHandler              = null;
  72 
  73     private boolean _useServicesMechanism;
  74 
  75     static public TransletOutputHandlerFactory newInstance() {
  76         return new TransletOutputHandlerFactory(true);
  77     }
  78     static public TransletOutputHandlerFactory newInstance(boolean useServicesMechanism) {
  79         return new TransletOutputHandlerFactory(useServicesMechanism);
  80     }
  81 
  82     public TransletOutputHandlerFactory(boolean useServicesMechanism) {
  83         _useServicesMechanism = useServicesMechanism;
  84     }
  85     public void setOutputType(int outputType) {
  86         _outputType = outputType;
  87     }
  88 
  89     public void setEncoding(String encoding) {
  90         if (encoding != null) {
  91             _encoding = encoding;
  92         }
  93     }
  94 
  95     public void setOutputMethod(String method) {
  96         _method = method;
  97     }
  98 
  99     public void setOutputStream(OutputStream ostream) {
 100         _ostream = ostream;
 101     }
 102 
 103     public void setWriter(Writer writer) {
 104         _writer = writer;
 105     }
 106 
 107     public void setHandler(ContentHandler handler) {
 108         _handler = handler;
 109     }
 110 
 111     public void setLexicalHandler(LexicalHandler lex) {
 112         _lexHandler = lex;
 113     }
 114 
 115     public void setNode(Node node) {
 116         _node = node;
 117     }
 118 
 119     public Node getNode() {
 120         return (_handler instanceof SAX2DOM) ? ((SAX2DOM)_handler).getDOM()
 121            : null;
 122     }
 123 
 124     public void setNextSibling(Node nextSibling) {
 125         _nextSibling = nextSibling;
 126     }
 127 
 128     public XMLEventWriter getXMLEventWriter() {
 129         return (_handler instanceof SAX2StAXEventWriter) ? ((SAX2StAXEventWriter) _handler).getEventWriter() : null;
 130     }
 131 
 132     public void setXMLEventWriter(XMLEventWriter eventWriter) {
 133         _xmlStAXEventWriter = eventWriter;
 134     }
 135 
 136     public XMLStreamWriter getXMLStreamWriter() {
 137         return (_handler instanceof SAX2StAXStreamWriter) ? ((SAX2StAXStreamWriter) _handler).getStreamWriter() : null;
 138     }
 139 
 140     public void setXMLStreamWriter(XMLStreamWriter streamWriter) {
 141         _xmlStAXStreamWriter = streamWriter;
 142     }
 143 
 144     public void setIndentNumber(int value) {
 145         _indentNumber = value;
 146     }
 147 
 148     @SuppressWarnings("fallthrough")  // intentional at case STAX, SAX
 149     public SerializationHandler getSerializationHandler()
 150         throws IOException, ParserConfigurationException
 151     {
 152         SerializationHandler result = null;
 153         switch (_outputType)
 154         {
 155             case STREAM :
 156 
 157                 if (_method == null)
 158                 {
 159                     result = new ToUnknownStream();
 160                 }
 161                 else if (_method.equalsIgnoreCase("xml"))
 162                 {
 163 
 164                     result = new ToXMLStream();
 165 
 166                 }
 167                 else if (_method.equalsIgnoreCase("html"))
 168                 {
 169 
 170                     result = new ToHTMLStream();
 171 
 172                 }
 173                 else if (_method.equalsIgnoreCase("text"))
 174                 {
 175 
 176                     result = new ToTextStream();
 177 
 178                 }
 179 
 180                 if (result != null && _indentNumber >= 0)
 181                 {
 182                     result.setIndentAmount(_indentNumber);
 183                 }
 184 
 185                 result.setEncoding(_encoding);
 186 
 187                 if (_writer != null)
 188                 {
 189                     result.setWriter(_writer);
 190                 }
 191                 else
 192                 {
 193                     result.setOutputStream(_ostream);
 194                 }
 195                 return result;
 196 
 197             case DOM :
 198                 _handler = (_node != null) ? new SAX2DOM(_node, _nextSibling, _useServicesMechanism) : new SAX2DOM(_useServicesMechanism);
 199                 _lexHandler = (LexicalHandler) _handler;
 200                 // falls through
 201             case STAX :
 202                 if (_xmlStAXEventWriter != null) {
 203                     _handler =  new SAX2StAXEventWriter(_xmlStAXEventWriter);
 204                 } else if (_xmlStAXStreamWriter != null) {
 205                     _handler =  new SAX2StAXStreamWriter(_xmlStAXStreamWriter);
 206                 }
 207                 _lexHandler = (LexicalHandler) _handler;
 208                 // again falls through - Padmaja Vedula
 209             case SAX :
 210                 if (_method == null)
 211                 {
 212                     _method = "xml"; // default case
 213                 }
 214 
 215                 if (_method.equalsIgnoreCase("xml"))
 216                 {
 217 
 218                     if (_lexHandler == null)
 219                     {
 220                         result = new ToXMLSAXHandler(_handler, _encoding);
 221                     }
 222                     else
 223                     {
 224                         result =
 225                             new ToXMLSAXHandler(
 226                                 _handler,
 227                                 _lexHandler,
 228                                 _encoding);
 229                     }
 230 
 231                 }
 232                 else if (_method.equalsIgnoreCase("html"))
 233                 {
 234 
 235                     if (_lexHandler == null)
 236                     {
 237                         result = new ToHTMLSAXHandler(_handler, _encoding);
 238                     }
 239                     else
 240                     {
 241                         result =
 242                             new ToHTMLSAXHandler(
 243                                 _handler,
 244                                 _lexHandler,
 245                                 _encoding);
 246                     }
 247 
 248                 }
 249                 else if (_method.equalsIgnoreCase("text"))
 250                 {
 251 
 252                     if (_lexHandler == null)
 253                     {
 254                         result = new ToTextSAXHandler(_handler, _encoding);
 255                     }
 256                     else
 257                     {
 258                         result =
 259                             new ToTextSAXHandler(
 260                                 _handler,
 261                                 _lexHandler,
 262                                 _encoding);
 263                     }
 264 
 265                 }
 266                 return result;
 267         }
 268         return null;
 269     }
 270 
 271 }