Package railo.runtime.util

Source Code of railo.runtime.util.URLResolver$Tag

package railo.runtime.util;

import java.net.MalformedURLException;
import java.net.URL;

import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import railo.commons.lang.StringUtil;
import railo.runtime.exp.PageException;
import railo.runtime.op.Caster;
import railo.runtime.text.xml.XMLUtil;
import railo.transformer.util.CFMLString;

/**
* Transform a HTML String, set all relative Pathes inside HTML File to absolute
* TODO Test this 
*
*/
public final class URLResolver {
 
  private Tag[] tags=new Tag[]{
      new Tag("a","href"),
      new Tag("link","href"),
      new Tag("form","action"),
      new Tag("applet","code"),
      new Tag("script","src"),
      new Tag("body","background"),
      new Tag("frame","src"),
      new Tag("bgsound","src"),
      new Tag("img","src"),
     
      new Tag("embed",new String[]{"src","pluginspace"}),
      new Tag("object",new String[]{"data","classid","codebase","usemap"})
     
  };
 

  public void transform(Node node, URL url) throws MalformedURLException {
    Element el;
    if(node.getNodeType()==Node.DOCUMENT_NODE) {
      transform(XMLUtil.getRootElement(node, true), url);
    }
    else if(node.getNodeType()==Node.ELEMENT_NODE) {
      el=(Element) node;
      String[] attr;
      NamedNodeMap map;
      String attrName,value,value2,nodeName=el.getNodeName();
      int len;
      // translate attribute
      for(int i=0;i<tags.length;i++) {
        if(tags[i].tag.equalsIgnoreCase(nodeName)) {
         
          attr=tags[i].attributes;
          map = el.getAttributes();
          len = map.getLength();
          for(int y=0;y<attr.length;y++) {
            for(int z=0;z<len;z++) {
              attrName=map.item(z).getNodeName();
              if(attrName.equalsIgnoreCase(attr[y])) {
                value=el.getAttribute(attrName);
                value2=add(url, value);
               
                if(value!=value2){
                  el.setAttribute(attrName, value2);
                }
               
                break;
              }
            }
          }
        }
      }
     
      // list children
      NodeList nodes = el.getChildNodes();
      len=nodes.getLength();
      for(int i=0;i<len;i++) {
        transform(nodes.item(i), url);
      }
    }
  }
 
  /**
   * transform the HTML String
   * @param html HTML String to transform
   * @param url Absolute URL path to set
   * @return transformed HTMl String
   * @throws PageException
   */
  public String transform(String html, URL url, boolean setBaseTag) throws PageException {
    StringBuffer target=new StringBuffer();
    CFMLString cfml=new CFMLString(html,"UTF-8");
    while(!cfml.isAfterLast()) {
      if(cfml.forwardIfCurrent('<')) {
        target.append('<');
        try {
          for(int i=0;i<tags.length;i++) {
            if(cfml.forwardIfCurrent(tags[i].tag+" ")) {
              target.append(tags[i].tag+" ");
              transformTag(target,cfml,tags[i],url);
            }
          }
        }
        catch(MalformedURLException me) {
          throw Caster.toPageException(me);
        }
      }
      else {
        target.append(cfml.getCurrent());
        cfml.next();
      }
     
    }
    if(!setBaseTag)return target.toString();
   
    html=target.toString();
    String prefix="",postfix="";
    int index = StringUtil.indexOfIgnoreCase(html, "</head>");
    if(index==-1) {
      prefix="<head>";
      postfix="</head>";
      index = StringUtil.indexOfIgnoreCase(html, "</html>");
    }
     
   
    if(index!=-1) {
      StringBuffer sb=new StringBuffer();
      sb.append(html.substring(0,index));
      String port=url.getPort()==-1?"":":"+url.getPort();
      sb.append(prefix+"<base href=\""+(url.getProtocol()+"://"+url.getHost()+port)+"\">"+postfix);
      sb.append(html.substring(index));
      html=sb.toString();
     
    }
    return html;
  }
 
  /**
   * transform a single tag
   * @param target target to write to
   * @param cfml CFMl String Object containing plain HTML
   * @param tag current tag totransform
   * @param url absolute URL to Set at tag attribute
   * @throws MalformedURLException
   */
  private void transformTag(StringBuffer target, CFMLString cfml, Tag tag,URL url) throws MalformedURLException {
    // TODO attribute inside other attribute
   
    char quote=0;
    boolean inside=false;
    StringBuffer value=new StringBuffer();
   
    while(!cfml.isAfterLast()) {
      if(inside) {
        if(quote!=0 && cfml.forwardIfCurrent(quote)) {
          inside=false;
          target.append(add(url,value.toString()));
          target.append(quote);
        }
        else if(quote==0 && (cfml.isCurrent(' ')||cfml.isCurrent("/>")||cfml.isCurrent('>')||cfml.isCurrent('\t')||cfml.isCurrent('\n'))) {
         
          inside=false;
          target.append(new URL(url,value.toString()));
          target.append(cfml.getCurrent());
          cfml.next();
        }
        else {
          value.append(cfml.getCurrent());
          cfml.next();
        }
      }
      else if(cfml.forwardIfCurrent('>')) {
        target.append('>');
        break;
      }
      else {
       
        for(int i=0;i<tag.attributes.length;i++) {
          if(cfml.forwardIfCurrent(tag.attributes[i])) {
            target.append(tag.attributes[i]);
            cfml.removeSpace();
            // =
            if(cfml.isCurrent('=')) {
              inside=true;
              target.append('=');
              cfml.next();
              cfml.removeSpace();
             
              quote=cfml.getCurrent();
              value=new StringBuffer();
              if(quote!='"' && quote!='\'')quote=0;
              else {
                target.append(quote);
                cfml.next();
              }
            }
          }
        }
        if(!inside) {
          target.append(cfml.getCurrent());
          cfml.next();
        }
      }
    }
  }


  private String add(URL url, String value) {
    value=value.trim();
    String lcValue=value.toLowerCase();
    if(lcValue.startsWith("http://") || lcValue.startsWith("file://") || lcValue.startsWith("news://") || lcValue.startsWith("goopher://") || lcValue.startsWith("javascript:"))
      return (value);
    try {
      return new URL(url,value.toString()).toExternalForm();
    } catch (MalformedURLException e) {
      return value;
    }
  }

  private class Tag {
    private String tag;
    private String[] attributes;
    private Tag(String tag,String[] attributes) {
      this.tag=tag.toLowerCase();
      this.attributes=new String[attributes.length];
      for(int i=0;i<attributes.length;i++) {
        this.attributes[i]=attributes[i].toLowerCase();
      }
     
    }
    private Tag(String tag,String attribute1) {
      this.tag=tag.toLowerCase();
      this.attributes=new String[]{attribute1.toLowerCase()};
    }
 
  }

  public static URLResolver getInstance() {
    return new URLResolver();
  }
 
}
TOP

Related Classes of railo.runtime.util.URLResolver$Tag

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.