/*
* Copyright 2009-2014 PrimeTek.
*
* 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 org.primefaces.behavior.base;
import java.util.HashMap;
import java.util.Map;
import javax.el.ELContext;
import javax.el.ValueExpression;
import javax.faces.component.UIComponentBase;
import javax.faces.component.behavior.ClientBehaviorBase;
import javax.faces.context.FacesContext;
public abstract class AbstractBehavior extends ClientBehaviorBase {
protected Map<String, Object> literals;
protected Map<String, ValueExpression> bindings;
public AbstractBehavior() {
super();
int propertiesCount = getAllProperties().length;
literals = new HashMap<String, Object>(propertiesCount);
bindings = new HashMap<String, ValueExpression>(propertiesCount);
}
public void setLiteral(String attr, Object val) {
if (val == null && literals.containsKey(attr)) {
literals.remove(attr);
} else {
literals.put(attr, val);
}
}
public void setLiteral(Enum<?> property, Object val) {
String attr = property.name();
setLiteral(attr, val);
}
public void setValueExpression(String attr, ValueExpression ve) {
if (ve == null && bindings.containsKey(attr)) {
bindings.remove(attr);
} else {
bindings.put(attr, ve);
}
}
public void setValueExpression(Enum<?> property, ValueExpression ve) {
String attr = property.name();
setValueExpression(attr, ve);
}
public <T> T eval(String attr, T unspecifiedValue) {
if (literals.containsKey(attr)) {
Object val = literals.get(attr);
if(val == null){
return unspecifiedValue;
} else {
return (T) val;
}
}
ValueExpression ve = bindings.get(attr);
if (ve != null) {
FacesContext facesContext = FacesContext.getCurrentInstance();
ELContext elContext = facesContext.getELContext();
return (T) ve.getValue(elContext);
}
return unspecifiedValue;
}
protected <T> T eval(Enum<?> property, T unspecifiedValue) {
return eval(property.name(), unspecifiedValue);
}
protected boolean isAttributeSet(String attr) {
return literals.containsKey(attr) || bindings.containsKey(attr);
}
protected boolean isAttributeSet(Enum<?> property) {
String attr = property.name();
return isAttributeSet(attr);
}
@Override
public Object saveState(FacesContext context) {
if (context == null) {
throw new NullPointerException();
}
Object[] values;
Object superState = super.saveState(context);
if (initialStateMarked()) {
if (superState == null) {
values = null;
} else {
values = new Object[] { superState };
}
} else {
values = new Object[3];
values[0] = superState;
values[1] = savePropertyMap(context, literals, false);
values[2] = savePropertyMap(context, bindings, true);
}
return values;
}
@Override
public void restoreState(FacesContext context, Object state) {
if (context == null) {
throw new NullPointerException();
}
if (state != null) {
Object[] values = (Object[]) state;
super.restoreState(context, values[0]);
if (values.length != 1) {
literals = restorePropertyMap(context, (Object[]) values[1], false);
bindings = restorePropertyMap(context, (Object[]) values[2], true);
// If we saved state last time, save state again next time.
clearInitialState();
}
}
}
protected Object[] savePropertyMap(FacesContext context, Map map, boolean saveValuesAsAttachedState) {
if (map == null) {
return null;
}
Enum<?>[] allProperties = getAllProperties();
Object[] values = new Object[allProperties.length];
for (int i = 0; i < allProperties.length; i++) {
values[i] = map.get(allProperties[i].name());
if (saveValuesAsAttachedState) {
values[i] = UIComponentBase.saveAttachedState(context, values[i]);
}
}
return values;
}
protected Map restorePropertyMap(FacesContext context, Object[] values, boolean restoreValuesFromAttachedState) {
if (values == null) {
return null;
}
Enum<?>[] allProperties = getAllProperties();
Map<String, Object> map = new HashMap<String, Object>(allProperties.length);
for (int i = 0; i < allProperties.length; i++) {
Object val = values[i];
if (restoreValuesFromAttachedState) {
val = UIComponentBase.restoreAttachedState(context, val);
}
map.put(allProperties[i].name(), val);
}
return map;
}
protected abstract Enum<?>[] getAllProperties();
}