Package org.ajax4jsf.io.parser

Source Code of org.ajax4jsf.io.parser.FastHtmlParser

/**
* License Agreement.
*
* Rich Faces - Natural Ajax for Java Server Faces (JSF)
*
* Copyright (C) 2007 Exadel, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
*/

package org.ajax4jsf.io.parser;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Field;
import java.util.LinkedList;
import java.util.Map;

import org.ajax4jsf.context.SAXEndElementEvent;
import org.ajax4jsf.context.SAXStartElementEvent;
import org.ajax4jsf.context.SAXTextEvent;
import org.ajax4jsf.io.FastBufferReader;
import org.ajax4jsf.webapp.HtmlParser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* Simplified and fast HTML parsed - for find insertion point of <html><head>
* there can be inserted <script><style> and <meta> tags.
*
* @author shura
*
*/
public class FastHtmlParser implements HtmlParser {

  private static final Log log = LogFactory.getLog(FastHtmlParser.class);

  private String encoding;

  private String doctype;

  private String viewState;

  private String mimeType;

  private Object[] headEvents;

  public void parse(Reader in, Writer out) throws IOException {
    boolean haveHtml = false;
    boolean haveHead = false;
    boolean closingElement = false;
//see if any characters has been written http://jira.jboss.com/jira/browse/RF-3685
    boolean parsed = false;
// Always parse content, see http://jira.jboss.com/jira/browse/RF-3577
//    if (null != scripts || null != styles || null != userStyles) {
      ParsingStateManager stateManager = ParsingStateManager
          .getInstance();
      ParserState state = stateManager.getInitialState();
      ParsingContext context = new ParsingContext(out);
      int nextChar;
      while ((nextChar = in.read()) > 0) {
        parsed = true;
        char c = (char)nextChar;
        state = state.getNextState(c, context);
        if (log.isDebugEnabled()) {
          // Find state name.
          Class<? extends ParsingStateManager> stateMgrClass = stateManager.getClass();
          Field[] fields = stateMgrClass.getDeclaredFields();
          for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            try {
              if (field.get(stateManager) == state) {
                log
                    .debug("Parser reached state is StateManager."
                        + field.getName());
                break;
              }
            } catch (Exception e) {
              // ignore ...
            }
          }
        }
        state.send(c, context);
        if (state == stateManager.LT) {
          closingElement = false;
        } else if (state == stateManager.CLOSINGELEMENT) {
          closingElement = true;
        } else if (state == stateManager.ENDELEMENT) {
          if (context.getLastMatched() == stateManager.HTML) {
            haveHtml = true;
            //if xmlns is not set on HTML element, append xmlns attribute
            if (!context.contains("xmlns=")) {
              context.insert(" xmlns=\"http://www.w3.org/1999/xhtml\"");
            }
           
            context.send();
            if (log.isDebugEnabled()) {
              log.debug("Found <html> element");
            }
          } else if (context.getLastMatched() == stateManager.HEAD) {
            haveHead = true;
            if (log.isDebugEnabled()) {
              log.debug("Found <head> element");
            }
            if (closingElement) {
              writeToHead(out, haveHtml, haveHead);
              break;
            } else {
              context.send();             
            }
          } else if (context.getLastMatched() == stateManager.TITLE) {
            context.send();
            haveHead = true;
            haveHtml = true;
            if (log.isDebugEnabled()) {
              log.debug("Found <title> element");
            }
          } else if (context.getLastMatched() == stateManager.BASE) {
            context.send();
            haveHead = true;
            haveHtml = true;
            if (log.isDebugEnabled()) {
              log.debug("Found <base> element");
            }
          } else {
            if (log.isDebugEnabled()) {
              log
                  .debug("non <html> or <head><title>|<base> element");
            }
            writeToHead(out, haveHtml, haveHead);
            break;
          }
        } else if (state == stateManager.ELEMENT) {
          writeToHead(out, haveHtml, haveHead);
          break;
        }
      }
      context.send();
//    } else {
//      haveHtml = true;
//    }
    // Send rest of input.
    if (in instanceof FastBufferReader) {
      FastBufferReader fastIn = (FastBufferReader) in;
      fastIn.writeTo(out);

    } else {
      char[] buffer = new char[1024];
      int buffersCount = -1;
      int length;
      for (length = in.read(buffer); length > 0; length = in.read(buffer)) {
        out.write(buffer, 0, length);
        buffersCount++;
      }
    }
    if (!haveHtml && parsed) {
      out.write("</html>");
    }

  }

  private void writeToHead(Writer out, boolean haveHtml, boolean haveHead)
      throws IOException {
    if (!haveHead && !haveHtml) {
      out.write("<html  xmlns=\"http://www.w3.org/1999/xhtml\">");
    }
    if (!haveHead) {
      out.write("<head>");
    }
   
    if (headEvents != null && headEvents.length > 0) {
      LinkedList<Boolean> closedStack = new LinkedList<Boolean>();
     
      for (Object event : headEvents) {
        if (event instanceof SAXStartElementEvent) {
          SAXStartElementEvent startElementEvent = (SAXStartElementEvent) event;

          if (!closedStack.isEmpty() && Boolean.FALSE.equals(closedStack.peek())) {
            out.write('>');
            closedStack.set(0, Boolean.TRUE);
          }

          out.write('<');
          out.write(startElementEvent.getName());
         
          for (Map.Entry<String, String> entry : startElementEvent.getAttributes().entrySet()) {
            String name = entry.getKey();
            String value = entry.getValue();
            out.write(' ');
            out.write(name);
            out.write("='");
            out.write(value);
            out.write('\'');
          }

          closedStack.addFirst(Boolean.FALSE);
        } else if (event instanceof SAXTextEvent) {
          SAXTextEvent textEvent = (SAXTextEvent) event;

          if (!closedStack.isEmpty() && Boolean.FALSE.equals(closedStack.peek())) {
            out.write('>');
            closedStack.set(0, Boolean.TRUE);
          }
         
          out.write(textEvent.getText());

        } else if (event instanceof SAXEndElementEvent) {
          SAXEndElementEvent endElementEvent = (SAXEndElementEvent) event;
          String elementName = endElementEvent.getName();
         
          if (Boolean.FALSE.equals(closedStack.removeFirst())) {
            if ("script".equals(elementName)) {
              out.write('>');
              out.write("</");
              out.write(elementName);
              out.write('>');
            } else {
              out.write(" />");
            }
          } else {
            out.write("</");
            out.write(elementName);
            out.write('>');
          }
        } else {
          throw new IllegalArgumentException();
        }
      }
    }
   
    if (!haveHead) {
      out.write("</head>");
    }

  }

  public void parseHtml(InputStream input, Writer output) throws IOException {
    parse(new InputStreamReader(input, encoding), output);

  }

  public void parseHtml(Reader input, Writer output) throws IOException {
    parse(input, output);

  }

  public void setInputEncoding(String encoding) {
    this.encoding = encoding;

  }

  public void setOutputEncoding(String encoding) {
    // TODO Auto-generated method stub

  }

  public void setMoveElements(boolean move) {
  }

  public void setDoctype(String doctype) {
    this.doctype = doctype;

  }

  public void setViewState(String viewState) {
    this.viewState = viewState;

  }

  public boolean setMime(String mimeType) {
      this.mimeType=mimeType;
      return true;
  }

  public void setHeadEvents(Object[] events) {
    this.headEvents = events;
  }
}
TOP

Related Classes of org.ajax4jsf.io.parser.FastHtmlParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.