jsr344-experts@javaserverfaces-spec-public.java.net

[jsr344-experts] [594-FacesComponentTagHandler] PROPOSAL PROVISIONALLY CLOSED

From: Edward Burns <edward.burns_at_oracle.com>
Date: Mon, 13 Feb 2012 14:42:43 -0800

Because this one was pretty straightforward, I'm marking it
PROVISIONALLY CLOSED, but we can certainly discuss it.

ACTION: Please review by 23:59 EST Wednesday 15 February 2012.

If all the tests pass locally, I'm going to commit this so it'll be in
tonight's nightly build.

Here is the changebundle from the issue [1].

http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-594

This is one approach to specifying and implementing this feature. There
are certainly others. This one is optimized to achieve a balance of
user productivity and runtime performance.

The specification change is the addition of some attributes to the
FacesComponent annotation.


SECTION: Modified Files
----------------------------
M jsf-api/src/main/java/javax/faces/component/FacesComponent.java

+ * <p><span class="changed_modified_2_2">The</span> presence of this annotation
+ * on a class that extends {_at_link UIComponent} must cause the runtime to
+ * register this class as a component suitable for inclusion in a view.
+ * <span class="changed_added_2_2">If the <code>tagHandler</code> attribute
+ * is <code>true</code>, the runtime must create a corresponding Facelet
+ * tag handler according to the rules specified in the attributes of
+ * this annotation.</span></p>

  My overall goal is to make it as easy as possible for the developer to
  have a tag created for their component, without causing all pre-2.2
  usages of @FacesComponent to be picked up in the scheme.

  I really wanted to achieve the simplicity of inferring the tag name
  from the SimpleName of the class to which the annotation is attached.
  This goal made it impossible to rely on the presence or absence of a
  value for the "tagName" attribute as an indicator of the intent to
  autogenerate a tag handler.

  Therefore, I chose to introduce a "boolean tagHandler() default
  false;" attribute as a compromise intended to deliver the maximum
  convention over configuration, without causing the runtime to pay an
  undue performance penalty. I also didn't want to get in the way of
  existing composite component usages. With this design, the minimal
  thing you can do to get a tag looks like this:

  @FacesComponent(value="myComponentId", tagHandler=true)
  public class MyComponent extends HtmlInputText {}

  This will cause a tag named myComponent to appear in tag library
  <http://java.sun.com/jsf/component>. Note that we have another issue
  to introduce a short-hand for tag library namespace URLs. Thus, I
  won't bother with making a short name in this issue.

  Now, sure, there are other ways to design this, and I'm open to
  considering them, but let's put this one on the table as a starting
  point.

A jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/LazyTagLibrary.java

- This class is an abstraction from CompositeComponentTagLibrary.

M jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/CompositeComponentTagLibrary.java

- Make this extend LazyTagLibrary.

A jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/FacesComponentTagLibrary.java

- Now a sibling of CompositeComponentTagLibrary, this LazyTagLibrary is for
  tags corresponding to components annotated with @FacesComponent

M jsf-ri/src/main/java/com/sun/faces/facelets/tag/CompositeTagLibrary.java

- Leverage the fact that there are exactly two kinds of LazyTagLibrary to consider.

M jsf-ri/src/main/java/com/sun/faces/application/ApplicationAssociate.java
M jsf-ri/src/main/java/com/sun/faces/application/ApplicationImpl.java
M jsf-ri/src/main/java/com/sun/faces/application/annotation/ComponentConfigHandler.java

- Wire up the annotation scanning to Facelets, using ApplicationAssociate.

A jsf-ri/src/main/java/com/sun/faces/application/annotation/FacesComponentUsage.jav

- Helper struct class.

M jsf-test/build.xml

- new test

M nbproject/project.xml

- Spellchecker wordlist.

