Author: nbelaevski
Date: 2010-04-20 15:38:18 -0400 (Tue, 20 Apr 2010)
New Revision: 16786
Modified:
root/framework/trunk/api/src/main/java/org/richfaces/component/MetaComponentResolver.java
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java
root/ui/trunk/components/core/src/main/java/org/richfaces/component/AbstractRegion.java
Log:
https://jira.jboss.org/jira/browse/RF-7856
Modified:
root/framework/trunk/api/src/main/java/org/richfaces/component/MetaComponentResolver.java
===================================================================
---
root/framework/trunk/api/src/main/java/org/richfaces/component/MetaComponentResolver.java 2010-04-20
18:47:01 UTC (rev 16785)
+++
root/framework/trunk/api/src/main/java/org/richfaces/component/MetaComponentResolver.java 2010-04-20
19:38:18 UTC (rev 16786)
@@ -33,7 +33,6 @@
// TODO - do we want to make this configurable in web.xml?
public static final char META_COMPONENT_SEPARATOR_CHAR = '@';
- public String resolveClientId(FacesContext facesContext, UIComponent
contextComponent,
- String componentId, String metaId);
+ public String resolveClientId(FacesContext facesContext, UIComponent
contextComponent, String metaComponentId);
}
Modified:
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java 2010-04-20
18:47:01 UTC (rev 16785)
+++
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java 2010-04-20
19:38:18 UTC (rev 16786)
@@ -26,6 +26,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Locale;
@@ -85,6 +86,15 @@
public static final String THIS = "@this";
public static final String NONE = "@none";
+ public static final Set<String> GLOBAL_META_COMPONENTS;
+
+ static {
+ GLOBAL_META_COMPONENTS = new HashSet<String>(2);
+
+ GLOBAL_META_COMPONENTS.add(ALL);
+ GLOBAL_META_COMPONENTS.add(NONE);
+ }
+
/**
* Attribute to keep
*/
@@ -661,7 +671,7 @@
* @return
*/
public static String[] asArray(String valuesSet) {
- return valuesSet.trim().split("(\\s*,\\s*)|(\\s+)");
+ return IdSplitBuilder.split(valuesSet);
}
/**
Modified:
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java 2010-04-20
18:47:01 UTC (rev 16785)
+++
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java 2010-04-20
19:38:18 UTC (rev 16786)
@@ -44,6 +44,7 @@
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
import javax.faces.component.UIForm;
+import javax.faces.component.UINamingContainer;
import javax.faces.component.UIParameter;
import javax.faces.component.UIViewRoot;
import javax.faces.component.ValueHolder;
@@ -919,6 +920,136 @@
return false;
}
+ private static int findNextIdx(String string, char c, int startIdx) {
+ int result = string.indexOf(c, startIdx);
+
+ if (result < 0) {
+ result = string.length();
+ }
+
+ return result;
+ }
+
+ private static UIComponent findParentContainer(UIComponent component) {
+ UIComponent c = component;
+
+ do {
+ c = c.getParent();
+ } while (!(c instanceof NamingContainer) && c != null);
+
+ return c;
+ }
+
+ private static String computeClientId(FacesContext context,
+ UIComponent component, String cleanedId, String id) {
+
+ StringBuilder builder = new StringBuilder(id.length());
+
+ char separatorChar = UINamingContainer.getSeparatorChar(context);
+
+ int nameSegmentsCounter = 1;
+ int idx = 0;
+
+ //TODO nick - here hack is used - implement correct findComponent(...) method
+ while ((idx = cleanedId.indexOf(separatorChar, idx) + 1) > 0) {
+ nameSegmentsCounter++;
+ }
+
+ UIComponent container = component;
+
+ for (int i = 0; i < nameSegmentsCounter && container != null; i++) {
+ container = findParentContainer(container);
+ }
+
+ if (container != null) {
+ String clientId = container.getContainerClientId(context);
+ if (clientId.length() != 0) {
+ builder.append(clientId);
+ builder.append(separatorChar);
+ }
+ }
+
+ builder.append(id);
+
+ return builder.toString();
+ }
+
+ private static String cleanupId(char separatorChar, String id) {
+ if (id == null || id.length() == 0) {
+ return id;
+ }
+
+ StringBuilder sb = new StringBuilder();
+
+ boolean appendSeparator = false;
+ int lastIdx = 0;
+ int idx = 0;
+
+ do {
+ idx = findNextIdx(id, separatorChar, lastIdx);
+ //TODO nick - extract constants
+ if (idx == lastIdx || (id.charAt(lastIdx) != '[' &&
id.charAt(idx - 1) != ']')) {
+ //TODO nick - review this code for '*' selectors handling
+ if (idx - lastIdx != 1 || id.charAt(lastIdx) != '*') {
+ if (appendSeparator) {
+ sb.append(separatorChar);
+ } else {
+ appendSeparator = true;
+ }
+
+ sb.append(id.substring(lastIdx, idx));
+ }
+ }
+
+ lastIdx = idx + 1;
+ } while (idx != id.length());
+
+ return sb.toString();
+ }
+
+ private static String resolveMetaComponentId(FacesContext context, UIComponent
component, String metaComponentId) {
+ UIComponent c = component;
+ while (c != null) {
+ if (c instanceof MetaComponentResolver) {
+ MetaComponentResolver metaComponentResolver = (MetaComponentResolver) c;
+
+ String resolvedId = metaComponentResolver.resolveClientId(context,
component, metaComponentId);
+
+ if (resolvedId != null) {
+ return resolvedId;
+ }
+ }
+
+ c = c.getParent();
+ }
+
+ return metaComponentSubstitutions.get(metaComponentId);
+ }
+
+ private boolean addPredefinedMetaComponentId(FacesContext facesContext, UIComponent
component,
+ Set<String> ids, String id) {
+
+ if (AjaxRendererUtils.ALL.equals(id)) {
+ ids.clear();
+ ids.add(AjaxRendererUtils.ALL);
+ return true;
+ } else if (AjaxRendererUtils.NONE.equals(id)) {
+ ids.clear();
+ return true;
+ } else if (AjaxRendererUtils.THIS.equals(id)) {
+ ids.add(component.getClientId(facesContext));
+ return true;
+ } else if (AjaxRendererUtils.FORM.equals(id)) {
+ UIForm nestingForm = getNestingForm(facesContext, component);
+ if (nestingForm != null) {
+ ids.add(nestingForm.getClientId(facesContext));
+ }
+ return true;
+ }
+
+ return false;
+ }
+
/**
* @param context
* @param component
@@ -934,82 +1065,79 @@
Set<String> result = new LinkedHashSet<String>(shortIds.size());
if (checkKeyword(shortIds, AjaxRendererUtils.ALL)) {
+ result.clear();
result.add(AjaxRendererUtils.ALL);
} else if (checkKeyword(shortIds, AjaxRendererUtils.NONE)) {
//do nothing, use empty set
} else {
for (String id : shortIds) {
- if (AjaxRendererUtils.THIS.equals(id)) {
- result.add(component.getClientId(context));
- } else if (AjaxRendererUtils.FORM.equals(id)) {
- result.add(getNestingForm(context, component).getClientId(context));
- } else {
- String componentId;
- String metaComponentId;
+ if (id.length() == 0) {
+ continue;
+ }
- int idx = id.indexOf(META_COMPONENT_SEPARATOR_CHAR);
- if (idx >= 0) {
- componentId = id.substring(0, idx);
- metaComponentId = id.substring(idx + 1);
- } else {
- componentId = id;
- metaComponentId = null;
- }
+ if (addPredefinedMetaComponentId(context, component, result, id)) {
+ continue;
+ }
- if (metaComponentId == null) {
- UIComponent foundComponent = findComponentFor(component,
componentId);
- if (foundComponent != null) {
- result.add(foundComponent.getClientId(context));
- } else {
- result.add(componentId);
- }
- } else {
- UIComponent foundComponent;
+ char separatorChar = UINamingContainer.getSeparatorChar(context);
+ if (id.charAt(0) == separatorChar) {
+ //TODO nick - how to handle meta-component IDs attached to client
IDs?
+ result.add(id.substring(1));
+ continue;
+ }
- if (componentId != null && componentId.length() != 0) {
- foundComponent = findComponentFor(component, componentId);
- } else {
- foundComponent = component;
- }
+ String componentId;
+ String metaComponentId;
- String convertedId = null;
+ int idx = id.indexOf(META_COMPONENT_SEPARATOR_CHAR);
+ if (idx >= 0) {
+ componentId = id.substring(0, idx);
+ metaComponentId = id.substring(idx + 1);
+ } else {
+ componentId = id;
+ metaComponentId = null;
+ }
- while (foundComponent != null) {
- if (foundComponent instanceof MetaComponentResolver) {
- MetaComponentResolver metadataConversionComponent =
- (MetaComponentResolver) foundComponent;
+ UIComponent baseComponent = null;
+ String cleanedId = null;
+ if (!isEmpty(componentId)) {
+ cleanedId = cleanupId(separatorChar, componentId);
+ baseComponent = findComponentFor(component, cleanedId);
- convertedId =
metadataConversionComponent.resolveClientId(context, component,
- componentId, metaComponentId);
+ if (baseComponent == null) {
+ LOGGER.warn(MessageFormat.format(
+ "''{0}'' cannot be resolved in the
current context", cleanedId));
+ }
+ }
- if (convertedId != null) {
- break;
- }
- }
+ if (!isEmpty(metaComponentId)) {
+ if (isEmpty(componentId)) {
+ baseComponent = component;
+ }
- foundComponent = foundComponent.getParent();
- }
-
- if (convertedId == null) {
- convertedId =
metaComponentSubstitutions.get(metaComponentId);
- }
-
- if (convertedId != null) {
- if (AjaxRendererUtils.ALL.equals(convertedId)) {
- result.clear();
- result.add(AjaxRendererUtils.ALL);
+ if (baseComponent != null) {
+ String convertedId = resolveMetaComponentId(context,
baseComponent, metaComponentId);
+ if (addPredefinedMetaComponentId(context, baseComponent, result,
convertedId)) {
+ if
(AjaxRendererUtils.GLOBAL_META_COMPONENTS.contains(convertedId)) {
break;
- } else {
- result.add(convertedId);
}
} else {
- //TODO - review
- LOGGER.warn(
- MessageFormat.format("''{0}'' cannot
be resolved in the current context", id));
+ if (convertedId == null) {
+ convertedId = computeClientId(context, baseComponent,
cleanedId, id);
+ }
- result.add(id);
+ result.add(convertedId);
}
+ } else {
+ result.add(id);
}
+ } else {
+ if (baseComponent != null) {
+ String computedId = computeClientId(context, baseComponent,
cleanedId, id);
+ result.add(computedId);
+ } else {
+ result.add(id);
+ }
}
}
}
Modified:
root/ui/trunk/components/core/src/main/java/org/richfaces/component/AbstractRegion.java
===================================================================
---
root/ui/trunk/components/core/src/main/java/org/richfaces/component/AbstractRegion.java 2010-04-20
18:47:01 UTC (rev 16785)
+++
root/ui/trunk/components/core/src/main/java/org/richfaces/component/AbstractRegion.java 2010-04-20
19:38:18 UTC (rev 16786)
@@ -37,8 +37,7 @@
)
public abstract class AbstractRegion extends UIComponentBase implements
MetaComponentResolver, AjaxContainer {
- public String resolveClientId(FacesContext facesContext, UIComponent
contextComponent,
- String componentId, String metaId) {
+ public String resolveClientId(FacesContext facesContext, UIComponent
contextComponent, String metaId) {
if (META_COMPONENT_ID.equals(metaId)) {
return getClientId(facesContext);