Package railo.transformer.library.tag

Source Code of railo.transformer.library.tag.TagLibFactory

package railo.transformer.library.tag;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

import railo.commons.collection.MapFactory;
import railo.commons.io.IOUtil;
import railo.commons.io.SystemUtil;
import railo.commons.io.res.Resource;
import railo.commons.io.res.filter.ExtensionResourceFilter;
import railo.commons.io.res.util.ResourceUtil;
import railo.runtime.op.Caster;
import railo.runtime.text.xml.XMLUtil;
import railo.runtime.type.util.ArrayUtil;

/**
* Die Klasse TagLibFactory liest die XML Repraesentation einer TLD ein
* und laedt diese in eine Objektstruktur.
* Sie tut dieses mithilfe eines Sax Parser.
* Die Klasse kann sowohl einzelne Files oder gar ganze Verzeichnisse von TLD laden.
*/
public final class TagLibFactory extends DefaultHandler {
 
  /**
   * Standart Sax Parser
   */
  public final static String DEFAULT_SAX_PARSER="org.apache.xerces.parsers.SAXParser";
  /**
   * Field <code>TYPE_CFML</code>
   */
  public final static short TYPE_CFML=0;
  /**
   * Field <code>TYPE_JSP</code>
   */
  public final static short TYPE_JSP=1;
 
  //private short type=TYPE_CFML;
 
  private XMLReader xmlReader;
 
  private static Map<String,TagLib> hashLib=MapFactory.<String,TagLib>getConcurrentMap();
  private static TagLib systemTLD;
  private TagLib lib=new TagLib();
 
  private TagLibTag tag;
  private boolean insideTag=false;
  private boolean insideScript=false;
 
  private TagLibTagAttr att;
  private boolean insideAtt=false;

  private String inside;
  private StringBuffer content=new StringBuffer();
  private TagLibTagScript script;
  // System default tld
  private final static String TLD_1_0=  "/resource/tld/web-cfmtaglibrary_1_0";
   

  /**
   * Privater Konstruktor, der als Eingabe die TLD als File Objekt erhaelt.
   * @param saxParser String Klassenpfad zum Sax Parser.
   * @param file File Objekt auf die TLD.
   * @throws TagLibException
   * @throws IOException
   */
  private TagLibFactory(String saxParser,Resource res) throws TagLibException {
    Reader r=null;
    try {
      InputSource is=new InputSource(r=IOUtil.getReader(res.getInputStream(), (Charset)null));
      is.setSystemId(res.getPath());
      init(saxParser,is);
    } catch (IOException e) {
      throw new TagLibException(e);
    }
    finally {
      IOUtil.closeEL(r);
    }
  }

  /**
   * Privater Konstruktor, der als Eingabe die TLD als File Objekt erhaelt.
   * @param saxParser String Klassenpfad zum Sax Parser.
   * @param file File Objekt auf die TLD.
   * @throws TagLibException
   */
  private TagLibFactory(String saxParser,InputStream stream) throws TagLibException {
    try {
      InputSource is=new InputSource(IOUtil.getReader(stream, SystemUtil.getCharset()));
      //is.setSystemId(file.toString());
      init(saxParser,is);
    } catch (IOException e) {
      throw new TagLibException(e);
    }
  }
 
  /**
   * Privater Konstruktor nur mit Sax Parser Definition, liest Default TLD vom System ein.
   * @param saxParser String Klassenpfad zum Sax Parser.
   * @throws TagLibException
   */
  private TagLibFactory(String saxParser) throws TagLibException {
    InputSource is=new InputSource(this.getClass().getResourceAsStream(TLD_1_0) );
    init(saxParser,is);   
    lib.setIsCore(true);
  }
 
  /**
   * Generelle Initialisierungsmetode der Konstruktoren.
   * @param saxParser String Klassenpfad zum Sax Parser.
   * @param  is InputStream auf die TLD.
   * @throws TagLibException
   */
  private void init(String saxParser,InputSource is) throws TagLibException  {
    //print.dumpStack();
    try {
      xmlReader=XMLUtil.createXMLReader(saxParser);
      xmlReader.setContentHandler(this);
      xmlReader.setErrorHandler(this);
      xmlReader.setEntityResolver(new TagLibEntityResolver());
      xmlReader.parse(is);
    }
    catch (IOException e) {
     
      //String fileName=is.getSystemId();
      //String message="IOException: ";
      //if(fileName!=null) message+="In File ["+fileName+"], ";
      throw new TagLibException(e);
    }
    catch (SAXException e) {
      e.printStackTrace();
      //String fileName=is.getSystemId();
      //String message="SAXException: ";
      //if(fileName!=null) message+="In File ["+fileName+"], ";
      throw new TagLibException(e);
    }
   
    }

