Merging the following plugin chagnes to 2.x plugin branch:
TRINIDAD-1583
TRINIDAD-1677
TRINIDAD-1679
diff --git a/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/AbstractTagBean.java b/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/AbstractTagBean.java
index 6ab3454..39aa5f8 100644
--- a/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/AbstractTagBean.java
+++ b/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/AbstractTagBean.java
@@ -18,23 +18,26 @@
*/
package org.apache.myfaces.trinidadbuild.plugin.faces.parse;
-import javax.xml.namespace.QName;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.LinkedHashMap;
import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import javax.xml.namespace.QName;
public class AbstractTagBean extends ObjectBean {
- private String _description;
- private String _longDescription;
- private QName _tagName;
- private String _tagClass;
- protected Map _properties;
- private int _tagClassModifiers;
- private Map _examples;
- private int _exampleIdx = 0;
- private Map _screenshots;
- private int _screenshotIdx = 0;
+ private List<String> _accessibilityGuidelines = new ArrayList<String>();
+ private String _description;
+ private String _longDescription;
+ private QName _tagName;
+ private String _tagClass;
+ protected Map _properties;
+ private int _tagClassModifiers;
+ private Map _examples;
+ private int _exampleIdx = 0;
+ private Map _screenshots;
+ private int _screenshotIdx = 0;
public AbstractTagBean()
{
@@ -273,6 +276,40 @@
return _screenshots.values().iterator();
}
+ /**
+ * Adds an Accessibility (e.g. section 508 compliance) Guideline to this component. The
+ * accessibility guidelines are used during tag doc generation to give the application
+ * developer hints on how to configure the component to be accessibility-compliant.
+ *
+ * @param accessibilityGuideline the accessibility guideline to add
+ */
+ public void addAccessibilityGuideline(
+ String accessibilityGuideline)
+ {
+ _accessibilityGuidelines.add(accessibilityGuideline);
+ }
+
+ /**
+ * Returns true if this component has any accessibility guidelines.
+ *
+ * @return true if this component has any accessibility guidelines,
+ * false otherwise
+ */
+ public boolean hasAccessibilityGuidelines()
+ {
+ return !_accessibilityGuidelines.isEmpty();
+ }
+
+ /**
+ * Returns an iterator for all accessibility guidelines on this component only.
+ *
+ * @return the accessibility guidelines iterator
+ */
+ public Iterator<String> accessibilityGuidelines()
+ {
+ return _accessibilityGuidelines.iterator();
+ }
+
public void parseTagClassModifier(
String modifier)
{
diff --git a/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/AccessibilityGuidelineBean.java b/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/AccessibilityGuidelineBean.java
new file mode 100644
index 0000000..fc6f708
--- /dev/null
+++ b/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/AccessibilityGuidelineBean.java
@@ -0,0 +1,98 @@
+/*
+ * 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.trinidadbuild.plugin.faces.parse;
+
+/**
+ * AccessibilityGuidelineBean is a Java representation of the faces-config mfp:accessibilityGuidelines
+ * XML element.
+ * An example of how the AccessibilityGuidelineBean would be represented as an XML element is:
+ * <mfp:accessibilityGuideline>
+ * <mfp:type>required</mfp:type>
+ * <mfp:description>
+ * Title attribute must be set in order for a screenreader user to identify the purpose of the popup dialog.
+ * </mfp:description>
+ * </mfp:accessibilityGuideline>
+ */
+public class AccessibilityGuidelineBean extends ObjectBean
+{
+ /**
+ * Get Description Text. The description text for the accessibility guideline.
+ *
+ * @return Accessibility Guideline Description Text
+ */
+ public String getDescription()
+ {
+ return _description;
+ }
+
+ /**
+ * Set accessibility guideline Description Text.
+ *
+ * @param description Accessibility Guideline Description Text.
+ */
+ public void setDescription( String description )
+ {
+ _description = description;
+ }
+
+ /**
+ * Returns the type of the Accessibility Guideline (e.g. required, suggested, discouraged).
+ *
+ * @return type of Accessibility Guideline
+ */
+ public String getType()
+ {
+ return _type;
+ }
+
+ /**
+ * Set if element is required to meet Accessibility Guidelines
+ *
+ * @param required whether or not the element is required to meet accessibility guidelines
+ */
+ public void setType( String type )
+ {
+ _type = type;
+ }
+
+ /**
+ * Returns AccessibilityGuideline hashmap key.
+ *
+ * @return AccessibilityGuideline hashmap key
+ */
+ public String getKey()
+ {
+ return _key;
+ }
+
+ /**
+ * Set hashmap key for this accessibility guideline.
+ *
+ * @param key Set key for this accessibility guideline put in
+ * ComponentBean _accessibilityGuidelines hashmap.
+ */
+ protected void setKey( String key )
+ {
+ _key = key;
+ }
+
+ private String _description = null;
+ private String _type = null;
+ private String _key = null;
+}
diff --git a/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/AttributeBean.java b/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/AttributeBean.java
index ecf3159..3b07a54 100644
--- a/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/AttributeBean.java
+++ b/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/AttributeBean.java
@@ -18,9 +18,12 @@
*/
package org.apache.myfaces.trinidadbuild.plugin.faces.parse;
+import java.lang.Comparable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.lang.Comparable;
/**
* AttributeBean is a Java representation of the faces-config component or
@@ -177,6 +180,40 @@
}
/**
+ * Adds an Accessibility (e.g. section 508 compliance) Guideline to this attribute. The
+ * accessibility guidelines are used during tag doc generation to give the application
+ * developer hints on how to configure the attribute to be accessibility-compliant.
+ *
+ * @param accessibilityGuideline the accessibility guideline to add
+ */
+ public void addAccessibilityGuideline(
+ String accessibilityGuideline)
+ {
+ _accessibilityGuidelines.add(accessibilityGuideline);
+ }
+
+ /**
+ * Returns true if this attribute has any accessibility guidelines.
+ *
+ * @return true if this component has any accessibility guidelines,
+ * false otherwise
+ */
+ public boolean hasAccessibilityGuidelines()
+ {
+ return !_accessibilityGuidelines.isEmpty();
+ }
+
+ /**
+ * Returns an iterator for all accessibility guidelines on this component only.
+ *
+ * @return the accessibility guidelines iterator
+ */
+ public Iterator<String> accessibilityGuidelines()
+ {
+ return _accessibilityGuidelines.iterator();
+ }
+
+ /**
* Sets the virtual flag of this property.
*
* @param virtual the property required flag
@@ -219,6 +256,7 @@
private String _alternateClass;
private boolean _virtual;
private MethodSignatureBean _signature;
+ private List<String> _accessibilityGuidelines = new ArrayList<String>();
static private final Pattern _GENERIC_TYPE = Pattern.compile("([^<]+)<(.+)>");
static private final String[] _EMPTY_ARRAY = new String[0];
diff --git a/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/ComponentBean.java b/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/ComponentBean.java
index 9d17ae3..0e8b45e 100644
--- a/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/ComponentBean.java
+++ b/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/ComponentBean.java
@@ -20,9 +20,12 @@
import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
@@ -759,6 +762,147 @@
}
/**
+ * Parses the string of satisfied contracts into a String array
+ * using space as the separator between values.
+ * In the component metadata file, the satisfied contracts are noted
+ * with satisfied-contracts markup. As an example, af:popup
+ * (oracle.adf.view.rich.component.rich.RichPopup) supports
+ * oracle-adf-richmenu-holder, oracle-adf-richdialog-holder,
+ * oracle-adf-richnotewindow-holder, and oracle-adf-richpanelwindow-holder
+ * contracts. The satisfied contracts of a given component are matched
+ * with the required ancestor contracts of other components to determine
+ * if a component hierarchy is legally assembled.
+ *
+ * @param satisfiedContracts a space delimited string of satisifed contracts
+ */
+ public void parseSatisfiedContracts(
+ String satisfiedContracts)
+ {
+ setSatisfiedContracts(satisfiedContracts.split(" "));
+ }
+
+ /**
+ * Sets the possible values for this property.
+ * In the component metadata file, the satisfied contracts are noted
+ * with satisfied-contracts markup. As an example, af:popup
+ * (oracle.adf.view.rich.component.rich.RichPopup) supports
+ * oracle-adf-richmenu-holder, oracle-adf-richdialog-holder,
+ * oracle-adf-richnotewindow-holder, and oracle-adf-richpanelwindow-holder
+ * contracts. The satisfied contracts of a given component are matched
+ * with the required ancestor contracts of other components to determine
+ * if a component hierarchy is legally assembled.
+ *
+ * @param satisfiedContracts a string array of the satisfied contracts
+ */
+ public void setSatisfiedContracts(
+ String[] satisfiedContracts)
+ {
+ _satisfiedContracts = Arrays.asList(satisfiedContracts);
+ }
+
+ /**
+ * Returns an iterator of the satisfied contracts for this component.
+ * In the component metadata file, the satisfied contracts are noted
+ * with satisfied-contracts markup. As an example, af:popup
+ * (oracle.adf.view.rich.component.rich.RichPopup) supports
+ * oracle-adf-richmenu-holder, oracle-adf-richdialog-holder,
+ * oracle-adf-richnotewindow-holder, and oracle-adf-richpanelwindow-holder
+ * contracts. The satisfied contracts of a given component are matched
+ * with the required ancestor contracts of other components to determine
+ * if a component hierarchy is legally assembled.
+ *
+ * @return a java.util.Iterator of Strings, where each string is the name of a
+ * satisfied contract
+ */
+ public Iterator<String> satisfiedContracts()
+ {
+ return _satisfiedContracts.iterator();
+ }
+
+ /**
+ * Returns true if this component has any satisfied contracts.
+ *
+ * @return true if this component has any satisfied contracts,
+ * false otherwise
+ */
+ public boolean hasSatisfiedContracts()
+ {
+ return (!_satisfiedContracts.isEmpty());
+ }
+
+ /**
+ * Parses the string of required ancestor contracts into a String array
+ * using space as the separator between values.
+ * In the component metadata file, the required ancestors are noted
+ * with required-ancestor-contracts markup. This indicates that an
+ * ancestor (e.g. parent or grandparent) tag must be have satisfied-contracts
+ * metadata matching the required-ancestor-contracts metadata of this tag.
+ * As an example, af:dialog
+ * (oracle.adf.view.rich.component.rich.RichDialog) lists
+ * oracle-adf-richdialog-holder as a required ancestor contract, and
+ * af:popup (oracle.adf.view.rich.component.rich.RichPopup) lists
+ * oracle-adf-richdialog-holder as a satisified contract.
+ *
+ * @param requiredAncestorContracts a space delimited string of required ancestor contracts
+ */
+ public void parseRequiredAncestorContracts(
+ String requiredAncestorContracts)
+ {
+ setRequiredAncestorContracts(requiredAncestorContracts.split(" "));
+ }
+
+ /**
+ * Sets the possible values for this property.
+ * In the component metadata file, the required ancestors are noted
+ * with required-ancestor-contracts markup. This indicates that an
+ * ancestor (e.g. parent or grandparent) tag must be have satisfied-contracts
+ * metadata matching the required-ancestor-contracts metadata of this tag.
+ * As an example, af:dialog
+ * (oracle.adf.view.rich.component.rich.RichDialog) lists
+ * oracle-adf-richdialog-holder as a required ancestor contract, and
+ * af:popup (oracle.adf.view.rich.component.rich.RichPopup) lists
+ * oracle-adf-richdialog-holder as a satisified contract.
+ *
+ * @param requiredAncestorContracts a string array of the required ancestor contracts
+ */
+ public void setRequiredAncestorContracts(
+ String[] requiredAncestorContracts)
+ {
+ _requiredAncestorContracts = Arrays.asList(requiredAncestorContracts);
+ }
+
+ /**
+ * Returns the required ancestor contracts for this component.
+ * In the component metadata file, the required ancestors are noted
+ * with required-ancestor-contracts markup. This indicates that an
+ * ancestor (e.g. parent or grandparent) tag must be have satisfied-contracts
+ * metadata matching the required-ancestor-contracts metadata of this tag.
+ * As an example, af:dialog
+ * (oracle.adf.view.rich.component.rich.RichDialog) lists
+ * oracle-adf-richdialog-holder as a required ancestor contract, and
+ * af:popup (oracle.adf.view.rich.component.rich.RichPopup) lists
+ * oracle-adf-richdialog-holder as a satisified contract.
+ *
+ * @return a java.util.Iterator of strings, where each string is the name
+ * of a required ancestor contract
+ */
+ public Iterator<String> requiredAncestorContracts()
+ {
+ return _requiredAncestorContracts.iterator();
+ }
+
+ /**
+ * Returns true if this component has any required ancestor contracts.
+ *
+ * @return true if this component has any required ancestor contracts,
+ * false otherwise
+ */
+ public boolean hasRequiredAncestorContracts()
+ {
+ return (!_requiredAncestorContracts.isEmpty());
+ }
+
+ /**
* Adds a Java Language class modifier to the tag class.
*
* @param modifier the modifier to be added
@@ -1085,6 +1229,9 @@
private int _componentClassModifiers;
private int _tagClassModifiers;
private String[] _unsupportedAgents = new String[0];
+ private List<String> _requiredAncestorContracts = new ArrayList<String>();
+ private List<String> _satisfiedContracts = new ArrayList<String>();
+
private String[] _eventNames;
static private final String _TRINIDAD_COMPONENT_BASE =
diff --git a/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/FacesConfigParser.java b/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/FacesConfigParser.java
index 99bc23c..aeee69d 100644
--- a/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/FacesConfigParser.java
+++ b/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/FacesConfigParser.java
@@ -132,6 +132,11 @@
// faces-config/component/facet/facet-extension
digester.addBeanPropertySetter("faces-config/component/facet/facet-extension/hidden");
+ // faces-config/component/facet/facet-extension/facet-metadata/accessibility-guideline
+ digester.addCallMethod("faces-config/component/facet/facet-extension/facet-metadata/accessibility-guideline",
+ "addAccessibilityGuideline", 1);
+ digester.addCallParam("faces-config/component/facet/facet-extension/facet-metadata/accessibility-guideline", 0);
+
// faces-config/component/facet/example
digester.addObjectCreate("faces-config/component/facet/example",
ExampleBean.class);
@@ -182,6 +187,11 @@
digester.addBeanPropertySetter("faces-config/component/component-extension/uix2-node-class",
"nodeClass");
+ // faces-config/component/component-extension/accessibility-guideline
+ digester.addCallMethod("faces-config/component/component-extension/accessibility-guideline",
+ "addAccessibilityGuideline", 1);
+ digester.addCallParam("faces-config/component/component-extension/accessibility-guideline", 0);
+
// faces-config/component/component-extension/example
digester.addObjectCreate("faces-config/component/component-extension/example",
ExampleBean.class);
@@ -223,6 +233,21 @@
"parseEventNames", 1);
digester.addCallParam("faces-config/component/component-extension/component-metadata/event-names", 0);
+ // faces-config/component/facet/facet-extension/facet-metadata/allowed-child-components
+ digester.addCallMethod("faces-config/component/facet/facet-extension/facet-metadata/allowed-child-components",
+ "parseAllowedChildComponents", 1);
+ digester.addCallParam("faces-config/component/facet/facet-extension/facet-metadata/allowed-child-components", 0);
+
+ // faces-config/component/component-extension/component-metadata/required-ancestor-contracts
+ digester.addCallMethod("faces-config/component/component-extension/component-metadata/required-ancestor-contracts",
+ "parseRequiredAncestorContracts", 1);
+ digester.addCallParam("faces-config/component/component-extension/component-metadata/required-ancestor-contracts", 0);
+
+ // faces-config/component/component-extension/component-metadata/satisfied-contracts
+ digester.addCallMethod("faces-config/component/component-extension/component-metadata/satisfied-contracts",
+ "parseSatisfiedContracts", 1);
+ digester.addCallParam("faces-config/component/component-extension/component-metadata/satisfied-contracts", 0);
+
// XInclude rules
digester.setRuleNamespaceURI(XIncludeFilter.XINCLUDE_NAMESPACE);
digester.addFactoryCreate("faces-config/component/include",
@@ -294,12 +319,18 @@
digester.addSetNext("faces-config/component/property/property-extension/method-binding-signature",
"setMethodBindingSignature",
MethodSignatureBean.class.getName());
- // faces-config/component/property/property-extension/property-metada
+
+ // faces-config/component/property/property-extension/property-metadata
digester.addBeanPropertySetter("faces-config/component/property/property-extension/property-metadata/use-max-time",
"useMaxTime");
digester.addBeanPropertySetter("faces-config/component/property/property-extension/property-metadata/deprecated");
digester.addCallMethod("faces-config/component/property/property-extension/property-metadata/no-op", "makeNoOp");
+ // faces-config/component/property/property-extension/property-metadata/accessibility-guideline
+ digester.addCallMethod("faces-config/component/property/property-extension/property-metadata/accessibility-guideline",
+ "addAccessibilityGuideline", 1);
+ digester.addCallParam("faces-config/component/property/property-extension/property-metadata/accessibility-guideline", 0);
+
// jsr-276 metadata rules
digester.setRuleNamespaceURI("http://java.sun.com/xml/ns/javaee/faces/design-time-metadata");
digester.addCallMethod("faces-config/component/property/property-extension/property-metadata/property-values",
diff --git a/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/FacetBean.java b/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/FacetBean.java
index c9cbf05..b01fc48 100644
--- a/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/FacetBean.java
+++ b/maven-faces-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/faces/parse/FacetBean.java
@@ -18,6 +18,11 @@
*/
package org.apache.myfaces.trinidadbuild.plugin.faces.parse;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
/**
* FacetBean is a Java representation of the faces-config component or
* renderer facet XML element.
@@ -104,9 +109,110 @@
{
this._hidden = hidden;
}
+
+ /**
+ * Adds an Accessibility (e.g. section 508 compliance) Guideline to this facet. The
+ * accessibility guidelines are used during tag doc generation to give the application
+ * developer hints on how to configure the facet to be accessibility-compliant.
+ *
+ * @param accGuidelines the accessibility guideline to add
+ */
+ public void addAccessibilityGuideline(
+ String accessibilityGuideline)
+ {
+ _accessibilityGuidelines.add(accessibilityGuideline);
+ }
- private String _description;
- private String _facetName;
- private boolean _required;
- private boolean _hidden;
+ /**
+ * Returns true if this component has any accessibility guidelines.
+ *
+ * @return true if this component has any accessibility guidelines,
+ * false otherwise
+ */
+ public boolean hasAccessibilityGuidelines()
+ {
+ return !_accessibilityGuidelines.isEmpty();
+ }
+
+ /**
+ * Returns an iterator for all accessibility guidelines on this component only.
+ *
+ * @return the accessibility guidelines iterator
+ */
+ public Iterator<String> accessibilityGuidelines()
+ {
+ return _accessibilityGuidelines.iterator();
+ }
+
+ /**
+ * Parses the string of allowed child class names into a String array
+ * using space as the separator between values.
+ * In the component metadata file, the allowed child components
+ * are denoted with allowed-child-components markup. As an example,
+ * oracle.adf.RichMenu is an allowed child component of
+ * af:panelCollection's (oracle.adf.view.rich.component.rich.output.RichPanelCollection)
+ * menu facet. The allowed child components of one component are matched with the
+ * component type attribute of other components to determine which child tags
+ * are allowed in the component hierarchy.
+ *
+ * @param allowedChildComponents a space delimited string of allowed child component class names
+ */
+ public void parseAllowedChildComponents(
+ String allowedChildComponents)
+ {
+ setAllowedChildComponents(allowedChildComponents.split(" "));
+ }
+
+ /**
+ * Sets the possible values for this property.
+ * In the component metadata file, the allowed child components
+ * are denoted with allowed-child-components markup. As an example,
+ * oracle.adf.RichMenu is an allowed child component of
+ * af:panelCollection's (oracle.adf.view.rich.component.rich.output.RichPanelCollection)
+ * menu facet. The allowed child components of one component are matched with the
+ * component type attribute of other components to determine which child tags
+ * are allowed in the component hierarchy.
+ *
+ * @param allowedChildComponents a string array of the allowed child component class names
+ */
+ public void setAllowedChildComponents(
+ String[] allowedChildComponents)
+ {
+ _allowedChildComponents = Arrays.asList(allowedChildComponents);
+ }
+
+ /**
+ * Returns the allowed child components for this facet.
+ * In the component metadata file, the allowed child components
+ * are denoted with allowed-child-components markup. As an example,
+ * oracle.adf.RichMenu is an allowed child component of
+ * af:panelCollection's (oracle.adf.view.rich.component.rich.output.RichPanelCollection)
+ * menu facet. The allowed child components of one component are matched with the
+ * component type attribute of other components to determine which child tags
+ * are allowed in the component hierarchy.
+ *
+ * @return an iterator of allowed child component class name strings
+ */
+ public Iterator<String> allowedChildComponents()
+ {
+ return (_allowedChildComponents.iterator());
+ }
+
+ /**
+ * Returns true if this component has any allowed child components.
+ *
+ * @return true if this component has any allowed child components,
+ * false otherwise
+ */
+ public boolean hasAllowedChildComponents()
+ {
+ return (!_allowedChildComponents.isEmpty());
+ }
+
+ private String _description;
+ private String _facetName;
+ private boolean _required;
+ private boolean _hidden;
+ private List<String> _accessibilityGuidelines = new ArrayList<String>();
+ private List<String> _allowedChildComponents = new ArrayList<String>();
}
diff --git a/maven-faces-plugin/src/main/resources/org/apache/myfaces/trinidadbuild/plugin/faces/resources/transform12.xsl b/maven-faces-plugin/src/main/resources/org/apache/myfaces/trinidadbuild/plugin/faces/resources/transform12.xsl
index 8b0f500..08cfef7 100644
--- a/maven-faces-plugin/src/main/resources/org/apache/myfaces/trinidadbuild/plugin/faces/resources/transform12.xsl
+++ b/maven-faces-plugin/src/main/resources/org/apache/myfaces/trinidadbuild/plugin/faces/resources/transform12.xsl
@@ -1042,6 +1042,7 @@
</xsl:template>
<!-- Blacklisted mfp: that should not be copied over into the faces-config.xml: -->
+ <xsl:template match="//mfp:accessibility-guideline" />
<xsl:template match="//mfp:alternate-class" />
<xsl:template match="//mfp:author" />
<xsl:template match="//mfp:component-metadata/mfp:group" />
diff --git a/maven-tagdoc-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/tagdoc/TagdocReport.java b/maven-tagdoc-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/tagdoc/TagdocReport.java
index 417503d..e4d1a48 100644
--- a/maven-tagdoc-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/tagdoc/TagdocReport.java
+++ b/maven-tagdoc-plugin/src/main/java/org/apache/myfaces/trinidadbuild/plugin/tagdoc/TagdocReport.java
@@ -34,6 +34,7 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -121,12 +122,73 @@
return;
}
-
- Iterator components = facesConfig.components();
+ // Need to cycle through the components two times, hence need two iterators.
+ // components Iterator will be used when actually writing out the tag doc
+ // compIter Iterator will be used when creating the maps of component relationships
+ Iterator<ComponentBean> components = facesConfig.components();
components = new FilteredIterator(components, new SkipFilter());
components = new FilteredIterator(components, new ComponentTagFilter());
components = new FilteredIterator(components, new ComponentNamespaceFilter());
+ Iterator<ComponentBean> compIter = facesConfig.components();
+ compIter = new FilteredIterator(compIter, new SkipFilter());
+ compIter = new FilteredIterator(compIter, new ComponentTagFilter());
+ compIter = new FilteredIterator(compIter, new ComponentNamespaceFilter());
+
+ // compTypeMap holds a map of compononent types to tag names that implement that component type
+ // The map is built using getComponentType method on the component bean to determine the
+ // component type of a given tag name
+ Map<String, List<QName>> compTypeMap = new HashMap<String, List<QName>> ();
+ // contractMap holds a map of contract name to tag names that satisify that contract.
+ // The map is built using the getSatisfiedContracts method API on the component bean to determine
+ // which contracts are satisfied for a given tagname
+ Map<String, List<QName>> contractMap = new HashMap<String, List<QName>>();
+ while (compIter.hasNext())
+ {
+ ComponentBean compBean = compIter.next();
+ List<QName> tagNames;
+ String compType = compBean.getComponentType();
+ if (compType != null &&
+ compTypeMap.containsKey (compType) &&
+ compBean.getTagName() != null)
+ {
+ // the component type map already contains an entry for this component type
+ tagNames = compTypeMap.get(compType);
+ }
+ else
+ {
+ // the component type map does not contain an entry for this component type
+ // so create a new ArrayList that will be used to store the tag names of
+ // component that have this component type
+ tagNames = new ArrayList<QName>();
+ }
+ tagNames.add(compBean.getTagName());
+ compTypeMap.put (compType, tagNames);
+
+ if (compBean.hasSatisfiedContracts())
+ {
+ Iterator<String> satContractsIter = compBean.satisfiedContracts();
+ while (satContractsIter.hasNext())
+ {
+ String satContract = satContractsIter.next();
+ if (contractMap.containsKey (satContract))
+ {
+ // the contract map already contains an entry for this contract
+ tagNames = contractMap.get(satContract);
+ }
+ else
+ {
+ // the contract map does not contain an entry for this contract, so
+ // create a new ArrayList which will be used to store the tag names of
+ // components that satisfy this contract
+ tagNames = new ArrayList<QName>();
+ }
+ tagNames.add(compBean.getTagName());
+ contractMap.put (satContract, tagNames);
+ }
+ }
+ }
+
Iterator validators = facesConfig.validators();
validators = new FilteredIterator(validators, new ValidatorTagFilter());
validators = new FilteredIterator(validators, new ValidatorNamespaceFilter());
@@ -153,7 +215,7 @@
int count = 0;
while (components.hasNext())
{
- String pageName = _generateComponentDoc((ComponentBean)components.next());
+ String pageName = _generateComponentDoc((ComponentBean)components.next(), compTypeMap, contractMap);
if (pageName != null)
{
componentPages.add(pageName);
@@ -252,6 +314,53 @@
return set;
}
+ private String _formatTagList(
+ Iterator<String> strIter,
+ Map <String, List<QName>> pMap,
+ String header)
+ {
+ String formatted = null;
+
+ // Don't know how long this will be, but 300 should be plenty.
+ StringBuffer sb = new StringBuffer(300);
+ sb.append("\n");
+ sb.append("<b>");
+ sb.append(header);
+ sb.append(":</b> ");
+
+ boolean gotOne = false;
+ while (strIter.hasNext())
+ {
+ List<QName> tagNameList = pMap.get(strIter.next());
+ if (tagNameList != null && !tagNameList.isEmpty())
+ {
+ Iterator<QName> tagNameIter = tagNameList.iterator();
+
+ while (tagNameIter.hasNext())
+ {
+ QName tagName = tagNameIter.next();
+
+ String tagdocURL = _platformAgnosticPath("../tagdoc/" +
+ _toPageName(tagName) + ".html");
+ sb.append("<a href=\"" + tagdocURL + "\">");
+ sb.append(_getQualifiedName(tagName));
+ sb.append("</a>");
+ if (gotOne)
+ {
+ sb.append(", ");
+ }
+ gotOne = true;
+ }
+ }
+ if (gotOne)
+ {
+ sb.append("<br/>\n");
+ formatted = sb.toString();
+ }
+ }
+ return formatted;
+ }
+
private String _formatPropList(
String[] pList,
String header)
@@ -378,7 +487,7 @@
return "unknown";
}
- private String _generateComponentDoc(ComponentBean component)
+ private String _generateComponentDoc(ComponentBean component, Map<String, List<QName>> compTypeMap, Map <String, List<QName>> contractMap)
throws Exception
{
if (component.getTagName() == null)
@@ -406,7 +515,7 @@
out.write(" <section name=\"Summary\">\n");
out.write(" <p>\n");
- _writeComponentSummary(out, component);
+ _writeComponentSummary(out, component, contractMap);
out.write(" </p>\n");
out.write(" </section>\n");
@@ -414,6 +523,8 @@
_writeExamples(out, component);
+ _writeAccessibilityGuidelines(out, component);
+
if (component.isClientBehaviorHolder())
{
out.write(" <section name=\"Supported Client Events for Client Behaviors\">\n");
@@ -436,7 +547,7 @@
{
out.write(" <section name=\"Supported Facets\">\n");
out.write(" <p>\n");
- _writeComponentFacets(out, component);
+ _writeComponentFacets(out, component, compTypeMap);
out.write(" </p>\n");
out.write(" </section>\n");
}
@@ -558,7 +669,7 @@
return pageName;
}
- private void _writeComponentSummary(Writer out, ComponentBean bean) throws IOException
+ private void _writeComponentSummary(Writer out, ComponentBean bean, Map <String, List<QName>> contractMap) throws IOException
{
out.write(" <b>Tag name:</b> <" +
_getQualifiedName(bean.getTagName()) + ">\n");
@@ -577,6 +688,14 @@
out.write(" <b>Component type:</b> " + bean.getComponentType() + "\n");
out.write(" <br/>\n");
+ if (bean.hasRequiredAncestorContracts())
+ {
+ String formattedAncestors = _formatTagList ( bean.requiredAncestorContracts(),
+ contractMap,
+ "Required Ancestor Tag");
+ out.write (formattedAncestors);
+ }
+
if (_isNamingContainer(bean))
{
out.write(" <p><b>Naming container:</b> Yes. When referring to children of this " +
@@ -901,6 +1020,14 @@
{
String valStr = _formatPropList(attr.getPropertyValues(),
"Valid Values");
+
+ // The default value for the attribute. defaultValueStr will be null if no
+ // default value is specified via <default-value> in component xml file.
+ // Since _formatPropList takes an array as the first input param, covert the default
+ // value into a single item array when calling formatPropList
+ String defaultValueStr = _formatPropList (new String[] { attr.getDefaultValue() },
+ "Default Value");
+
String unsupAgentsStr =
_formatPropList(attr.getUnsupportedAgents(),
"Not supported on the following agents",
@@ -924,6 +1051,17 @@
if (valStr != null)
{
out.write(valStr);
+ }
+
+ if (defaultValueStr != null)
+ {
+ out.write(defaultValueStr);
+ }
+
+ // if we print out a list of possible values and/or a default value for the attribute,
+ // then enter a line break before printing out other information about the attribute.
+ if (valStr != null || defaultValueStr != null)
+ {
out.write("<br/>");
}
@@ -1067,14 +1205,14 @@
}
- private void _writeComponentFacets(Writer out, ComponentBean bean) throws IOException
+ private void _writeComponentFacets(Writer out, ComponentBean bean, Map<String, List<QName>> compTypeMap) throws IOException
{
// Sort the facets
TreeSet facetNames = new TreeSet();
- Iterator iter = bean.facets(true);
+ Iterator<FacetBean> iter = bean.facets(true);
while (iter.hasNext())
{
- FacetBean facetBean = (FacetBean)iter.next();
+ FacetBean facetBean = iter.next();
if (!facetBean.isHidden())
{
facetNames.add(facetBean.getFacetName());
@@ -1087,14 +1225,22 @@
out.write("<th>Description</th>\n");
out.write("</tr>\n");
- Iterator nameIter = facetNames.iterator();
+ Iterator<String> nameIter = facetNames.iterator();
while (nameIter.hasNext())
{
- String name = (String) nameIter.next();
+ String name = nameIter.next();
FacetBean facet = bean.findFacet(name, true);
out.write("<tr>\n");
out.write("<td>" + facet.getFacetName() + "</td>");
out.write("<td>");
+
+ if (facet.hasAllowedChildComponents())
+ {
+ String formattedChildComps = _formatTagList (facet.allowedChildComponents(), compTypeMap, "Allowed Child Components");
+ out.write (formattedChildComps);
+ out.write("<br/>");
+ }
+
out.write(facet.getDescription());
out.write("</td>\n");
out.write("</tr>\n");
@@ -1206,6 +1352,145 @@
out.write(" </section>\n");
}
+ // Write out the accessibility Guidelines for the component. Accessibility Guidelines
+ // help the application developer to create an application that can be used by users that e.g.
+ // use a screen reader (e.g JAWS). Oftentimes, in order to be accessibility compliant (e.g. section 508
+ // compliant) an application developer needs to specify metadata for the screenreader application
+ // to be able to correctly interpret the application for the blind user. The accessibility guideline
+ // can be associated with the Component itself, with a specific attribute of the component
+ // or with a specific facet of the component. All accessibility guidelines are printed out
+ // together in an "Accessibility Guidelines" section, with the component-generic guidelines
+ // listed first, followed by the attribute specific guidelines and finally the facet-specific
+ // guidelines
+ private void _writeAccessibilityGuidelines(Writer out, ComponentBean bean) throws IOException
+ {
+ // accAttributes and accFacets are sorted lists of attributes and facets, respectively,
+ // that have an associated accessibility guideline
+ TreeSet<PropertyBean> accAttributes = new TreeSet<PropertyBean>();
+ TreeSet<String> accFacets = new TreeSet<String>();
+
+ // see if any of the component's properties has an associated accessibility guideline
+ Iterator<PropertyBean> attrs = bean.properties();
+ while (attrs.hasNext())
+ {
+ PropertyBean property = attrs.next();
+ if (!property.isTagAttributeExcluded() && property.hasAccessibilityGuidelines())
+ {
+ accAttributes.add(property);
+ }
+ }
+
+ // see if any of the component's facets has an associated accessibility guideline
+ if (bean.hasFacets())
+ {
+ Iterator<FacetBean> facets = bean.facets(true);
+ while (facets.hasNext())
+ {
+ FacetBean facetBean = facets.next();
+ if (!facetBean.isHidden() && facetBean.hasAccessibilityGuidelines())
+ {
+ accFacets.add(facetBean.getFacetName());
+ }
+ }
+ }
+
+ // if neither the component nor the component's attributes nor the component's facets
+ // has an accessibility guideline, return
+ if (!bean.hasAccessibilityGuidelines() && accAttributes.isEmpty() && accFacets.isEmpty())
+ return;
+
+ String accGuideline;
+
+ // Write header
+ out.write(" <section name=\"Accessibility Guideline(s)\">\n");
+ out.write(" <p>\n");
+ out.write(" <html>\n");
+ out.write(" <ul>");
+
+ // write out component-generic accessibility guidelines, i.e. accessibility
+ // guidelines that apply to the component as a whole, not associated with a
+ // specific attribute
+ if (bean.hasAccessibilityGuidelines())
+ {
+ Iterator iter = bean.accessibilityGuidelines();
+ while (iter.hasNext())
+ {
+ accGuideline = (String) iter.next();
+ _writeAccessibilityGuideline(out, "", accGuideline);
+ }
+ }
+
+ // Write out attribute-specific accessibility guidelines. Each attribute can have
+ // one or more associated accessibility guidelines.
+ if (!accAttributes.isEmpty())
+ {
+ Iterator<PropertyBean> propIter = accAttributes.iterator();
+ while (propIter.hasNext())
+ {
+ PropertyBean property = propIter.next();
+ Iterator<String> propAccIter = property.accessibilityGuidelines();
+ while (propAccIter.hasNext())
+ {
+ accGuideline = propAccIter.next();
+ _writeAccessibilityGuideline(out, property.getPropertyName() + " attribute", accGuideline);
+ }
+ }
+ }
+
+ // Write out facet-specific accessibility guidelines. A facet in the accFacets iterator
+ // can have one or more associated accessibility guidelines
+ if (!accFacets.isEmpty())
+ {
+ Iterator<String> facetIter = accFacets.iterator();
+ while (facetIter.hasNext())
+ {
+ String facetName = facetIter.next();
+ FacetBean facet = bean.findFacet(facetName, true);
+
+ Iterator<String> facetAccIter = facet.accessibilityGuidelines();
+ while (facetAccIter.hasNext())
+ {
+ accGuideline = facetAccIter.next();
+ _writeAccessibilityGuideline(out, facetName + " facet", accGuideline);
+ }
+ }
+ }
+
+ out.write(" </ul>");
+ out.write(" </html>\n");
+ out.write(" </p>\n");
+ out.write(" </section>\n");
+ }
+
+ // Write out an Accessibility Guideline
+ // A bullet in an unordered list, followed by (optionally) the reference name in bold, e.g. the
+ // name of the attribute or name of the facet which the guideline applies to, then the text
+ // of the accessibility guideline. For accessibility guidelines on the component, the referenceName
+ // attribute is left blank.
+ private void _writeAccessibilityGuideline(Writer out, String referenceName, String desc) throws IOException
+ {
+ out.write(" <div class=\'accGuideline\'>\n");
+ out.write("<li>");
+
+ if (!"".equals(referenceName))
+ {
+ out.write("<b>");
+ out.write(referenceName);
+ out.write("</b>: ");
+ }
+
+ if (desc != null)
+ {
+ if (!"".equals(desc))
+ {
+ out.write(desc + "\n");
+ }
+ }
+
+ out.write("</li>");
+ out.write(" </div>\n");
+ }
+
protected MavenProject getProject()
{
return project;