A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_htmlunit
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_htmlunit/src
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_htmlunit/src/main
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_htmlunit/src/main/java
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_htmlunit/src/main/java/com
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_htmlunit/src/main/java/com/sun
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_htmlunit/src/main/java/com/sun/faces
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_htmlunit/src/main/java/com/sun/faces/test
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_htmlunit/src/main/java/com/sun/faces/test/i_spec_594_htmlunit
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_htmlunit/src/main/java/com/sun/faces/test/i_spec_594_htmlunit/IssueSpec594TestCase.java
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_htmlunit/src/main/resources
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_htmlunit/pom.xml
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java/com
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java/com/sun
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java/com/sun/faces
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java/com/sun/faces/test
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java/com/sun/faces/test/i_spec_594_war
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java/com/sun/faces/test/i_spec_594_war/UserBean.java
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java/com/sun/faces/test/i_spec_594_war/components
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java/com/sun/faces/test/i_spec_594_war/components/TagNameExplicitlyDeclared.java
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java/com/sun/faces/test/i_spec_594_war/components/TagNameDerivedFromClassName.java
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/resources
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/webapp
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/webapp/main.xhtml
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/webapp/WEB-INF
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/webapp/WEB-INF/beans.xml
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/webapp/WEB-INF/web.xml
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/pom.xml
A jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/build.xml

- testcase

SECTION: Diffs
----------------------------
Index: jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/LazyTagLibrary.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/LazyTagLibrary.java (revision 0)
+++ jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/LazyTagLibrary.java (revision 0)
@@ -0,0 +1,53 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+
+ */
+package com.sun.faces.facelets.tag.jsf;
+
+import com.sun.faces.facelets.tag.TagLibraryImpl;
+
+public abstract class LazyTagLibrary extends TagLibraryImpl {
+
+ public LazyTagLibrary(String namespace) {
+ super(namespace);
+ }
+
+ public abstract boolean tagLibraryForNSExists(String toTest);
+
+}
Index: jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/CompositeComponentTagLibrary.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/CompositeComponentTagLibrary.java (revision 9668)
+++ jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/CompositeComponentTagLibrary.java (working copy)
@@ -76,7 +76,7 @@
 import java.util.logging.Logger;
 
 