  /**
   * Geerbte Methode von org.xml.sax.ContentHandler,
   * wird bei durchparsen des XML, beim Auftreten eines Start-Tag aufgerufen.
   * 
   * @see org.xml.sax.ContentHandler#startElement(String, String, String, Attributes)
   */
  public void startElement(String uri, String name, String qName, Attributes atts) {

    inside=qName;
   
   
    if(qName.equals("tag")) startTag();
    else if(qName.equals("attribute")) startAtt();
    else if(qName.equals("script")) startScript();
   
  }
   
  /**
   * Geerbte Methode von org.xml.sax.ContentHandler,
   * wird bei durchparsen des XML, beim auftreten eines End-Tag aufgerufen.
   * 
   * @see org.xml.sax.ContentHandler#endElement(String, String, String)
   */
  public void endElement(String uri, String name, String qName) {
    setContent(content.toString().trim());
    content=new StringBuffer();
    inside="";
    /*
    if(tag!=null && tag.getName().equalsIgnoreCase("input")) {
      print.ln(tag.getName()+"-"+att.getName()+":"+inside+"-"+insideTag+"-"+insideAtt);
     
    }
    */
    if(qName.equals("tag")) endTag();
    else if(qName.equals("attribute")) endAtt();
    else if(qName.equals("script")) endScript();
  }
 
 
    /**
     * Geerbte Methode von org.xml.sax.ContentHandler,
   * wird bei durchparsen des XML, zum einlesen des Content eines Body Element aufgerufen.
   *
   * @see org.xml.sax.ContentHandler#characters(char[], int, int)
   */
  public void characters (char ch[], int start, int length)  {
    content.append(new String(ch,start,length));
  }
 
