package com.softwaremill.common.faces.navigation;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewParameter;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewDeclarationLanguage;
import javax.faces.view.ViewMetadata;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author Adam Warski (adam at warski dot org)
*/
public abstract class AbstractPage implements Page, Serializable {
private final Map<String, String> params;
private final boolean requiresLogin;
public AbstractPage(Map<String, String> params, boolean requiresLogin) {
this.params = params;
this.requiresLogin = requiresLogin;
}
protected abstract String computeViewId();
public abstract Page copy(Map<String, String> params, boolean requiresLogin);
public Page includeParam(String name, String value) {
Map<String, String> newParams = new LinkedHashMap<String, String>(params);
newParams.put(name, value);
return copy(newParams, isRequiresLogin());
}
public Page redirect() {
return includeParam("faces-redirect", "true");
}
public Page includeViewParams() {
return includeParam("includeViewParams", "true");
}
public Page includeViewParam(String name) {
String viewId = computeViewId();
// Getting the metadata facet of the view
FacesContext ctx = FacesContext.getCurrentInstance();
ViewDeclarationLanguage vdl = ctx.getApplication().getViewHandler().getViewDeclarationLanguage(ctx, viewId);
ViewMetadata viewMetadata = vdl.getViewMetadata(ctx, viewId);
UIViewRoot viewRoot = viewMetadata.createMetadataView(ctx);
UIComponent metadataFacet = viewRoot.getFacet(UIViewRoot.METADATA_FACET_NAME);
// Looking for a view parameter with the specified name
UIViewParameter viewParam = null;
for (UIComponent child : metadataFacet.getChildren()) {
if (child instanceof UIViewParameter) {
UIViewParameter tempViewParam = (UIViewParameter) child;
if (name.equals(tempViewParam.getName())) {
viewParam = tempViewParam;
break;
}
}
}
if (viewParam == null) {
throw new FacesException("Unknown parameter: '" + name + "' for view: " + viewId);
}
// Getting the value
String value = viewParam.getStringValue(ctx);
return includeParam(name, value);
}
public String s() {
StringBuilder sb = new StringBuilder();
sb.append(computeViewId());
String paramSeparator = "?";
for (Map.Entry<String, String> nameValue : params.entrySet()) {
sb.append(paramSeparator).append(nameValue.getKey()).append("=").append(nameValue.getValue());
paramSeparator = "&";
}
return sb.toString();
}
public String getS() { return s(); }
public boolean isRequiresLogin() {
return requiresLogin;
}
}