-public class CompositeComponentTagLibrary extends TagLibraryImpl {
+public class CompositeComponentTagLibrary extends LazyTagLibrary {
     
     private static final Logger LOGGER = FacesLogger.FACELETS_COMPONENT.getLogger();
 
@@ -178,6 +178,7 @@
     private static final String NS_COMPOSITE_COMPONENT_PREFIX =
             "http://java.sun.com/jsf/composite/";
     
+ @Override
     public boolean tagLibraryForNSExists(String toTest) {
         boolean result = false;
         
Index: jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/FacesComponentTagLibrary.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/FacesComponentTagLibrary.java (revision 0)
+++ jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/FacesComponentTagLibrary.java (revision 0)
@@ -0,0 +1,154 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+
+ */
+package com.sun.faces.facelets.tag.jsf;
+
+import com.sun.faces.application.ApplicationAssociate;
+import com.sun.faces.application.annotation.FacesComponentUsage;
+import com.sun.faces.util.FacesLogger;
+import com.sun.faces.util.Util;
+import java.util.List;
+import java.util.logging.Logger;
+import javax.faces.FacesException;
+import javax.faces.component.FacesComponent;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.view.facelets.TagConfig;
+import javax.faces.view.facelets.TagHandler;
+
+public class FacesComponentTagLibrary extends LazyTagLibrary {
+
+ private static final Logger LOGGER = FacesLogger.FACELETS_COMPONENT.getLogger();
+
+ private ApplicationAssociate appAss;
+
+
+ public FacesComponentTagLibrary(String ns) {
+ super(ns);
+ if (null == ns) {
+ throw new NullPointerException();
+ }
+ appAss = ApplicationAssociate.getCurrentInstance();
+ }
+
+
+ @Override
+ public boolean containsTagHandler(String ns, String localName) {
+ Util.notNull("namespace", ns);
+ Util.notNull("tagName", localName);
+
+ if (!ns.equals(this.getNamespace())) {
+ return false;
+ }
+
+ // Check the cache maintained by our superclass...
+ boolean containsTagHandler = super.containsTagHandler(ns, localName);
+ if (!containsTagHandler) {
+ FacesComponentUsage matchingFacesComponentUsage =
+ findFacesComponentUsageForLocalName(ns, localName);
+ containsTagHandler = null != matchingFacesComponentUsage;
+
+ }
+ return containsTagHandler;
+ }
+
+ private FacesComponentUsage findFacesComponentUsageForLocalName(String ns, String localName) {
+ FacesComponentUsage result = null;
+
+ Util.notNull("namespace", ns);
+ Util.notNull("tagName", localName);
+
+ if (!ns.equals(this.getNamespace())) {
+ return result;
+ }
+ List<FacesComponentUsage> componentsForNamespace = appAss.getComponentsForNamespace(ns);
+ String tagName;
+ for (FacesComponentUsage cur: componentsForNamespace) {
+ FacesComponent curFacesComponent = cur.getAnnotation();
+ tagName = curFacesComponent.tagName();
+ // if the current entry has an explicitly declared tagName...
+ if (null != tagName && 0 < tagName.length()) {
+ // compare it to the argument tagName
+ if (localName.equals(tagName)) {
+ result = cur;
+ break;
+ }
+ } else if (null != tagName) {
+ tagName = cur.getTarget().getSimpleName();
+ tagName = tagName.substring(0, 1).toLowerCase() + tagName.substring(1);
+ if (localName.equals(tagName)) {
+ result = cur;
+ break;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public TagHandler createTagHandler(String ns, String localName, TagConfig tag) throws FacesException {
+ assert(containsTagHandler(ns, localName));
+ TagHandler result = super.createTagHandler(ns, localName, tag);
+ if (null == result) {
+ FacesComponentUsage facesComponentUsage =
+ findFacesComponentUsageForLocalName(ns, localName);
+ String componentType = facesComponentUsage.getAnnotation().value();
+ UIComponent throwAwayComponent = FacesContext.getCurrentInstance().
+ getApplication().createComponent(componentType);
+ String rendererType = throwAwayComponent.getRendererType();
+ super.addComponent(localName, componentType, rendererType);
+ result = super.createTagHandler(ns, localName, tag);
+ }
+ return result;
+ }
+
+ @Override
+ public boolean tagLibraryForNSExists(String ns) {
+ boolean result = false;
+ List<FacesComponentUsage> componentsForNamespace = appAss.getComponentsForNamespace(ns);
+
+ result = !componentsForNamespace.isEmpty();
+
+ return result;
+ }
+
+
+}
Index: jsf-ri/src/main/java/com/sun/faces/facelets/tag/CompositeTagLibrary.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/facelets/tag/CompositeTagLibrary.java (revision 9668)
+++ jsf-ri/src/main/java/com/sun/faces/facelets/tag/CompositeTagLibrary.java (working copy)
@@ -60,6 +60,8 @@
 
 import com.sun.faces.facelets.compiler.CompilationMessageHolder;
 import com.sun.faces.facelets.tag.jsf.CompositeComponentTagLibrary;
+import com.sun.faces.facelets.tag.jsf.FacesComponentTagLibrary;
+import com.sun.faces.facelets.tag.jsf.LazyTagLibrary;
 import com.sun.faces.util.Util;
 
 import javax.faces.FacesException;
@@ -108,13 +110,21 @@
             }
         }
         // PENDING: this is a terribly inefficient impl. Needs refactoring.
- CompositeComponentTagLibrary toTest = new CompositeComponentTagLibrary(ns);
- if (toTest.tagLibraryForNSExists(ns)) {
+ LazyTagLibrary lazyLibraries [] = new LazyTagLibrary[2];
+ lazyLibraries[0] = new CompositeComponentTagLibrary(ns);
+ lazyLibraries[1] = new FacesComponentTagLibrary(ns);
+ LazyTagLibrary toTest = null;
+ for (int i = 0; i < lazyLibraries.length; i++) {
+ if (lazyLibraries[i].tagLibraryForNSExists(ns)) {
+ toTest = lazyLibraries[i];
+ break;
+ }
+ }
+ if (null != toTest) {
             TagLibrary [] librariesPlusOne = new TagLibrary[libraries.length+1];
             System.arraycopy(this.libraries, 0, librariesPlusOne,
                     0, libraries.length);
- librariesPlusOne[libraries.length] =
- new CompositeComponentTagLibrary(ns);
+ librariesPlusOne[libraries.length] = toTest;
             for (int i = 0; i < this.libraries.length; i++) {
                 libraries[i] = null;
             }
Index: jsf-ri/src/main/java/com/sun/faces/application/ApplicationAssociate.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/application/ApplicationAssociate.java (revision 9668)
+++ jsf-ri/src/main/java/com/sun/faces/application/ApplicationAssociate.java (working copy)
@@ -45,6 +45,7 @@
 import com.sun.faces.application.resource.ResourceCache;
 import com.sun.faces.application.resource.ResourceManager;
 import com.sun.faces.application.annotation.AnnotationManager;
+import com.sun.faces.application.annotation.FacesComponentUsage;
 import com.sun.faces.config.ConfigManager;
 import com.sun.faces.config.WebConfiguration;
 import com.sun.faces.facelets.compiler.Compiler;
@@ -80,6 +81,7 @@
 import com.sun.faces.facelets.PrivateApiFaceletCacheAdapter;
 import com.sun.faces.lifecycle.ELResolverInitPhaseListener;
 
+import java.util.ArrayList;
 import javax.el.CompositeELResolver;
 import javax.el.ELResolver;
 import javax.el.ExpressionFactory;
@@ -106,6 +108,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 import javax.faces.FactoryFinder;
 import javax.faces.application.NavigationCase;
+import javax.faces.component.FacesComponent;
 import javax.faces.view.facelets.FaceletCacheFactory;
 import javax.faces.view.facelets.FaceletFactoryWrapper;
 import javax.faces.view.facelets.FaceletsResourceResolver;
@@ -136,6 +139,14 @@
      * card, and some may be specified as an asterisk "*".
      */
     private Map<String, Set<NavigationCase>> navigationMap = null;
+
+ /*
+ * The FacesComponentTagLibrary uses the information in this map
+ * to help it fabricate tag handlers for components annotated with
+ * FacesComponent.
+ * Key: namespace
+ */
+ private Map<String, List<FacesComponentUsage>> facesComponentsByNamespace = null;
 
     // Flag indicating that a response has been rendered.
     private boolean responseRendered = false;
@@ -533,8 +544,39 @@
     public boolean hasRequestBeenServiced() {
         return requestServiced;
     }
+
+ public void addFacesComponent(FacesComponentUsage facesComponentUsage) {
+ FacesComponent facesComponent = facesComponentUsage.getAnnotation();
+ assert(facesComponent.tagHandler());
+ if (null == facesComponentsByNamespace) {
+ facesComponentsByNamespace = new HashMap<String, List<FacesComponentUsage>>();
+ }
 
+ List<FacesComponentUsage> componentsInNamespace = null;
+ final String namespace = facesComponent.namespace();
+
+ if (!facesComponentsByNamespace.containsKey(facesComponent.namespace())) {
+ componentsInNamespace = new ArrayList<FacesComponentUsage>();
+ facesComponentsByNamespace.put(namespace, componentsInNamespace);
+ } else {
+ componentsInNamespace = facesComponentsByNamespace.get(namespace);
+ }
+ componentsInNamespace.add(facesComponentUsage);
 
+ }
+
+ public List<FacesComponentUsage> getComponentsForNamespace(String ns) {
+ List<FacesComponentUsage> result = Collections.emptyList();
+ if (null != facesComponentsByNamespace) {
+ if (facesComponentsByNamespace.containsKey(ns)) {
+ result = facesComponentsByNamespace.get(ns);
+ }
+
+ }
+
+ return result;
+ }
+
     /**
      * Add a navigation case to the internal case set. If a case set
      * does not already exist in the case list map containing this case
Index: jsf-ri/src/main/java/com/sun/faces/application/ApplicationImpl.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/application/ApplicationImpl.java (revision 9668)
+++ jsf-ri/src/main/java/com/sun/faces/application/ApplicationImpl.java (working copy)
@@ -881,7 +881,7 @@
     }
 
     /**
- * @see javax.faces.application.Application#addComponent(String, String)
+ * @see javax.faces.application.Application#addFacesComponent(String, String)
      */
     public void addComponent(String componentType, String componentClass) {
 
Index: jsf-ri/src/main/java/com/sun/faces/application/annotation/ComponentConfigHandler.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/application/annotation/ComponentConfigHandler.java (revision 9668)
+++ jsf-ri/src/main/java/com/sun/faces/application/annotation/ComponentConfigHandler.java (working copy)
@@ -40,6 +40,7 @@
 
 package com.sun.faces.application.annotation;
 
+import com.sun.faces.application.ApplicationAssociate;
 import java.lang.annotation.Annotation;
 import java.util.Collection;
 import java.util.Collections;
@@ -67,7 +68,8 @@
         HANDLES = Collections.unmodifiableCollection(handles);
     }
 
- private Map<String,String> components;
+ // key: componentId
+ private Map<String,FacesComponentUsage> components;
 
 
     // ------------------------------------- Methods from ComponentConfigHandler
@@ -89,9 +91,9 @@
     public void collect(Class<?> target, Annotation annotation) {
 
         if (components == null) {
- components = new HashMap<String,String>();
+ components = new HashMap<String,FacesComponentUsage>();
         }
- components.put(((FacesComponent) annotation).value(), target.getName());
+ components.put(((FacesComponent) annotation).value(),new FacesComponentUsage(target, (FacesComponent) annotation));
 
     }
 
@@ -103,8 +105,12 @@
 
         if (components != null) {
             Application app = ctx.getApplication();
- for (Map.Entry<String, String> entry : components.entrySet()) {
- app.addComponent(entry.getKey(), entry.getValue());
+ ApplicationAssociate appAss = ApplicationAssociate.getCurrentInstance();
+ for (Map.Entry<String, FacesComponentUsage> entry : components.entrySet()) {
+ if (entry.getValue().getAnnotation().tagHandler()) {
+ appAss.addFacesComponent(entry.getValue());
+ }
+ app.addComponent(entry.getKey(), entry.getValue().getTarget().getName());
             }
         }
 
Index: jsf-ri/src/main/java/com/sun/faces/application/annotation/FacesComponentUsage.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/application/annotation/FacesComponentUsage.java (revision 0)
+++ jsf-ri/src/main/java/com/sun/faces/application/annotation/FacesComponentUsage.java (revision 0)
@@ -0,0 +1,65 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+
+ */
+package com.sun.faces.application.annotation;
+
+import javax.faces.component.FacesComponent;
+
+public class FacesComponentUsage {
+ private Class<?> target;
+ private FacesComponent annotation;
+
+ public FacesComponentUsage(Class<?> target, FacesComponent annotation) {
+ this.target = target;
+ this.annotation = annotation;
+ }
+
+ public FacesComponent getAnnotation() {
+ return annotation;
+ }
+
+ public Class<?> getTarget() {
+ return target;
+ }
+
+
+}
+
+
Index: jsf-test/build.xml
===================================================================
--- jsf-test/build.xml (revision 9668)
+++ jsf-test/build.xml (working copy)
@@ -108,7 +108,8 @@
                     JAVASERVERFACES-2113,
                     JAVASERVERFACES-1660,
                     JAVASERVERFACES_SPEC_PUBLIC-479,
- JAVASERVERFACES_SPEC_PUBLIC-220" />
+ JAVASERVERFACES_SPEC_PUBLIC-220,
+ JAVASERVERFACES_SPEC_PUBLIC-594" />
 
     <target name="clean" depends="define.applications"
             description="">
Index: jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_htmlunit/src/main/java/com/sun/faces/test/i_spec_594_htmlunit/IssueSpec594TestCase.java
===================================================================
--- jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_htmlunit/src/main/java/com/sun/faces/test/i_spec_594_htmlunit/IssueSpec594TestCase.java (revision 0)
+++ jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_htmlunit/src/main/java/com/sun/faces/test/i_spec_594_htmlunit/IssueSpec594TestCase.java (revision 0)
@@ -0,0 +1,77 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.faces.test.i_spec_594_htmlunit;
+
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+
+import com.sun.faces.htmlunit.HtmlUnitFacesTestCase;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+
+public class IssueSpec594TestCase extends HtmlUnitFacesTestCase {
+
+ public IssueSpec594TestCase(String name) {
+ super(name);
+ }
+
+
+ /**
+ * Return the tests included in this test suite.
+ */
+ public static Test suite() {
+ return (new TestSuite(IssueSpec594TestCase.class));
+ }
+
+
+ // ------------------------------------------------------------ Test Methods
+
+ public void testBasicAppFunctionality() throws Exception {
+
+ HtmlPage page = getPage("/");
+ String pageXml = page.asXml();
+ assertTrue(pageXml.matches("(?s).*<input\\s+id=\"tagNameExplicitlyDeclared\"\\s+type=\"text\"\\s+name=\"tagNameExplicitlyDeclared\"/>.*<input\\s+id=\"myTag\"\\s+type=\"text\"\\s+name=\"myTag\"/>.*"));
+
+ assertTrue(pageXml.contains("javax.faces.ViewState"));
+ }
+
+
+}
Index: jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_htmlunit/pom.xml
===================================================================
--- jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_htmlunit/pom.xml (revision 0)
+++ jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_htmlunit/pom.xml (revision 0)
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>i_spec_594_htmlunit</artifactId>
+ <packaging>jar</packaging>
+ <name>i_spec_594_htmlunit</name>
+ <version>1.0-SNAPSHOT</version>
+
+ <dependencies>
+
+ <dependency>
+ <artifactId>htmlunit</artifactId>
+ <groupId>net.sourceforge.htmlunit</groupId>
+ <version>2.4</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.faces.extensions</groupId>
+ <artifactId>jsf-extensions-test-time</artifactId>
+ <version>2.0</version>
+ <scope>provided</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ <finalName>i_jsf_xxxx_htmlunit</finalName>
+ </build>
+
+ <repositories>
+ <repository>
+ <id>java.net</id>
+ <name>java.net</name>
+ <url>http://download.java.net/maven/2</url>
+ <layout>default</layout>
+ </repository>
+ </repositories>
+
+</project>
Index: jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java/com/sun/faces/test/i_spec_594_war/UserBean.java
===================================================================
--- jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java/com/sun/faces/test/i_spec_594_war/UserBean.java (revision 0)
+++ jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java/com/sun/faces/test/i_spec_594_war/UserBean.java (revision 0)
@@ -0,0 +1,92 @@
+package com.sun.faces.test.i_spec_594_war;
+
+import java.io.Serializable;
+import java.util.Date;
+import javax.enterprise.context.SessionScoped;
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.ValidatorException;
+import javax.inject.Named;
+
+_at_Named
+_at_SessionScoped
+public class UserBean implements Serializable {
+
+ protected String firstName = "Duke";
+ protected String lastName = "Java";
+ protected Date dob;
+ protected String sex = "Unknown";
+ protected String email;
+ protected String serviceLevel = "medium";
+
+ public UserBean() {}
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public Date getDob() {
+ return dob;
+ }
+
+ public void setDob(Date dob) {
+ this.dob = dob;
+ }
+
+ public String getSex() {
+ return sex;
+ }
+
+ public void setSex(String sex) {
+ this.sex = sex;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getServiceLevel() {
+ return serviceLevel;
+ }
+
+ public void setServiceLevel(String serviceLevel) {
+ this.serviceLevel = serviceLevel;
+ }
+
+ public void validateEmail(FacesContext context, UIComponent toValidate,
+ Object value) throws ValidatorException {
+ String emailStr = (String) value;
+ if (-1 == emailStr.indexOf("@")) {
+ FacesMessage message = new FacesMessage("Invalid email address");
+ throw new ValidatorException(message);
+ }
+ }
+
+ public String addConfirmedUser() {
+ // This method would call a database or other service and add the
+ // confirmed user information.
+ // For now, we just place an informative message in request scope
+ FacesMessage doneMessage =
+ new FacesMessage("Successfully added new user");
+ FacesContext.getCurrentInstance().addMessage(null, doneMessage);
+ return "done";
+ }
+}
+
Index: jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java/com/sun/faces/test/i_spec_594_war/components/TagNameExplicitlyDeclared.java
===================================================================
--- jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java/com/sun/faces/test/i_spec_594_war/components/TagNameExplicitlyDeclared.java (revision 0)
+++ jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java/com/sun/faces/test/i_spec_594_war/components/TagNameExplicitlyDeclared.java (revision 0)
@@ -0,0 +1,49 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+
+ */
+package com.sun.faces.test.i_spec_594_war.components;
+
+import javax.faces.component.FacesComponent;
+import javax.faces.component.html.HtmlInputText;
+
+_at_FacesComponent(value="TagNameExplicitlyDeclared", tagHandler=true, tagName="myTag")
+public class TagNameExplicitlyDeclared extends HtmlInputText {
+
+}
Index: jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java/com/sun/faces/test/i_spec_594_war/components/TagNameDerivedFromClassName.java
===================================================================
--- jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java/com/sun/faces/test/i_spec_594_war/components/TagNameDerivedFromClassName.java (revision 0)
+++ jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/java/com/sun/faces/test/i_spec_594_war/components/TagNameDerivedFromClassName.java (revision 0)
@@ -0,0 +1,49 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+
+ */
+package com.sun.faces.test.i_spec_594_war.components;
+
+import javax.faces.component.FacesComponent;
+import javax.faces.component.html.HtmlInputText;
+
+_at_FacesComponent(value="TagNameDerivedFromClassName", tagHandler=true)
+public class TagNameDerivedFromClassName extends HtmlInputText {
+
+}
Index: jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/webapp/main.xhtml
===================================================================
--- jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/webapp/main.xhtml (revision 0)
+++ jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/webapp/main.xhtml (revision 0)
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:foo="http://java.sun.com/jsf/component">
+<h:head>
+ <title>A Simple JavaServer Faces 2.0 View</title>
+</h:head>
+<h:body>
+ <h:form prependId="false">
+ First name: #{userBean.firstName} Last name: #{userBean.lastName}
+ <p><foo:tagNameDerivedFromClassName id="tagNameExplicitlyDeclared" /></p>
+ <p><foo:myTag id="myTag" /></p>
+ <p><h:commandButton value="submit" /></p>
+ </h:form>
+</h:body>
+</html>
Index: jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/webapp/WEB-INF/beans.xml
===================================================================
Index: jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/webapp/WEB-INF/web.xml
===================================================================
--- jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/webapp/WEB-INF/web.xml (revision 0)
+++ jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/src/main/webapp/WEB-INF/web.xml (revision 0)
@@ -0,0 +1,39 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<web-app version="3.0"
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
+
+ <display-name>mojarra-regression-test</display-name>
+ <description>A simple regression test to make it easier to get your bug fixed. The only reason we need a web.xml is to set the PROJECT_STAGE to Develoment. If you have a web.xml, then you need to map the FacesServlet.</description>
+
+ <context-param>
+ <description>
+ Tell the runtime where we are in the project development
+ lifecycle. Valid values are:
+ Development, UnitTest, SystemTest, or Production.
+ The runtime will display helpful hints to correct common mistakes
+ when the value is Development.
+ </description>
+ <param-name>javax.faces.PROJECT_STAGE</param-name>
+ <param-value>Development</param-value>
+ </context-param>
+
+ <!-- Faces Servlet -->
+ <servlet>
+ <servlet-name>Faces Servlet</servlet-name>
+ <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>Faces Servlet</servlet-name>
+ <url-pattern>/faces/*</url-pattern>
+ </servlet-mapping>
+
+ <welcome-file-list>
+ <welcome-file>faces/main.xhtml</welcome-file>
+ </welcome-file-list>
+
+</web-app>
Index: jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/pom.xml
===================================================================
--- jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/pom.xml (revision 0)
+++ jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/i_spec_594_war/pom.xml (revision 0)
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>com.sun.faces</groupId>
+ <artifactId>i_spec_594_war</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>war</packaging>
+ <name>${project.artifactId}</name>
+ <description>A simple project with war packaging that depends on JSF 2.1 and
+ javaee 6, in that order.</description>
+ <url>http://jsf-spec.java.net/</url>
+ <build>
+ <finalName>${project.artifactId}</finalName>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <failOnMissingWebXml>false</failOnMissingWebXml>
+ </configuration>
+ </plugin>
+
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>javax.faces-api</artifactId>
+ <version>2.2-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ <version>6.0</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
Index: jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/build.xml
===================================================================
--- jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/build.xml (revision 0)
+++ jsf-test/JAVASERVERFACES_SPEC_PUBLIC-594/build.xml (revision 0)
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+<!-- ************ JSF build file ************************************** -->
+<project name="JAVASERVERFACES-i_spec_594" default="test" basedir=".">
+
+ <property file="../../build.properties"/>
+ <path id="i_spec_594.classpath">
+ <path refid="html.classpath" />
+ <pathelement location="${basedir}/i_spec_594_htmlunit/target/classes"/>
+ </path>
+
+ <import file="${jsf.build.home}/common/ant/common.xml"/>
+
+ <target name="build">
+ <jsf.mvn dir="${basedir}/i_spec_594_war" goals="install" />
+ <jsf.mvn dir="${basedir}/i_spec_594_htmlunit" goals="install" />
+ </target>
+
+ <target name="clean">
+ <jsf.mvn dir="${basedir}/i_spec_594_htmlunit" goals="clean" />
+ <jsf.mvn dir="${basedir}/i_spec_594_war" goals="clean" />
+ </target>
+
+ <target name="install">
+ <deploy.artifact
+ artifact="${basedir}/i_spec_594_war/target/i_spec_594_war.war"
+ appName="i_spec_594_war"/>
+ </target>
+
+ <target name="remove">
+ <undeploy.artifact
+ artifact="${basedir}/i_spec_594_war/target/i_spec_594_war.war"
+ appName="i_spec_594_war"/>
+ </target>
+
+ <target name="test" depends="define.scenario.aware.port">
+
+ <jsf.junit context-path="/i_spec_594_war"
+ classpath-refid="i_spec_594.classpath"
+ test-results-dir="${regression.test.results.dir}">
+ <tests>
+ <fileset dir="${basedir}/i_spec_594_htmlunit/target/classes"
+ includes="com/sun/faces/test/i_spec_594_htmlunit/IssueSpec594TestCase.class"/>
+ </tests>
+ </jsf.junit>
+
+
+ </target>
+
+</project>
Index: nbproject/project.xml
===================================================================
--- nbproject/project.xml (revision 9668)
+++ nbproject/project.xml (working copy)
@@ -113,5 +113,8 @@
                 <source-level>1.5</source-level>
             </compilation-unit>
         </java-data>
+ <spellchecker-wordlist xmlns="http://www.netbeans.org/ns/spellchecker-wordlist/1">
+ <word>Facelet</word>
+ </spellchecker-wordlist>
     </configuration>
 </project>
Index: jsf-api/src/main/java/javax/faces/component/FacesComponent.java
===================================================================
--- jsf-api/src/main/java/javax/faces/component/FacesComponent.java (revision 9668)
+++ jsf-api/src/main/java/javax/faces/component/FacesComponent.java (working copy)
@@ -65,10 +65,28 @@
 
  */
 
+/**
+ * <p><span class="changed_modified_2_2">The</span> presence of this annotation
+ * on a class that extends {_at_link UIComponent} must cause the runtime to
+ * register this class as a component suitable for inclusion in a view.
+ * <span class="changed_added_2_2">If the <code>tagHandler</code> attribute
+ * is <code>true</code>, the runtime must create a corresponding Facelet
+ * tag handler according to the rules specified in the attributes of
+ * this annotation.</span></p>
+ *
+ */
+
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
 @Inherited
 public @interface FacesComponent {
+
+ /**
+ * <p class="changed_added_2_2">Components that declare a
+ * <code>tagHandler = true</code> attribute will be placed into this tag
+ * namespace if the namespace attribute is omitted.</p>
+ */
+ public static final String NAMESPACE = "http://java.sun.com/jsf/component";
 
     /**
      * <p class="changed_added_2_0">The value of this annotation
@@ -79,6 +97,35 @@
      */
 
     String value();
-
-
+
+ /**
+ * <p class="changed_added_2_2">If the value of this attribute is
+ * <code>true</code>, the runtime must create a Facelet tag handler,
+ * that extends from {_at_link javax.faces.view.facelets.ComponentHandler},
+ * suitable for use in pages under the tag library with namespace given
+ * by the value of the {_at_link #namespace} attribute.</p>
+ */
+
+ boolean tagHandler() default false;
+
+ /**
+ * <p class="changed_added_2_2">If the value of the {_at_link #tagHandler}
+ * attribute is <code>true</code>, the runtime must use this
+ * value as the tag name for including an instance of the component
+ * annotated with this annotation in a view. If this attribute is not
+ * specified on a usage of this annotation, the simple name of the
+ * class on which this annotation is declared, with the first character
+ * lowercased, is taken to be the value.</p>
+ */
+ String tagName() default "";
+
+ /**
+ * <p class="changed_added_2_2">If the value of the {_at_link #tagHandler}
+ * attribute is <code>true</code>, the value of this attribute is taken
+ * to be the tag library namespace into which this component is placed.</p>
+ *
+ */
+
+ String namespace() default NAMESPACE;
+
 }


SECTION: New Files
----------------------------
SEE ATTACHMENTS


[1] http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-594
-- 
| edward.burns_at_oracle.com | office: +1 407 458 0017
| homepage:               | http://ridingthecrest.com/