  private void setContent(String value)  {
      if(insideTag)  {
        // Att Args
        if(insideAtt)  {
          // description?
          // Name
          if(inside.equals("name")) att.setName(value);
          // Values
          if(inside.equals("values")) att.setValues(value);
          // Value Delimiter
          if(inside.equals("value-delimiter")) att.setValueDelimiter(value);
        // Required
        else if(inside.equals("required"))
          att.setRequired(Caster.toBooleanValue(value,false));
        // Rtexprvalue
        else if(inside.equals("rtexprvalue"))
          att.setRtexpr(Caster.toBooleanValue(value,false));
        // Type
        else if(inside.equals("type")) att.setType(value);
        // Default-Value
        else if(inside.equals("default-value")) att.setDefaultValue(value);
          // status
        else if(inside.equals("status")) att.setStatus(toStatus(value));
          // Description
        else if(inside.equals("description")) att.setDescription(value);
          // No-Name
        else if(inside.equals("noname")) att.setNoname(Caster.toBooleanValue(value,false));
        // default
        else if(inside.equals("default")) att.isDefault(Caster.toBooleanValue(value,false));
        else if(inside.equals("script-support")) att.setScriptSupport(value);
        }
        else if(insideScript)  {
          // type
          if(inside.equals("type")) script.setType(value);
          if(inside.equals("rtexprvalue")) script.setRtexpr(Caster.toBooleanValue(value,false));
          if(inside.equals("context")) script.setContext(value);
       
        }
        // Tag Args
        else  {
            // TODO TEI-class
          // Name
          if(inside.equals("name"))        {tag.setName(value);}
        // TAG - Class
          else if(inside.equals("tag-class"))  tag.setTagClass(value);
          else if(inside.equals("tagclass"))  tag.setTagClass(value);
          // status
        else if(inside.equals("status"))  tag.setStatus(toStatus(value));
          // TAG - description
        else if(inside.equals("description"))  tag.setDescription(value);
          // TTE - Class
        else if(inside.equals("tte-class"))  tag.setTteClass(value);
          // TTT - Class
        else if(inside.equals("ttt-class"))  tag.setTttClass(value);
        // TDBT - Class
        else if(inside.equals("tdbt-class"))  tag.setTdbtClass(value);
        // TDBT - Class
        else if(inside.equals("att-class"))  tag.setAttributeEvaluatorClassName(value);
        // Body Content
        else if(inside.equals("body-content") || inside.equals("bodycontent"))  {
                    tag.setBodyContent(value);
                }
          //allow-removing-literal
        else if(inside.equals("allow-removing-literal"))  {
                    tag.setAllowRemovingLiteral(Caster.toBooleanValue(value,false));
                }
        else if(inside.equals("att-default-value"))  tag.setAttributeDefaultValue(value);
       
         
         
                // Handle Exceptions
        else if(inside.equals("handle-exception"))  {
          tag.setHandleExceptions(Caster.toBooleanValue(value,false));
        }
        // Appendix
        else if(inside.equals("appendix"))  {
          tag.setAppendix(Caster.toBooleanValue(value,false));
        }
          // Body rtexprvalue
          else if(inside.equals("body-rtexprvalue")) {
            tag.setParseBody(Caster.toBooleanValue(value,false));
          }
          // Att - min
          else if(inside.equals("attribute-min")) 
            tag.setMin(Integer.parseInt(value));
          // Att - max
          else if(inside.equals("attribute-max")) 
            tag.setMax(Integer.parseInt(value));
          // Att Type
        else if(inside.equals("attribute-type"))  {
          int type=TagLibTag.ATTRIBUTE_TYPE_FIXED;
          if(value.toLowerCase().equals("fix"))type=TagLibTag.ATTRIBUTE_TYPE_FIXED;
          else if(value.toLowerCase().equals("fixed"))type=TagLibTag.ATTRIBUTE_TYPE_FIXED;
          else if(value.toLowerCase().equals("dynamic"))type=TagLibTag.ATTRIBUTE_TYPE_DYNAMIC;
          else if(value.toLowerCase().equals("noname"))type=TagLibTag.ATTRIBUTE_TYPE_NONAME;
          else if(value.toLowerCase().equals("mixed"))type=TagLibTag.ATTRIBUTE_TYPE_MIXED;
          else if(value.toLowerCase().equals("fulldynamic"))type=TagLibTag.ATTRIBUTE_TYPE_DYNAMIC;// deprecated
          tag.setAttributeType(type);
        }
        }
      }
      // Tag Lib
      else  {
          // TagLib Typ
          if(inside.equals("jspversion")) {
              //type=TYPE_JSP;
              lib.setType("jsp");
          }
          else if(inside.equals("cfml-version")) {
              //type=TYPE_CFML;
              lib.setType("cfml");
          }
         
         
        // EL Class
        else if(inside.equals("el-class")) lib.setELClass(value);
        // Name-Space
        else if(inside.equals("name-space")) lib.setNameSpace(value);
        // Name Space Sep
        else if(inside.equals("name-space-separator")) lib.setNameSpaceSeperator(value);
        // short-name
            else if(inside.equals("short-name")) lib.setShortName(value);
            else if(inside.equals("shortname")) lib.setShortName(value);
            // display-name
            else if(inside.equals("display-name")) lib.setDisplayName(value);
            else if(inside.equals("displayname")) lib.setDisplayName(value);
          // ignore-unknow-tags
            else if(inside.equals("ignore-unknow-tags")) lib.setIgnoreUnknowTags(Caster.toBooleanValue(value,false));
           
         
            else if(inside.equals("uri")) {
        try {
          lib.setUri(value);
        } catch (URISyntaxException e) {}
      }
      else if(inside.equals("description")) lib.setDescription(value);   
   
      }
    } 
 

  /**
   * Wird jedesmal wenn das Tag tag beginnt aufgerufen, um intern in einen anderen Zustand zu gelangen.
   */
  private void startTag()  {
      tag=new TagLibTag(lib);
      insideTag=true;
    }
 
  /**
   * Wird jedesmal wenn das Tag tag endet aufgerufen, um intern in einen anderen Zustand zu gelangen.
   */
  private void endTag()  {
    lib.setTag(tag);
      insideTag=false;
    }
 
  private void startScript()  {
      script=new TagLibTagScript(tag);
      insideScript=true;
    }
 
