/
SeamViewMetadata.java
82 lines (69 loc) · 2.74 KB
/
SeamViewMetadata.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package org.jboss.seam.faces.view;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewParameter;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewMetadata;
import org.jboss.logging.Logger;
import org.jboss.logging.Logger.Level;
/**
* Wrap the built-in {@link ViewMetadata} implementation for the purpose of adding a UIViewParameter placeholder component if
* necessary.
*
* <p>
* In JSF 2.0, the view metadata facet was introduced for the purpose of providing front-controller behavior in JSF. On an
* initial request, the full JSF lifecycle is executed on a partial view consisting of the components in the view metadata
* facet. However, there is one big caveat! The lifecycle is only executed if the view metadata contains at least one
* UIViewParameter.
* </p>
*
* <p>
* This wrapper intercepts the call to {@link ViewMetadata#createMetadataView(FacesContext)} and adds a placeholder
* UIViewParameter if the view metadata is non-empty and there are no other UIViewParameter components.
* </p>
*
* @author <a href="http://community.jboss.org/people/dan.j.allen">Dan Allen</a>
*/
public class SeamViewMetadata extends ViewMetadata {
private transient final Logger logger = Logger.getLogger(SeamViewMetadata.class.getName());
private ViewMetadata delegate;
public SeamViewMetadata(ViewMetadata delegate) {
this.delegate = delegate;
}
@Override
public String getViewId() {
return delegate.getViewId();
}
@Override
public UIViewRoot createMetadataView(FacesContext context) {
UIViewRoot viewRoot = null;
try {
viewRoot = delegate.createMetadataView(context);
} catch (RuntimeException e) {
// deal with swallowed exception in Mojarra
logger.fatal(e.getMessage());
throw e;
}
UIComponent metadataFacet = viewRoot.getFacet(UIViewRoot.METADATA_FACET_NAME);
if (metadataFacet == null) {
return viewRoot;
}
boolean foundViewParam = false;
boolean foundOther = false;
for (UIComponent candidate : metadataFacet.getChildren()) {
if (candidate instanceof UIViewParameter) {
foundViewParam = true;
} else {
foundOther = true;
}
}
if (foundOther && !foundViewParam) {
UIViewParameter placeholder = (UIViewParameter) context.getApplication().createComponent(
UIViewParameter.COMPONENT_TYPE);
placeholder.setId(viewRoot.createUniqueId());
placeholder.setName("");
metadataFacet.getChildren().add(0, placeholder);
}
return viewRoot;
}
}