/**
* (C) 2013-2015 Stephan Rauh http://www.beyondjava.net
*
* Licensed 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 net.bootsfaces.expressions.decorator;
import java.util.HashMap;
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.faces.view.facelets.Tag;
import javax.faces.view.facelets.TagAttribute;
import javax.faces.view.facelets.TagDecorator;
/**
* This is one of the most important classes of AngularFaces. It converts attributes to pass-through parameters, adds
* them to the list of JSF bean to be synchronized with the client and implements a couple of pseudo JSF tags.
*/
public class SearchExpressionsTagDecorator implements TagDecorator {
private static boolean active = false;
private boolean activeByDefault = true;
private static final String JSF_NAMESPACE = "http://xmlns.jcp.org/jsf/html";
private static final String JSF_NAMESPACE_OLD = "http://java.sun.com/jsf/html";
private static final String JSF_CORE_NAMESPACE = "http://xmlns.jcp.org/jsf/core";
private static final String JSF_CORE_NAMESPACE_OLD = "http://java.sun.com/jsf/core";
private static final Map<String, Boolean> activePages = new HashMap<String, Boolean>();
static {
System.out.println(
"The BootsFaces Search Expressions decorator is active. You can switch it off globally using the context parameter net.bootsfaces.defaults.decorator in the web.xml or on a per-page basis by adding the attribute bootsFacesDecorator='false'.");
}
public SearchExpressionsTagDecorator() {
String isActive = FacesContext.getCurrentInstance().getExternalContext()
.getInitParameter("net.bootsfaces.defaults.decorator");
if ("false".equalsIgnoreCase(isActive)) {
activeByDefault = false;
} else {
activeByDefault = true;
}
}
public static boolean isActive() {
return active;
}
@Override
public Tag decorate(Tag tag) {
TagAttribute decorator = tag.getAttributes().get("bootsFacesDecorator");
String page = tag.getLocation().getPath();
if (decorator != null) {
boolean decoratorActive = "true".equalsIgnoreCase(decorator.getValue());
Boolean isActive = activePages.get(page);
if (isActive == null) {
activePages.put(page, decoratorActive);
} else if (isActive.booleanValue() != decoratorActive) {
activePages.remove(page);
activePages.put(page, decoratorActive);
}
}
Boolean isActive = activePages.get(page);
if (isActive == null) {
isActive = activeByDefault;
}
if (isActive == Boolean.TRUE) {
Tag newTag = addSearchExpressionResolver(tag);
return newTag;
} else {
return tag;
}
}
private Tag addSearchExpressionResolver(Tag tag) {
if (tag.getNamespace().equals(JSF_CORE_NAMESPACE) || tag.getNamespace().equals(JSF_CORE_NAMESPACE_OLD)
|| tag.getNamespace().equals(JSF_NAMESPACE_OLD) || tag.getNamespace().equals(JSF_NAMESPACE)) {
boolean changeFor = containsAdvancesSearchExpression(tag, "for");
boolean changeRender = containsAdvancesSearchExpression(tag, "render");
boolean changeExecute = containsAdvancesSearchExpression(tag, "execute");
if (changeFor || changeRender || changeExecute) {
TagAttribute[] attributes = tag.getAttributes().getAll();
AFTagAttributes more = new AFTagAttributes(attributes);
if (changeFor) {
String old = tag.getAttributes().get("for").getValue();
more.replaceAttributeValue("for",
"#{searchExpressionResolverBean.resolve(component, '" + old + "')}");
}
if (changeRender) {
String old = tag.getAttributes().get("render").getValue();
more.replaceAttributeValue("render",
"#{searchExpressionResolverBean.resolve(component, '" + old + "')}");
}
if (changeExecute) {
String old = tag.getAttributes().get("execute").getValue();
more.replaceAttributeValue("execute",
"#{searchExpressionResolverBean.resolve(component, '" + old + "')}");
}
tag = new Tag(tag.getLocation(), tag.getNamespace(), tag.getLocalName(), tag.getQName(), more);
}
}
return tag;
}
private boolean containsAdvancesSearchExpression(Tag tag, String attribute) {
boolean changeIt = false;
TagAttribute forAttribute = tag.getAttributes().get(attribute);
if (null != forAttribute) {
String value = forAttribute.getValue();
if (value.contains("*"))
changeIt = true;
if (value.contains("@"))
changeIt = true;
if (value.equals("@form") || value.equals("@none") || value.equals("@this") || value.equals("@all"))
changeIt = false;
if (value.startsWith("#{"))
changeIt = false;
}
return changeIt;
}
}