  /**
   * Wird jedesmal wenn das Tag tag endet aufgerufen, um intern in einen anderen Zustand zu gelangen.
   */
  private void endScript()  {
    tag.setScript(script);
      insideScript=false;
    }
 
 
 
  /**
   * Wird jedesmal wenn das Tag attribute beginnt aufgerufen, um intern in einen anderen Zustand zu gelangen.
   */
  private void startAtt()  {
      att=new TagLibTagAttr(tag);
      insideAtt=true;
    }
 
 
  /**
   * Wird jedesmal wenn das Tag tag endet aufgerufen, um intern in einen anderen Zustand zu gelangen.
   */
  private void endAtt()  {
      tag.setAttribute(att);
      insideAtt=false;
    }

  /**
   * Gibt die interne TagLib zurueck.
   * @return Interne Repraesentation der zu erstellenden TagLib.
   */
  private TagLib getLib() {
    return lib;
  }
 
  /**
   * TagLib werden innerhalb der Factory in einer HashMap gecacht,
   * so das diese einmalig von der Factory geladen werden.
   * Diese Methode gibt eine gecachte TagLib anhand dessen key zurueck,
   * falls diese noch nicht im Cache existiert, gibt die Methode null zurueck.
   *
   * @param key Absoluter Filepfad zur TLD.
   * @return TagLib
   */
  private static TagLib getHashLib(String key) {
    return hashLib.get(key);
  }
 
  /**
   * Laedt mehrere TagLib's die innerhalb eines Verzeichnisses liegen.
   * @param dir Verzeichnis im dem die TagLib's liegen.
   * @return TagLib's als Array
   * @throws TagLibException
   */
  public static TagLib[] loadFromDirectory(Resource dir) throws TagLibException  {
    return loadFromDirectory(dir,DEFAULT_SAX_PARSER);
  }
 
  /**
   * Laedt mehrere TagLib's die innerhalb eines Verzeichnisses liegen.
   * @param dir Verzeichnis im dem die TagLib's liegen.
   * @param saxParser Definition des Sax Parser mit dem die TagLib's eingelesen werden sollen.
   * @return TagLib's als Array
   * @throws TagLibException
   */
  public static TagLib[] loadFromDirectory(Resource dir,String saxParser) throws TagLibException  {
    if(!dir.isDirectory())return new TagLib[0];
    ArrayList<TagLib> arr=new ArrayList<TagLib>();
   
    Resource[] files=dir.listResources(new ExtensionResourceFilter("tld"));
    for(int i=0;i<files.length;i++)  {
      if(files[i].isFile())
        arr.add(TagLibFactory.loadFromFile(files[i],saxParser));
       
    }
    return arr.toArray(new TagLib[arr.size()]);
  }

  /**
   * Laedt eine einzelne TagLib.
   * @param file TLD die geladen werden soll.
   * @return TagLib
   * @throws TagLibException
   */
  public static TagLib loadFromFile(Resource res) throws TagLibException  {
    return loadFromFile(res,DEFAULT_SAX_PARSER);
  }

  /**
   * Laedt eine einzelne TagLib.
   * @param file TLD die geladen werden soll.
   * @return TagLib
   * @throws TagLibException
   */
  public static TagLib loadFromStream(InputStream is) throws TagLibException  {
    return loadFromStream(is,DEFAULT_SAX_PARSER);
  }

  /**
   * Laedt eine einzelne TagLib.
   * @param file TLD die geladen werden soll.
   * @param saxParser Definition des Sax Parser mit dem die TagLib eingelsesen werden soll.
   * @return TagLib
   * @throws TagLibException
   */
  public static TagLib loadFromFile(Resource res,String saxParser) throws TagLibException  {
       
    // Read in XML
      TagLib lib=TagLibFactory.getHashLib(ResourceUtil.getCanonicalPathEL(res));
    if(lib==null)  {
        lib=new TagLibFactory(saxParser,res).getLib();
      TagLibFactory.hashLib.put(ResourceUtil.getCanonicalPathEL(res),lib);
    }
    lib.setSource(res.toString());
    return lib;
  }
  /**
   * Laedt eine einzelne TagLib.
   * @param file TLD die geladen werden soll.
   * @param saxParser Definition des Sax Parser mit dem die TagLib eingelsesen werden soll.
   * @return TagLib
   * @throws TagLibException
   */
  public static TagLib loadFromStream(InputStream is,String saxParser) throws TagLibException  {
        return new TagLibFactory(saxParser,is).getLib();
  }
 
