1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.component.search;
20
21 import java.util.regex.Matcher;
22 import java.util.regex.Pattern;
23 import javax.faces.FacesException;
24 import javax.faces.component.ContextCallback;
25 import javax.faces.component.UIComponent;
26 import javax.faces.component.search.SearchExpressionContext;
27 import javax.faces.component.search.SearchExpressionHint;
28 import javax.faces.component.search.SearchKeywordContext;
29 import javax.faces.component.search.SearchKeywordResolver;
30 import javax.faces.component.visit.VisitCallback;
31 import javax.faces.component.visit.VisitContext;
32 import javax.faces.component.visit.VisitResult;
33 import javax.faces.context.FacesContext;
34
35
36
37
38 public class IdSearchKeywordResolver extends SearchKeywordResolver
39 {
40
41 public static final String ID_KEYWORD = "id";
42
43 private static final Pattern PATTERN = Pattern.compile("id\\((\\w+)\\)");
44
45 @Override
46 public void resolve(SearchKeywordContext expressionContext, UIComponent current, String keyword)
47 {
48 FacesContext facesContext = expressionContext.getSearchExpressionContext().getFacesContext();
49
50 final String targetId = extractId(keyword);
51 if (expressionContext.getSearchExpressionContext().getExpressionHints() != null
52 && expressionContext.getSearchExpressionContext().getExpressionHints().contains(
53 SearchExpressionHint.SKIP_VIRTUAL_COMPONENTS))
54 {
55
56
57 withId(facesContext, targetId, current, expressionContext.getCallback());
58 expressionContext.setKeywordResolved(true);
59 }
60 else
61 {
62 current.visitTree(
63 VisitContext.createVisitContext(facesContext, null,
64 expressionContext.getSearchExpressionContext().getVisitHints()),
65 new VisitCallback()
66 {
67 @Override
68 public VisitResult visit(VisitContext context, UIComponent target)
69 {
70 if (targetId.equals(target.getId()))
71 {
72 expressionContext.invokeContextCallback(target);
73
74 if (expressionContext.getSearchExpressionContext().getExpressionHints() != null
75 && expressionContext.getSearchExpressionContext().getExpressionHints().contains(
76 SearchExpressionHint.RESOLVE_SINGLE_COMPONENT))
77 {
78 return VisitResult.COMPLETE;
79 }
80
81 return VisitResult.ACCEPT;
82 }
83 else
84 {
85 return VisitResult.ACCEPT;
86 }
87 }
88 });
89 }
90 }
91
92 protected String extractId(String expression)
93 {
94 Matcher matcher = PATTERN.matcher(expression);
95 if (matcher.matches())
96 {
97 return matcher.group(1);
98 }
99 else
100 {
101 throw new FacesException("Expression does not match following pattern @id(id). Expression: \""
102 + expression + "\"");
103 }
104 }
105
106 private static void withId(FacesContext context, String id, UIComponent base, ContextCallback callback)
107 {
108 if (id.equals(base.getId()))
109 {
110 callback.invokeContextCallback(context, base);
111 }
112
113 if (base.getFacetCount() > 0)
114 {
115 for (UIComponent facet : base.getFacets().values())
116 {
117 withId(context, id, facet, callback);
118 }
119 }
120
121 if (base.getChildCount() > 0)
122 {
123 for (int i = 0, childCount = base.getChildCount(); i < childCount; i++)
124 {
125 UIComponent child = base.getChildren().get(i);
126 withId(context, id, child, callback);
127 }
128 }
129 }
130
131 @Override
132 public boolean isResolverForKeyword(SearchExpressionContext searchExpressionContext, String command)
133 {
134 if (command.length() > 6 && command.substring(0, ID_KEYWORD.length()).equalsIgnoreCase(ID_KEYWORD))
135 {
136 Matcher matcher = PATTERN.matcher(command);
137
138 if (matcher.matches())
139 {
140 return true;
141 }
142 else
143 {
144 return false;
145 }
146 }
147 return false;
148 }
149
150 @Override
151 public boolean isPassthrough(SearchExpressionContext searchExpressionContext, String keyword)
152 {
153 return false;
154 }
155
156 @Override
157 public boolean isLeaf(SearchExpressionContext searchExpressionContext, String keyword)
158 {
159 return false;
160 }
161
162 }