You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sl...@apache.org on 2009/04/04 20:45:04 UTC

svn commit: r761982 [3/10] - in /myfaces/core/branches/2_0_0/impl/src: main/java/com/ main/java/org/apache/myfaces/application/ main/java/org/apache/myfaces/config/ main/java/org/apache/myfaces/config/impl/digester/ main/java/org/apache/myfaces/config/...

Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CompilationManager.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CompilationManager.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CompilationManager.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CompilationManager.java Sat Apr  4 18:44:59 2009
@@ -0,0 +1,460 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.compiler;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.faces.view.facelets.FaceletHandler;
+import javax.faces.view.facelets.Tag;
+import javax.faces.view.facelets.TagAttribute;
+import javax.faces.view.facelets.TagAttributeException;
+import javax.faces.view.facelets.TagException;
+
+import org.apache.myfaces.view.facelets.tag.TagAttributesImpl;
+import org.apache.myfaces.view.facelets.tag.TagDecorator;
+import org.apache.myfaces.view.facelets.tag.TagLibrary;
+import org.apache.myfaces.view.facelets.tag.ui.ComponentRefHandler;
+import org.apache.myfaces.view.facelets.tag.ui.CompositionHandler;
+import org.apache.myfaces.view.facelets.tag.ui.UILibrary;
+
+/**
+ * Compilation unit for managing the creation of a single FaceletHandler based on events from an XML parser.
+ * 
+ * @see org.apache.myfaces.view.facelets.compiler.Compiler
+ * 
+ * @author Jacob Hookom
+ * @version $Id: CompilationManager.java,v 1.15 2008/07/13 19:01:34 rlubke Exp $
+ */
+final class CompilationManager
+{
+
+    private final static Logger log = Logger.getLogger("facelets.compiler");
+
+    private final Compiler compiler;
+
+    private final TagLibrary tagLibrary;
+
+    private final TagDecorator tagDecorator;
+
+    private final NamespaceManager namespaceManager;
+
+    private final Stack<CompilationUnit> units;
+
+    private int tagId;
+
+    private boolean finished;
+
+    private final String alias;
+
+    public CompilationManager(String alias, Compiler compiler)
+    {
+
+        // this is our alias
+        this.alias = alias;
+
+        // grab compiler state
+        this.compiler = compiler;
+        this.tagDecorator = compiler.createTagDecorator();
+        this.tagLibrary = compiler.createTagLibrary();
+
+        // namespace management
+        this.namespaceManager = new NamespaceManager();
+
+        // tag uids
+        this.tagId = 0;
+
+        // for composition use
+        this.finished = false;
+
+        // our compilationunit stack
+        this.units = new Stack<CompilationUnit>();
+        this.units.push(new CompilationUnit());
+    }
+
+    public void writeInstruction(String value)
+    {
+        if (this.finished)
+        {
+            return;
+        }
+
+        // don't carelessly add empty tags
+        if (value.length() == 0)
+        {
+            return;
+        }
+
+        TextUnit unit;
+        if (this.currentUnit() instanceof TextUnit)
+        {
+            unit = (TextUnit) this.currentUnit();
+        }
+        else
+        {
+            unit = new TextUnit(this.alias, this.nextTagId());
+            this.startUnit(unit);
+        }
+        unit.writeInstruction(value);
+    }
+
+    public void writeText(String value)
+    {
+
+        if (this.finished)
+        {
+            return;
+        }
+
+        // don't carelessly add empty tags
+        if (value.length() == 0)
+        {
+            return;
+        }
+
+        TextUnit unit;
+        if (this.currentUnit() instanceof TextUnit)
+        {
+            unit = (TextUnit) this.currentUnit();
+        }
+        else
+        {
+            unit = new TextUnit(this.alias, this.nextTagId());
+            this.startUnit(unit);
+        }
+        unit.write(value);
+    }
+
+    public void writeComment(String text)
+    {
+        if (this.compiler.isTrimmingComments())
+            return;
+
+        if (this.finished)
+        {
+            return;
+        }
+
+        // don't carelessly add empty tags
+        if (text.length() == 0)
+        {
+            return;
+        }
+
+        TextUnit unit;
+        if (this.currentUnit() instanceof TextUnit)
+        {
+            unit = (TextUnit) this.currentUnit();
+        }
+        else
+        {
+            unit = new TextUnit(this.alias, this.nextTagId());
+            this.startUnit(unit);
+        }
+
+        unit.writeComment(text);
+    }
+
+    public void writeWhitespace(String text)
+    {
+        if (!this.compiler.isTrimmingWhitespace())
+        {
+            this.writeText(text);
+        }
+    }
+
+    private String nextTagId()
+    {
+        return Integer.toHexString(Math.abs(this.alias.hashCode() ^ 13 * this.tagId++));
+    }
+
+    public void pushTag(Tag orig)
+    {
+
+        if (this.finished)
+        {
+            return;
+        }
+
+        if (log.isLoggable(Level.FINE))
+        {
+            log.fine("Tag Pushed: " + orig);
+        }
+
+        Tag t = this.tagDecorator.decorate(orig);
+        String[] qname = this.determineQName(t);
+        t = this.trimAttributes(t);
+
+        if (isTrimmed(qname[0], qname[1]))
+        {
+            log.fine("Composition Found, Popping Parent Tags");
+            this.units.clear();
+            NamespaceUnit nsUnit = this.namespaceManager.toNamespaceUnit(this.tagLibrary);
+            this.units.push(nsUnit);
+            this.startUnit(new TrimmedTagUnit(this.tagLibrary, qname[0], qname[1], t, this.nextTagId()));
+            log.fine("New Namespace and [Trimmed] TagUnit pushed");
+        }
+        else if (isRemove(qname[0], qname[1]))
+        {
+            this.units.push(new RemoveUnit());
+        }
+        else if (this.tagLibrary.containsTagHandler(qname[0], qname[1]))
+        {
+            this.startUnit(new TagUnit(this.tagLibrary, qname[0], qname[1], t, this.nextTagId()));
+        }
+        else if (this.tagLibrary.containsNamespace(qname[0]))
+        {
+            throw new TagException(orig, "Tag Library supports namespace: " + qname[0]
+                    + ", but no tag was defined for name: " + qname[1]);
+        }
+        else
+        {
+            TextUnit unit;
+            if (this.currentUnit() instanceof TextUnit)
+            {
+                unit = (TextUnit) this.currentUnit();
+            }
+            else
+            {
+                unit = new TextUnit(this.alias, this.nextTagId());
+                this.startUnit(unit);
+            }
+            unit.startTag(t);
+        }
+    }
+
+    public void popTag()
+    {
+
+        if (this.finished)
+        {
+            return;
+        }
+
+        CompilationUnit unit = this.currentUnit();
+
+        if (unit instanceof TextUnit)
+        {
+            TextUnit t = (TextUnit) unit;
+            if (t.isClosed())
+            {
+                this.finishUnit();
+            }
+            else
+            {
+                t.endTag();
+                return;
+            }
+        }
+
+        unit = this.currentUnit();
+        if (unit instanceof TagUnit)
+        {
+            TagUnit t = (TagUnit) unit;
+            if (t instanceof TrimmedTagUnit)
+            {
+                this.finished = true;
+                return;
+            }
+        }
+
+        this.finishUnit();
+    }
+
+    public void popNamespace(String ns)
+    {
+        this.namespaceManager.popNamespace(ns);
+        if (this.currentUnit() instanceof NamespaceUnit)
+        {
+            this.finishUnit();
+        }
+    }
+
+    public void pushNamespace(String prefix, String uri)
+    {
+
+        if (log.isLoggable(Level.FINE))
+        {
+            log.fine("Namespace Pushed " + prefix + ": " + uri);
+        }
+
+        this.namespaceManager.pushNamespace(prefix, uri);
+        NamespaceUnit unit;
+        if (this.currentUnit() instanceof NamespaceUnit)
+        {
+            unit = (NamespaceUnit) this.currentUnit();
+        }
+        else
+        {
+            unit = new NamespaceUnit(this.tagLibrary);
+            this.startUnit(unit);
+        }
+        unit.setNamespace(prefix, uri);
+    }
+
+    public FaceletHandler createFaceletHandler()
+    {
+        return ((CompilationUnit) this.units.get(0)).createFaceletHandler();
+    }
+
+    private CompilationUnit currentUnit()
+    {
+        if (!this.units.isEmpty())
+        {
+            return (CompilationUnit) this.units.peek();
+        }
+        return null;
+    }
+
+    private void finishUnit()
+    {
+        Object obj = this.units.pop();
+
+        if (log.isLoggable(Level.FINE))
+        {
+            log.fine("Finished Unit: " + obj);
+        }
+    }
+
+    private void startUnit(CompilationUnit unit)
+    {
+
+        if (log.isLoggable(Level.FINE))
+        {
+            log.fine("Starting Unit: " + unit + " and adding it to parent: " + this.currentUnit());
+        }
+
+        this.currentUnit().addChild(unit);
+        this.units.push(unit);
+    }
+
+    private Tag trimAttributes(Tag tag)
+    {
+        Tag t = this.trimJSFCAttribute(tag);
+        t = this.trimNSAttributes(t);
+        return t;
+    }
+
+    protected static boolean isRemove(String ns, String name)
+    {
+        return UILibrary.Namespace.equals(ns) && "remove".equals(name);
+    }
+
+    protected static boolean isTrimmed(String ns, String name)
+    {
+        return UILibrary.Namespace.equals(ns)
+                && (CompositionHandler.Name.equals(name) || ComponentRefHandler.Name.equals(name));
+    }
+
+    private String[] determineQName(Tag tag)
+    {
+        TagAttribute attr = tag.getAttributes().get("jsfc");
+        if (attr != null)
+        {
+            if (log.isLoggable(Level.FINE))
+            {
+                log.fine(attr + " JSF Facelet Compile Directive Found");
+            }
+            String value = attr.getValue();
+            String namespace, localName;
+            int c = value.indexOf(':');
+            if (c == -1)
+            {
+                namespace = this.namespaceManager.getNamespace("");
+                localName = value;
+            }
+            else
+            {
+                String prefix = value.substring(0, c);
+                namespace = this.namespaceManager.getNamespace(prefix);
+                if (namespace == null)
+                {
+                    throw new TagAttributeException(tag, attr, "No Namespace matched for: " + prefix);
+                }
+                localName = value.substring(c + 1);
+            }
+            return new String[] { namespace, localName };
+        }
+        else
+        {
+            return new String[] { tag.getNamespace(), tag.getLocalName() };
+        }
+    }
+
+    private Tag trimJSFCAttribute(Tag tag)
+    {
+        TagAttribute attr = tag.getAttributes().get("jsfc");
+        if (attr != null)
+        {
+            TagAttribute[] oa = tag.getAttributes().getAll();
+            TagAttribute[] na = new TagAttribute[oa.length - 1];
+            int p = 0;
+            for (int i = 0; i < oa.length; i++)
+            {
+                if (!"jsfc".equals(oa[i].getLocalName()))
+                {
+                    na[p++] = oa[i];
+                }
+            }
+            return new Tag(tag, new TagAttributesImpl(na));
+        }
+        return tag;
+    }
+
+    private Tag trimNSAttributes(Tag tag)
+    {
+        TagAttribute[] attr = tag.getAttributes().getAll();
+        int remove = 0;
+        for (int i = 0; i < attr.length; i++)
+        {
+            if (attr[i].getQName().startsWith("xmlns") && this.tagLibrary.containsNamespace(attr[i].getValue()))
+            {
+                remove |= 1 << i;
+                if (log.isLoggable(Level.FINE))
+                {
+                    log.fine(attr[i] + " Namespace Bound to TagLibrary");
+                }
+            }
+        }
+        if (remove == 0)
+        {
+            return tag;
+        }
+        else
+        {
+            List<TagAttribute> attrList = new ArrayList<TagAttribute>(attr.length);
+            int p = 0;
+            for (int i = 0; i < attr.length; i++)
+            {
+                p = 1 << i;
+                if ((p & remove) == p)
+                {
+                    continue;
+                }
+                attrList.add(attr[i]);
+            }
+            attr = attrList.toArray(new TagAttribute[attrList.size()]);
+            return new Tag(tag.getLocation(), tag.getNamespace(), tag.getLocalName(), tag.getQName(),
+                           new TagAttributesImpl(attr));
+        }
+    }
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CompilationUnit.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CompilationUnit.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CompilationUnit.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CompilationUnit.java Sat Apr  4 18:44:59 2009
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.compiler;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.el.ELException;
+import javax.faces.FacesException;
+import javax.faces.component.UIComponent;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.FaceletException;
+import javax.faces.view.facelets.FaceletHandler;
+
+import org.apache.myfaces.view.facelets.tag.CompositeFaceletHandler;
+
+/**
+ * 
+ * @author Jacob Hookom
+ * @version $Id: CompilationUnit.java,v 1.7 2008/07/13 19:01:33 rlubke Exp $
+ */
+class CompilationUnit
+{
+
+    protected final static FaceletHandler LEAF = new FaceletHandler()
+    {
+        public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, FaceletException,
+                ELException
+        {
+        }
+
+        public String toString()
+        {
+            return "FaceletHandler Tail";
+        }
+    };
+
+    private List<CompilationUnit> children;
+
+    public CompilationUnit()
+    {
+    }
+
+    public void addChild(CompilationUnit unit)
+    {
+        if (this.children == null)
+        {
+            this.children = new ArrayList<CompilationUnit>();
+        }
+        this.children.add(unit);
+    }
+
+    public FaceletHandler createFaceletHandler()
+    {
+        return this.getNextFaceletHandler();
+    }
+
+    protected final FaceletHandler getNextFaceletHandler()
+    {
+        if (this.children == null || this.children.size() == 0)
+        {
+            return LEAF;
+        }
+        if (this.children.size() == 1)
+        {
+            CompilationUnit u = (CompilationUnit) this.children.get(0);
+            return u.createFaceletHandler();
+        }
+        FaceletHandler[] fh = new FaceletHandler[this.children.size()];
+        for (int i = 0; i < fh.length; i++)
+        {
+            fh[i] = ((CompilationUnit) this.children.get(i)).createFaceletHandler();
+        }
+        return new CompositeFaceletHandler(fh);
+    }
+
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/Compiler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/Compiler.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/Compiler.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/Compiler.java Sat Apr  4 18:44:59 2009
@@ -0,0 +1,239 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.compiler;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.el.ELException;
+import javax.el.ExpressionFactory;
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+import javax.faces.view.facelets.FaceletException;
+import javax.faces.view.facelets.FaceletHandler;
+
+import org.apache.myfaces.view.facelets.tag.CompositeTagDecorator;
+import org.apache.myfaces.view.facelets.tag.CompositeTagLibrary;
+import org.apache.myfaces.view.facelets.tag.TagDecorator;
+import org.apache.myfaces.view.facelets.tag.TagLibrary;
+import org.apache.myfaces.view.facelets.tag.ui.UILibrary;
+import org.apache.myfaces.view.facelets.util.ParameterCheck;
+import org.apache.myfaces.view.facelets.util.ReflectionUtil;
+
+/**
+ * A Compiler instance may handle compiling multiple sources
+ * 
+ * @author Jacob Hookom
+ * @version $Id: Compiler.java,v 1.16 2008/07/13 19:01:33 rlubke Exp $
+ */
+public abstract class Compiler
+{
+
+    protected final static Logger log = Logger.getLogger("facelets.compiler");
+
+    public final static String EXPRESSION_FACTORY = "compiler.ExpressionFactory";
+
+    private static final TagLibrary EMPTY_LIBRARY = new CompositeTagLibrary(new TagLibrary[0]);
+
+    private static final TagDecorator EMPTY_DECORATOR = new CompositeTagDecorator(new TagDecorator[0]);
+
+    private boolean validating = false;
+
+    private boolean trimmingWhitespace = false;
+
+    private boolean trimmingComments = false;
+
+    private final List<TagLibrary> libraries = new ArrayList<TagLibrary>();
+
+    private final List<TagDecorator> decorators = new ArrayList<TagDecorator>();
+
+    private final Map<String, String> features = new HashMap<String, String>();
+
+    private boolean initialized = false;
+
+    /**
+     * 
+     */
+    public Compiler()
+    {
+
+    }
+
+    private synchronized void initialize()
+    {
+        if (this.initialized)
+            return;
+        log.fine("Initializing");
+        try
+        {
+            TagLibraryConfig cfg = new TagLibraryConfig();
+            cfg.loadImplicit(this);
+
+            if (!this.createTagLibrary().containsNamespace(UILibrary.Namespace))
+            {
+                log
+                        .severe("Missing Built-in Tag Libraries! Make sure they are included within the META-INF directory of Facelets' Jar");
+            }
+
+        }
+        catch (IOException e)
+        {
+            log.log(Level.SEVERE, "Compiler Initialization Error", e);
+        }
+        finally
+        {
+            this.initialized = true;
+        }
+        log.fine("Initialization Successful");
+    }
+
+    public final FaceletHandler compile(URL src, String alias) throws IOException, FaceletException, ELException,
+            FacesException
+    {
+        if (!this.initialized)
+            this.initialize();
+        return this.doCompile(src, alias);
+    }
+
+    protected abstract FaceletHandler doCompile(URL src, String alias) throws IOException, FaceletException,
+            ELException, FacesException;
+
+    public final TagDecorator createTagDecorator()
+    {
+        if (this.decorators.size() > 0)
+        {
+            return new CompositeTagDecorator(this.decorators.toArray(new TagDecorator[this.decorators.size()]));
+        }
+        return EMPTY_DECORATOR;
+    }
+
+    public final void addTagDecorator(TagDecorator decorator)
+    {
+        ParameterCheck.notNull("decorator", decorator);
+        if (!this.decorators.contains(decorator))
+        {
+            this.decorators.add(decorator);
+        }
+    }
+
+    public final ExpressionFactory createExpressionFactory()
+    {
+        ExpressionFactory el = null;
+        el = (ExpressionFactory) this.featureInstance(EXPRESSION_FACTORY);
+        if (el == null)
+        {
+            try
+            {
+                el = FacesContext.getCurrentInstance().getApplication().getExpressionFactory();
+                if (el == null)
+                {
+                    log.warning("No default ExpressionFactory from Faces Implementation, attempting to load from Feature["
+                                + EXPRESSION_FACTORY + "]");
+                }
+            }
+            catch (Exception e)
+            {
+                // do nothing
+            }
+        }
+        
+        return el;
+    }
+
+    private final Object featureInstance(String name)
+    {
+        String type = (String) this.features.get(name);
+        if (type != null)
+        {
+            try
+            {
+                return ReflectionUtil.forName(type).newInstance();
+            }
+            catch (Throwable t)
+            {
+                throw new FaceletException("Could not instantiate feature[" + name + "]: " + type);
+            }
+        }
+        return null;
+    }
+
+    public final TagLibrary createTagLibrary()
+    {
+        if (this.libraries.size() > 0)
+        {
+            return new CompositeTagLibrary(this.libraries.toArray(new TagLibrary[this.libraries.size()]));
+        }
+        return EMPTY_LIBRARY;
+    }
+
+    public final void addTagLibrary(TagLibrary library)
+    {
+        ParameterCheck.notNull("library", library);
+        if (!this.libraries.contains(library))
+        {
+            this.libraries.add(library);
+        }
+    }
+
+    public final void setFeature(String name, String value)
+    {
+        this.features.put(name, value);
+    }
+
+    public final String getFeature(String name)
+    {
+        return (String) this.features.get(name);
+    }
+
+    public final boolean isTrimmingComments()
+    {
+        return this.trimmingComments;
+    }
+
+    public final void setTrimmingComments(boolean trimmingComments)
+    {
+        this.trimmingComments = trimmingComments;
+    }
+
+    public final boolean isTrimmingWhitespace()
+    {
+        return this.trimmingWhitespace;
+    }
+
+    public final void setTrimmingWhitespace(boolean trimmingWhitespace)
+    {
+        this.trimmingWhitespace = trimmingWhitespace;
+    }
+
+    public final boolean isValidating()
+    {
+        return this.validating;
+    }
+
+    public final void setValidating(boolean validating)
+    {
+        this.validating = validating;
+    }
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/EncodingHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/EncodingHandler.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/EncodingHandler.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/EncodingHandler.java Sat Apr  4 18:44:59 2009
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.compiler;
+
+import java.io.IOException;
+
+import javax.el.ELException;
+import javax.faces.FacesException;
+import javax.faces.component.UIComponent;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.FaceletException;
+import javax.faces.view.facelets.FaceletHandler;
+
+public class EncodingHandler implements FaceletHandler
+{
+
+    private final FaceletHandler next;
+    private final String encoding;
+
+    public EncodingHandler(FaceletHandler next, String encoding)
+    {
+        this.next = next;
+        this.encoding = encoding;
+    }
+
+    public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, FaceletException,
+            ELException
+    {
+        this.next.apply(ctx, parent);
+        ctx.getFacesContext().getExternalContext().getRequestMap().put("facelets.Encoding", this.encoding);
+    }
+
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/EndElementInstruction.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/EndElementInstruction.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/EndElementInstruction.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/EndElementInstruction.java Sat Apr  4 18:44:59 2009
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.compiler;
+
+import java.io.IOException;
+
+import javax.el.ELContext;
+import javax.el.ExpressionFactory;
+import javax.faces.context.FacesContext;
+
+final class EndElementInstruction implements Instruction
+{
+    private final String element;
+
+    public EndElementInstruction(String element)
+    {
+        this.element = element;
+    }
+
+    public void write(FacesContext context) throws IOException
+    {
+        context.getResponseWriter().endElement(this.element);
+    }
+
+    public Instruction apply(ExpressionFactory factory, ELContext ctx)
+    {
+        return this;
+    }
+
+    public boolean isLiteral()
+    {
+        return true;
+    }
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/Instruction.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/Instruction.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/Instruction.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/Instruction.java Sat Apr  4 18:44:59 2009
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.compiler;
+
+import java.io.IOException;
+
+import javax.el.ELContext;
+import javax.el.ExpressionFactory;
+import javax.faces.context.FacesContext;
+
+interface Instruction
+{
+    public void write(FacesContext context) throws IOException;
+
+    public Instruction apply(ExpressionFactory factory, ELContext ctx);
+
+    public boolean isLiteral();
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/LiteralAttributeInstruction.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/LiteralAttributeInstruction.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/LiteralAttributeInstruction.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/LiteralAttributeInstruction.java Sat Apr  4 18:44:59 2009
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.compiler;
+
+import java.io.IOException;
+
+import javax.el.ELContext;
+import javax.el.ExpressionFactory;
+import javax.faces.context.FacesContext;
+
+final class LiteralAttributeInstruction implements Instruction
+{
+    private final String attr;
+
+    private final String text;
+
+    public LiteralAttributeInstruction(String attr, String text)
+    {
+        this.attr = attr;
+        this.text = text;
+    }
+
+    public void write(FacesContext context) throws IOException
+    {
+        context.getResponseWriter().writeAttribute(this.attr, this.text, null);
+    }
+
+    public Instruction apply(ExpressionFactory factory, ELContext ctx)
+    {
+        return this;
+    }
+
+    public boolean isLiteral()
+    {
+        return true;
+    }
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/LiteralCommentInstruction.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/LiteralCommentInstruction.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/LiteralCommentInstruction.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/LiteralCommentInstruction.java Sat Apr  4 18:44:59 2009
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.compiler;
+
+import java.io.IOException;
+
+import javax.el.ELContext;
+import javax.el.ExpressionFactory;
+import javax.faces.context.FacesContext;
+
+final class LiteralCommentInstruction implements Instruction
+{
+    private final String text;
+
+    public LiteralCommentInstruction(String text)
+    {
+        this.text = text;
+    }
+
+    public void write(FacesContext context) throws IOException
+    {
+        context.getResponseWriter().writeComment(this.text);
+    }
+
+    public Instruction apply(ExpressionFactory factory, ELContext ctx)
+    {
+        return this;
+    }
+
+    public boolean isLiteral()
+    {
+        return true;
+    }
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/LiteralTextInstruction.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/LiteralTextInstruction.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/LiteralTextInstruction.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/LiteralTextInstruction.java Sat Apr  4 18:44:59 2009
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.compiler;
+
+import java.io.IOException;
+
+import javax.el.ELContext;
+import javax.el.ExpressionFactory;
+import javax.faces.context.FacesContext;
+
+final class LiteralTextInstruction implements Instruction
+{
+    private final String text;
+
+    public LiteralTextInstruction(String text)
+    {
+        this.text = text;
+    }
+
+    public void write(FacesContext context) throws IOException
+    {
+        context.getResponseWriter().writeText(this.text, null);
+    }
+
+    public Instruction apply(ExpressionFactory factory, ELContext ctx)
+    {
+        return this;
+    }
+
+    public boolean isLiteral()
+    {
+        return true;
+    }
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/LiteralXMLInstruction.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/LiteralXMLInstruction.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/LiteralXMLInstruction.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/LiteralXMLInstruction.java Sat Apr  4 18:44:59 2009
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.compiler;
+
+import java.io.IOException;
+
+import javax.el.ELContext;
+import javax.el.ExpressionFactory;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+
+final class LiteralXMLInstruction implements Instruction
+{
+
+    private final static char[] STOP = new char[0];
+
+    private final char[] instruction;
+    private final int len;
+
+    public LiteralXMLInstruction(String literal)
+    {
+        this.instruction = literal.toCharArray();
+        this.len = this.instruction.length;
+    }
+
+    public void write(FacesContext context) throws IOException
+    {
+        ResponseWriter rw = context.getResponseWriter();
+        rw.writeText(STOP, 0, 0); // hack to get closing elements
+        rw.write(this.instruction, 0, this.len);
+    }
+
+    public Instruction apply(ExpressionFactory factory, ELContext ctx)
+    {
+        return this;
+    }
+
+    public boolean isLiteral()
+    {
+        return true;
+    }
+
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/NamespaceHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/NamespaceHandler.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/NamespaceHandler.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/NamespaceHandler.java Sat Apr  4 18:44:59 2009
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.compiler;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import javax.el.ELException;
+import javax.el.FunctionMapper;
+import javax.faces.FacesException;
+import javax.faces.component.UIComponent;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.FaceletException;
+import javax.faces.view.facelets.FaceletHandler;
+
+import org.apache.myfaces.view.facelets.el.CompositeFunctionMapper;
+import org.apache.myfaces.view.facelets.tag.TagLibrary;
+
+final class NamespaceHandler extends FunctionMapper implements FaceletHandler
+{
+
+    private final TagLibrary library;
+    private final Map<String, String> ns;
+    private FaceletHandler next;
+
+    public NamespaceHandler(FaceletHandler next, TagLibrary library, Map<String, String> ns)
+    {
+        this.library = library;
+        this.ns = ns;
+        this.next = next;
+    }
+
+    public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, FaceletException,
+            ELException
+    {
+        FunctionMapper orig = ctx.getFunctionMapper();
+        ctx.setFunctionMapper(new CompositeFunctionMapper(this, orig));
+        try
+        {
+            next.apply(ctx, parent);
+        }
+        finally
+        {
+            ctx.setFunctionMapper(orig);
+        }
+    }
+
+    public Method resolveFunction(String prefix, String localName)
+    {
+        String uri = (String) this.ns.get(prefix);
+        if (uri != null)
+        {
+            return this.library.createFunction(uri, localName);
+        }
+        return null;
+    }
+
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/NamespaceManager.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/NamespaceManager.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/NamespaceManager.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/NamespaceManager.java Sat Apr  4 18:44:59 2009
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.compiler;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.myfaces.view.facelets.tag.TagLibrary;
+
+/**
+ * @author Jacob Hookom
+ * @version $Id: NamespaceManager.java,v 1.5 2008/07/13 19:01:33 rlubke Exp $
+ */
+final class NamespaceManager
+{
+
+    private final static class NS
+    {
+        public final String prefix;
+
+        public final String namespace;
+
+        public NS(String prefix, String ns)
+        {
+            this.prefix = prefix;
+            this.namespace = ns;
+        }
+    }
+
+    private final List<NS> namespaces;
+
+    /**
+     * 
+     */
+    public NamespaceManager()
+    {
+        this.namespaces = new ArrayList<NS>();
+    }
+
+    public void reset()
+    {
+        this.namespaces.clear();
+    }
+
+    public void pushNamespace(String prefix, String namespace)
+    {
+        NS ns = new NS(prefix, namespace);
+        this.namespaces.add(0, ns);
+    }
+
+    public String getNamespace(String prefix)
+    {
+        NS ns = null;
+        for (int i = 0; i < this.namespaces.size(); i++)
+        {
+            ns = (NS) this.namespaces.get(i);
+            if (ns.prefix.equals(prefix))
+            {
+                return ns.namespace;
+            }
+        }
+        return null;
+    }
+
+    public void popNamespace(String prefix)
+    {
+        NS ns = null;
+        for (int i = 0; i < this.namespaces.size(); i++)
+        {
+            ns = (NS) this.namespaces.get(i);
+            if (ns.prefix.equals(prefix))
+            {
+                this.namespaces.remove(i);
+                return;
+            }
+        }
+    }
+
+    public final NamespaceUnit toNamespaceUnit(TagLibrary library)
+    {
+        NamespaceUnit unit = new NamespaceUnit(library);
+        if (this.namespaces.size() > 0)
+        {
+            NS ns = null;
+            for (int i = this.namespaces.size() - 1; i >= 0; i--)
+            {
+                ns = this.namespaces.get(i);
+                unit.setNamespace(ns.prefix, ns.namespace);
+            }
+        }
+        return unit;
+    }
+
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/NamespaceUnit.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/NamespaceUnit.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/NamespaceUnit.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/NamespaceUnit.java Sat Apr  4 18:44:59 2009
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.compiler;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.faces.view.facelets.FaceletHandler;
+
+import org.apache.myfaces.view.facelets.tag.TagLibrary;
+
+/**
+ * 
+ * @author Jacob Hookom
+ * @version $Id: NamespaceUnit.java,v 1.4 2008/07/13 19:01:34 rlubke Exp $
+ */
+final class NamespaceUnit extends CompilationUnit
+{
+
+    private final Map<String, String> ns = new HashMap<String, String>();
+    private final TagLibrary library;
+
+    public NamespaceUnit(TagLibrary library)
+    {
+        this.library = library;
+    }
+
+    public FaceletHandler createFaceletHandler()
+    {
+        FaceletHandler next = this.getNextFaceletHandler();
+        return new NamespaceHandler(next, this.library, this.ns);
+    }
+
+    public void setNamespace(String prefix, String uri)
+    {
+        this.ns.put(prefix, uri);
+    }
+
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/RemoveUnit.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/RemoveUnit.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/RemoveUnit.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/RemoveUnit.java Sat Apr  4 18:44:59 2009
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.compiler;
+
+import javax.faces.view.facelets.FaceletHandler;
+
+/**
+ * 
+ * @author Jacob Hookom
+ * @version $Id: RemoveUnit.java,v 1.4 2008/07/13 19:01:33 rlubke Exp $
+ */
+final class RemoveUnit extends CompilationUnit
+{
+
+    public RemoveUnit()
+    {
+        super();
+    }
+
+    public void addChild(CompilationUnit unit)
+    {
+        // do nothing
+    }
+
+    public FaceletHandler createFaceletHandler()
+    {
+        return LEAF;
+    }
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/SAXCompiler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/SAXCompiler.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/SAXCompiler.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/SAXCompiler.java Sat Apr  4 18:44:59 2009
@@ -0,0 +1,327 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.compiler;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.el.ELException;
+import javax.faces.FacesException;
+import javax.faces.view.facelets.FaceletException;
+import javax.faces.view.facelets.FaceletHandler;
+import javax.faces.view.facelets.Location;
+import javax.faces.view.facelets.Tag;
+import javax.faces.view.facelets.TagAttribute;
+import javax.faces.view.facelets.TagAttributes;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.myfaces.view.facelets.tag.TagAttributeImpl;
+import org.apache.myfaces.view.facelets.tag.TagAttributesImpl;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Compiler implementation that uses SAX
+ * 
+ * @see org.apache.myfaces.view.facelets.compiler.Compiler
+ * 
+ * @author Jacob Hookom
+ * @version $Id: SAXCompiler.java,v 1.14 2008/07/13 19:01:33 rlubke Exp $
+ */
+public final class SAXCompiler extends Compiler
+{
+
+    private final static Pattern XmlDeclaration = Pattern
+            .compile("^<\\?xml.+?version=['\"](.+?)['\"](.+?encoding=['\"]((.+?))['\"])?.*?\\?>");
+
+    private static class CompilationHandler extends DefaultHandler implements LexicalHandler
+    {
+
+        private final String alias;
+
+        private boolean inDocument = false;
+
+        private Locator locator;
+
+        private final CompilationManager unit;
+
+        public CompilationHandler(CompilationManager unit, String alias)
+        {
+            this.unit = unit;
+            this.alias = alias;
+        }
+
+        public void characters(char[] ch, int start, int length) throws SAXException
+        {
+            if (this.inDocument)
+            {
+                this.unit.writeText(new String(ch, start, length));
+            }
+        }
+
+        public void comment(char[] ch, int start, int length) throws SAXException
+        {
+            if (this.inDocument)
+            {
+                this.unit.writeComment(new String(ch, start, length));
+            }
+        }
+
+        protected TagAttributes createAttributes(Attributes attrs)
+        {
+            int len = attrs.getLength();
+            TagAttribute[] ta = new TagAttribute[len];
+            for (int i = 0; i < len; i++)
+            {
+                ta[i] = new TagAttributeImpl(this.createLocation(), attrs.getURI(i), attrs.getLocalName(i), attrs
+                        .getQName(i), attrs.getValue(i));
+            }
+            return new TagAttributesImpl(ta);
+        }
+
+        protected Location createLocation()
+        {
+            return new Location(this.alias, this.locator.getLineNumber(), this.locator.getColumnNumber());
+        }
+
+        public void endCDATA() throws SAXException
+        {
+            if (this.inDocument)
+            {
+                this.unit.writeInstruction("]]>");
+            }
+        }
+
+        public void endDocument() throws SAXException
+        {
+            super.endDocument();
+        }
+
+        public void endDTD() throws SAXException
+        {
+            this.inDocument = true;
+        }
+
+        public void endElement(String uri, String localName, String qName) throws SAXException
+        {
+            this.unit.popTag();
+        }
+
+        public void endEntity(String name) throws SAXException
+        {
+        }
+
+        public void endPrefixMapping(String prefix) throws SAXException
+        {
+            this.unit.popNamespace(prefix);
+        }
+
+        public void fatalError(SAXParseException e) throws SAXException
+        {
+            if (this.locator != null)
+            {
+                throw new SAXException("Error Traced[line: " + this.locator.getLineNumber() + "] " + e.getMessage());
+            }
+            else
+            {
+                throw e;
+            }
+        }
+
+        public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
+        {
+            if (this.inDocument)
+            {
+                this.unit.writeWhitespace(new String(ch, start, length));
+            }
+        }
+
+        public InputSource resolveEntity(String publicId, String systemId) throws SAXException
+        {
+            String dtd = "default.dtd";
+            /*
+             * if ("-//W3C//DTD XHTML 1.0 Transitional//EN".equals(publicId)) { dtd = "xhtml1-transitional.dtd"; } else
+             * if (systemId != null && systemId.startsWith("file:/")) { return new InputSource(systemId); }
+             */
+            URL url = Thread.currentThread().getContextClassLoader().getResource(dtd);
+            return new InputSource(url.toString());
+        }
+
+        public void setDocumentLocator(Locator locator)
+        {
+            this.locator = locator;
+        }
+
+        public void startCDATA() throws SAXException
+        {
+            if (this.inDocument)
+            {
+                this.unit.writeInstruction("<![CDATA[");
+            }
+        }
+
+        public void startDocument() throws SAXException
+        {
+            this.inDocument = true;
+        }
+
+        public void startDTD(String name, String publicId, String systemId) throws SAXException
+        {
+            if (this.inDocument)
+            {
+                StringBuffer sb = new StringBuffer(64);
+                sb.append("<!DOCTYPE ").append(name);
+                if (publicId != null)
+                {
+                    sb.append(" PUBLIC \"").append(publicId).append("\"");
+                    if (systemId != null)
+                    {
+                        sb.append(" \"").append(systemId).append("\"");
+                    }
+                }
+                else if (systemId != null)
+                {
+                    sb.append(" SYSTEM \"").append(systemId).append("\"");
+                }
+                sb.append(" >\n");
+                this.unit.writeInstruction(sb.toString());
+            }
+            this.inDocument = false;
+        }
+
+        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
+        {
+            this.unit.pushTag(new Tag(this.createLocation(), uri, localName, qName, this.createAttributes(attributes)));
+        }
+
+        public void startEntity(String name) throws SAXException
+        {
+        }
+
+        public void startPrefixMapping(String prefix, String uri) throws SAXException
+        {
+            this.unit.pushNamespace(prefix, uri);
+        }
+
+        public void processingInstruction(String target, String data) throws SAXException
+        {
+            if (this.inDocument)
+            {
+                StringBuffer sb = new StringBuffer(64);
+                sb.append("<?").append(target).append(' ').append(data).append("?>\n");
+                this.unit.writeInstruction(sb.toString());
+            }
+        }
+    }
+
+    public SAXCompiler()
+    {
+        super();
+    }
+
+    public FaceletHandler doCompile(URL src, String alias) throws IOException, FaceletException, ELException,
+            FacesException
+    {
+        CompilationManager mngr = null;
+        InputStream is = null;
+        String encoding = "UTF-8";
+        try
+        {
+            is = new BufferedInputStream(src.openStream(), 1024);
+            mngr = new CompilationManager(alias, this);
+            encoding = writeXmlDecl(is, mngr);
+            CompilationHandler handler = new CompilationHandler(mngr, alias);
+            SAXParser parser = this.createSAXParser(handler);
+            parser.parse(is, handler);
+        }
+        catch (SAXException e)
+        {
+            throw new FaceletException("Error Parsing " + alias + ": " + e.getMessage(), e.getCause());
+        }
+        catch (ParserConfigurationException e)
+        {
+            throw new FaceletException("Error Configuring Parser " + alias + ": " + e.getMessage(), e.getCause());
+        }
+        finally
+        {
+            if (is != null)
+            {
+                is.close();
+            }
+        }
+        return new EncodingHandler(mngr.createFaceletHandler(), encoding);
+    }
+
+    protected static final String writeXmlDecl(InputStream is, CompilationManager mngr) throws IOException
+    {
+        is.mark(128);
+        String encoding = "UTF-8";
+        try
+        {
+            byte[] b = new byte[128];
+            if (is.read(b) > 0)
+            {
+                String r = new String(b);
+                Matcher m = XmlDeclaration.matcher(r);
+                if (m.find())
+                {
+                    mngr.writeInstruction(m.group(0) + "\n");
+                    if (m.group(3) != null)
+                    {
+                        encoding = m.group(3);
+                    }
+                }
+            }
+        }
+        finally
+        {
+            is.reset();
+        }
+        return encoding;
+    }
+
+    private final SAXParser createSAXParser(CompilationHandler handler) throws SAXException,
+            ParserConfigurationException
+    {
+        SAXParserFactory factory = SAXParserFactory.newInstance();
+        factory.setNamespaceAware(true);
+        factory.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
+        factory.setFeature("http://xml.org/sax/features/validation", this.isValidating());
+        factory.setValidating(this.isValidating());
+        SAXParser parser = factory.newSAXParser();
+        XMLReader reader = parser.getXMLReader();
+        reader.setProperty("http://xml.org/sax/properties/lexical-handler", handler);
+        reader.setErrorHandler(handler);
+        reader.setEntityResolver(handler);
+        return parser;
+    }
+
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/StartElementInstruction.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/StartElementInstruction.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/StartElementInstruction.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/StartElementInstruction.java Sat Apr  4 18:44:59 2009
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.compiler;
+
+import java.io.IOException;
+
+import javax.el.ELContext;
+import javax.el.ExpressionFactory;
+import javax.faces.context.FacesContext;
+
+final class StartElementInstruction implements Instruction
+{
+    private final String element;
+
+    public StartElementInstruction(String element)
+    {
+        this.element = element;
+    }
+
+    public void write(FacesContext context) throws IOException
+    {
+        context.getResponseWriter().startElement(this.element, null);
+    }
+
+    public Instruction apply(ExpressionFactory factory, ELContext ctx)
+    {
+        return this;
+    }
+
+    public boolean isLiteral()
+    {
+        return true;
+    }
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/TagLibraryConfig.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/TagLibraryConfig.java?rev=761982&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/TagLibraryConfig.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/TagLibraryConfig.java Sat Apr  4 18:44:59 2009
@@ -0,0 +1,515 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.compiler;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.faces.view.facelets.TagHandler;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.myfaces.view.facelets.tag.AbstractTagLibrary;
+import org.apache.myfaces.view.facelets.tag.TagLibrary;
+import org.apache.myfaces.view.facelets.util.Classpath;
+import org.apache.myfaces.view.facelets.util.ParameterCheck;
+import org.apache.myfaces.view.facelets.util.ReflectionUtil;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Handles creating a {@link org.apache.myfaces.view.facelets.tag.TagLibrary TagLibrary} from a {@link java.net.URL URL} source.
+ * 
+ * @author Jacob Hookom
+ * @version $Id: TagLibraryConfig.java,v 1.14 2008/07/13 19:01:34 rlubke Exp $
+ */
+public final class TagLibraryConfig
+{
+
+    private final static String SUFFIX = ".taglib.xml";
+
+    protected final static Logger log = Logger.getLogger("facelets.compiler");
+
+    private static class TagLibraryImpl extends AbstractTagLibrary
+    {
+        public TagLibraryImpl(String namespace)
+        {
+            super(namespace);
+        }
+
+        public void putConverter(String name, String id)
+        {
+            ParameterCheck.notNull("name", name);
+            ParameterCheck.notNull("id", id);
+            this.addConverter(name, id);
+        }
+
+        public void putConverter(String name, String id, Class<? extends TagHandler> handlerClass)
+        {
+            ParameterCheck.notNull("name", name);
+            ParameterCheck.notNull("id", id);
+            ParameterCheck.notNull("handlerClass", handlerClass);
+            this.addConverter(name, id, handlerClass);
+        }
+
+        public void putValidator(String name, String id)
+        {
+            ParameterCheck.notNull("name", name);
+            ParameterCheck.notNull("id", id);
+            this.addValidator(name, id);
+        }
+
+        public void putValidator(String name, String id, Class<? extends TagHandler> handlerClass)
+        {
+            ParameterCheck.notNull("name", name);
+            ParameterCheck.notNull("id", id);
+            ParameterCheck.notNull("handlerClass", handlerClass);
+            this.addValidator(name, id, handlerClass);
+        }
+
+        public void putTagHandler(String name, Class<? extends TagHandler> type)
+        {
+            ParameterCheck.notNull("name", name);
+            ParameterCheck.notNull("type", type);
+            this.addTagHandler(name, type);
+        }
+
+        public void putComponent(String name, String componentType, String rendererType)
+        {
+            ParameterCheck.notNull("name", name);
+            ParameterCheck.notNull("componentType", componentType);
+            this.addComponent(name, componentType, rendererType);
+        }
+
+        public void putComponent(String name, String componentType, String rendererType, 
+                                 Class<? extends TagHandler> handlerClass)
+        {
+            ParameterCheck.notNull("name", name);
+            ParameterCheck.notNull("componentType", componentType);
+            ParameterCheck.notNull("handlerClass", handlerClass);
+            this.addComponent(name, componentType, rendererType, handlerClass);
+        }
+
+        public void putUserTag(String name, URL source)
+        {
+            ParameterCheck.notNull("name", name);
+            ParameterCheck.notNull("source", source);
+            this.addUserTag(name, source);
+        }
+
+        public void putFunction(String name, Method method)
+        {
+            ParameterCheck.notNull("name", name);
+            ParameterCheck.notNull("method", method);
+            this.addFunction(name, method);
+        }
+    }
+
+    private static class LibraryHandler extends DefaultHandler
+    {
+        private final URL source;
+
+        private TagLibrary library;
+
+        private final StringBuffer buffer;
+
+        private Locator locator;
+
+        private String tagName;
+
+        private String converterId;
+
+        private String validatorId;
+
+        private String componentType;
+
+        private String rendererType;
+
+        private String functionName;
+
+        private Class<? extends TagHandler> handlerClass;
+
+        private Class<?> functionClass;
+
+        private String functionSignature;
+
+        public LibraryHandler(URL source)
+        {
+            this.source = source;
+            this.buffer = new StringBuffer(64);
+        }
+
+        public TagLibrary getLibrary()
+        {
+            return this.library;
+        }
+
+        public void endElement(String uri, String localName, String qName) throws SAXException
+        {
+            try
+            {
+                if ("facelet-taglib".equals(qName))
+                {
+                    ; // Nothing to do
+                }
+                else if ("library-class".equals(qName))
+                {
+                    this.processLibraryClass();
+                }
+                else if ("namespace".equals(qName))
+                {
+                    this.library = new TagLibraryImpl(this.captureBuffer());
+                }
+                else if ("component-type".equals(qName))
+                {
+                    this.componentType = this.captureBuffer();
+                }
+                else if ("renderer-type".equals(qName))
+                {
+                    this.rendererType = this.captureBuffer();
+                }
+                else if ("tag-name".equals(qName))
+                {
+                    this.tagName = this.captureBuffer();
+                }
+                else if ("function-name".equals(qName))
+                {
+                    this.functionName = this.captureBuffer();
+                }
+                else if ("function-class".equals(qName))
+                {
+                    String className = this.captureBuffer();
+                    this.functionClass = createClass(Object.class, className);
+                }
+                else
+                {
+                    // Make sure there we've seen a namespace element
+                    // before trying any of the following elements to avoid
+                    // obscure NPEs
+                    if (this.library == null)
+                    {
+                        throw new IllegalStateException("No <namespace> element");
+                    }
+
+                    TagLibraryImpl impl = (TagLibraryImpl) this.library;
+
+                    if ("tag".equals(qName))
+                    {
+                        if (this.handlerClass != null)
+                        {
+                            impl.putTagHandler(this.tagName, this.handlerClass);
+                        }
+                    }
+                    else if ("handler-class".equals(qName))
+                    {
+                        String cName = this.captureBuffer();
+                        this.handlerClass = createClass(TagHandler.class, cName);
+                    }
+                    else if ("component".equals(qName))
+                    {
+                        if (this.handlerClass != null)
+                        {
+                            impl.putComponent(this.tagName, this.componentType, this.rendererType, this.handlerClass);
+                            this.handlerClass = null;
+                        }
+                        else
+                        {
+                            impl.putComponent(this.tagName, this.componentType, this.rendererType);
+                        }
+                    }
+                    else if ("converter-id".equals(qName))
+                    {
+                        this.converterId = this.captureBuffer();
+                    }
+                    else if ("converter".equals(qName))
+                    {
+                        if (this.handlerClass != null)
+                        {
+                            impl.putConverter(this.tagName, this.converterId, handlerClass);
+                            this.handlerClass = null;
+                        }
+                        else
+                        {
+                            impl.putConverter(this.tagName, this.converterId);
+                        }
+                        this.converterId = null;
+                    }
+                    else if ("validator-id".equals(qName))
+                    {
+                        this.validatorId = this.captureBuffer();
+                    }
+                    else if ("validator".equals(qName))
+                    {
+                        if (this.handlerClass != null)
+                        {
+                            impl.putValidator(this.tagName, this.validatorId, handlerClass);
+                            this.handlerClass = null;
+                        }
+                        else
+                        {
+                            impl.putValidator(this.tagName, this.validatorId);
+                        }
+                        this.validatorId = null;
+                    }
+                    else if ("source".equals(qName))
+                    {
+                        String path = this.captureBuffer();
+                        URL url = new URL(this.source, path);
+                        impl.putUserTag(this.tagName, url);
+                    }
+                    else if ("function-signature".equals(qName))
+                    {
+                        this.functionSignature = this.captureBuffer();
+                        Method m = createMethod(this.functionClass, this.functionSignature);
+                        impl.putFunction(this.functionName, m);
+                    }
+                }
+            }
+            catch (Exception e)
+            {
+                SAXException saxe = new SAXException("Error Handling [" + this.source + "@"
+                        + this.locator.getLineNumber() + "," + this.locator.getColumnNumber() + "] <" + qName + ">");
+                saxe.initCause(e);
+                throw saxe;
+            }
+        }
+
+        private String captureBuffer() throws Exception
+        {
+            String s = this.buffer.toString().trim();
+            if (s.length() == 0)
+            {
+                throw new Exception("Value Cannot be Empty");
+            }
+            this.buffer.setLength(0);
+            return s;
+        }
+
+        @SuppressWarnings("unchecked")
+        private static <T> Class<? extends T> createClass(Class<T> type, String name) throws Exception
+        {
+            Class<? extends T> factory = (Class<? extends T>)ReflectionUtil.forName(name);
+            if (!type.isAssignableFrom(factory))
+            {
+                throw new Exception(name + " must be an instance of " + type.getName());
+            }
+            return factory;
+        }
+
+        private static Method createMethod(Class<?> type, String s) throws Exception
+        {
+            int pos = s.indexOf(' ');
+            if (pos == -1)
+            {
+                throw new Exception("Must Provide Return Type: " + s);
+            }
+            else
+            {
+                int pos2 = s.indexOf('(', pos + 1);
+                if (pos2 == -1)
+                {
+                    throw new Exception("Must provide a method name, followed by '(': " + s);
+                }
+                else
+                {
+                    String mn = s.substring(pos + 1, pos2).trim();
+                    pos = s.indexOf(')', pos2 + 1);
+                    if (pos == -1)
+                    {
+                        throw new Exception("Must close parentheses, ')' missing: " + s);
+                    }
+                    else
+                    {
+                        String[] ps = s.substring(pos2 + 1, pos).trim().split(",");
+                        Class<?>[] pc;
+                        if (ps.length == 1 && "".equals(ps[0]))
+                        {
+                            pc = new Class[0];
+                        }
+                        else
+                        {
+                            pc = new Class[ps.length];
+                            for (int i = 0; i < pc.length; i++)
+                            {
+                                pc[i] = ReflectionUtil.forName(ps[i].trim());
+                            }
+                        }
+                        try
+                        {
+                            return type.getMethod(mn, pc);
+                        }
+                        catch (NoSuchMethodException e)
+                        {
+                            throw new Exception("No Function Found on type: " + type.getName() + " with signature: "
+                                    + s);
+                        }
+
+                    }
+
+                }
+            }
+        }
+
+        private void processLibraryClass() throws Exception
+        {
+            String name = this.captureBuffer();
+            Class<?> type = createClass(TagLibrary.class, name);
+            this.library = (TagLibrary) type.newInstance();
+        }
+
+        public InputSource resolveEntity(String publicId, String systemId) throws SAXException
+        {
+            if ("-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN".equals(publicId))
+            {
+                URL url = Thread.currentThread().getContextClassLoader().getResource("facelet-taglib_1_0.dtd");
+                return new InputSource(url.toExternalForm());
+            }
+            return null;
+        }
+
+        public void characters(char[] ch, int start, int length) throws SAXException
+        {
+            this.buffer.append(ch, start, length);
+        }
+
+        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
+        {
+            this.buffer.setLength(0);
+            if ("tag".equals(qName))
+            {
+                this.handlerClass = null;
+                this.componentType = null;
+                this.rendererType = null;
+                this.tagName = null;
+            }
+            else if ("function".equals(qName))
+            {
+                this.functionName = null;
+                this.functionClass = null;
+                this.functionSignature = null;
+            }
+        }
+
+        public void error(SAXParseException e) throws SAXException
+        {
+            SAXException saxe = new SAXException("Error Handling [" + this.source + "@" + e.getLineNumber() + ","
+                    + e.getColumnNumber() + "]");
+            saxe.initCause(e);
+            throw saxe;
+        }
+
+        public void setDocumentLocator(Locator locator)
+        {
+            this.locator = locator;
+        }
+
+        public void fatalError(SAXParseException e) throws SAXException
+        {
+            throw e;
+        }
+
+        public void warning(SAXParseException e) throws SAXException
+        {
+            throw e;
+        }
+    }
+
+    public TagLibraryConfig()
+    {
+        super();
+    }
+
+    public static TagLibrary create(URL url) throws IOException
+    {
+        InputStream is = null;
+        TagLibrary t = null;
+        try
+        {
+            is = url.openStream();
+            LibraryHandler handler = new LibraryHandler(url);
+            SAXParser parser = createSAXParser(handler);
+            parser.parse(is, handler);
+            t = handler.getLibrary();
+        }
+        catch (SAXException e)
+        {
+            IOException ioe = new IOException("Error parsing [" + url + "]: ");
+            ioe.initCause(e);
+            throw ioe;
+        }
+        catch (ParserConfigurationException e)
+        {
+            IOException ioe = new IOException("Error parsing [" + url + "]: ");
+            ioe.initCause(e);
+            throw ioe;
+        }
+        finally
+        {
+            if (is != null)
+                is.close();
+        }
+        return t;
+    }
+
+    public void loadImplicit(Compiler compiler) throws IOException
+    {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        URL[] urls = Classpath.search(cl, "META-INF/", SUFFIX);
+        for (int i = 0; i < urls.length; i++)
+        {
+            try
+            {
+                compiler.addTagLibrary(create(urls[i]));
+                if (log.isLoggable(Level.FINE))
+                {
+                    log.fine("Added Library from: " + urls[i]);
+                }
+            }
+            catch (Exception e)
+            {
+                log.log(Level.SEVERE, "Error Loading Library: " + urls[i], e);
+            }
+        }
+    }
+
+    private static final SAXParser createSAXParser(LibraryHandler handler) throws SAXException,
+            ParserConfigurationException
+    {
+        SAXParserFactory factory = SAXParserFactory.newInstance();
+        factory.setNamespaceAware(false);
+        factory.setFeature("http://xml.org/sax/features/validation", true);
+        factory.setValidating(true);
+        SAXParser parser = factory.newSAXParser();
+        XMLReader reader = parser.getXMLReader();
+        reader.setErrorHandler(handler);
+        reader.setEntityResolver(handler);
+        return parser;
+    }
+
+}