  /**
   * Laedt die Systeminterne TLD.
   * @return FunctionLib
   * @throws TagLibException
   */
  public static TagLib loadFromSystem() throws TagLibException  {
    return loadFromSystem(DEFAULT_SAX_PARSER);
  }
 
  /**
   * Laedt die Systeminterne TLD.
   * @param saxParser Definition des Sax Parser mit dem die FunctionLib eingelsesen werden soll.
   * @return FunctionLib
   * @throws TagLibException
   */
  public static TagLib loadFromSystem(String saxParser) throws TagLibException  {
    if(systemTLD==null)
      systemTLD=new TagLibFactory(saxParser).getLib();
    return systemTLD;
  }

  public static TagLib[] loadFrom(Resource res) throws TagLibException {
    if(res.isDirectory())return loadFromDirectory(res);
    if(res.isFile()) return new TagLib[]{loadFromFile(res)};
    throw new TagLibException("can not load tag library descriptor from ["+res+"]");
  }

 
  /**
   * return one FunctionLib contain content of all given Function Libs
   * @param tlds
   * @return combined function lib
   */
  public static TagLib combineTLDs(TagLib[] tlds){
    TagLib tl = new TagLib();
    if(ArrayUtil.isEmpty(tlds)) return tl;

    setAttributes(tlds[0],tl);
   
    // add functions
    for(int i=0;i<tlds.length;i++){
      copyTags(tlds[i],tl);
    }
    return tl;
  }
 
  public static TagLib combineTLDs(Set tlds){
    TagLib newTL = new TagLib(),tmp;
    if(tlds.size()==0) return newTL ;

    Iterator it = tlds.iterator();
    int count=0;
    while(it.hasNext()){
      tmp=(TagLib) it.next();
      if(count++==0) setAttributes(tmp,newTL);
      copyTags(tmp,newTL);
    }
    return newTL;
  }
 
  private static void setAttributes(TagLib extTL, TagLib newTL) {
    newTL.setDescription(extTL.getDescription());
    newTL.setDisplayName(extTL.getDisplayName());
    newTL.setELClass(extTL.getELClass());
    newTL.setIsCore(extTL.isCore());
    newTL.setNameSpace(extTL.getNameSpace());
    newTL.setNameSpaceSeperator(extTL.getNameSpaceSeparator());
    newTL.setShortName(extTL.getShortName());
    newTL.setSource(extTL.getSource());
    newTL.setType(extTL.getType());
    newTL.setUri(extTL.getUri());
   
  }
 
  private static void copyTags(TagLib extTL, TagLib newTL) {
    Iterator it = extTL.getTags().entrySet().iterator();
    TagLibTag tlt;
    while(it.hasNext()){
      tlt= (TagLibTag) ((Map.Entry)it.next()).getValue(); // TODO function must be duplicated because it gets a new FunctionLib assigned
      newTL.setTag(tlt);
    }
  }
 

  public static short toStatus(String value) {
    value=value.trim().toLowerCase();
    if("deprecated".equals(value)) return TagLib.STATUS_DEPRECATED;
    if("dep".equals(value)) return TagLib.STATUS_DEPRECATED;
   
    if("unimplemented".equals(value)) return TagLib.STATUS_UNIMPLEMENTED;
    if("unimplemeted".equals(value)) return TagLib.STATUS_UNIMPLEMENTED;
    if("notimplemented".equals(value)) return TagLib.STATUS_UNIMPLEMENTED;
    if("not-implemented".equals(value)) return TagLib.STATUS_UNIMPLEMENTED;
    if("hidden".equals(value)) return TagLib.STATUS_HIDDEN;
   
    return TagLib.STATUS_IMPLEMENTED;
  }
  public static String toStatus(short value) {
    switch(value){
    case TagLib.STATUS_DEPRECATED: return "deprecated";
    case TagLib.STATUS_UNIMPLEMENTED: return "unimplemeted";
    case TagLib.STATUS_HIDDEN: return "hidden";
    }
    return "implemeted";
  }
 
}







TOP

Related Classes of railo.transformer.library.tag.TagLibFactory

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.