blob: aa3a8137e5b5793339d35c04b1d78a8d20b06564 [file] [log] [blame]
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.ofbiz.base.util.collections;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpSession;
import org.ofbiz.base.util.UtilGenerics;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.string.FlexibleStringExpander;
/**
* Used to flexibly access Map values, supporting the "." (dot) syntax for
* accessing sub-map values and the "[]" (square bracket) syntax for accessing
* list elements. See individual Map operations for more information.
*
*/
@SuppressWarnings("serial")
public class FlexibleServletAccessor<T> implements Serializable {
protected String name;
protected String attributeName;
protected FlexibleMapAccessor<T> fma;
protected boolean needsExpand;
protected boolean empty;
public FlexibleServletAccessor(String name) {
init(name);
}
public FlexibleServletAccessor(String name, String defaultName) {
if (UtilValidate.isEmpty(name)) {
init(defaultName);
} else {
init(name);
}
}
protected void init(String name) {
this.name = name;
if (UtilValidate.isEmpty(name)) {
empty = true;
needsExpand = false;
fma = FlexibleMapAccessor.getInstance(name);
attributeName = name;
} else {
empty = false;
int openPos = name.indexOf("${");
if (openPos != -1 && name.indexOf("}", openPos) != -1) {
fma = null;
attributeName = null;
needsExpand = true;
} else {
int dotIndex = name.indexOf('.');
if (dotIndex != -1) {
attributeName = name.substring(0, dotIndex);
fma = FlexibleMapAccessor.getInstance(name.substring(dotIndex+1));
} else {
attributeName = name;
fma = null;
}
needsExpand = false;
}
}
}
public boolean isEmpty() {
return this.empty;
}
/** Based on name get from ServletRequest or from List in ServletRequest
* @param request request to get the value from
* @param expandContext the context to use for name expansion
* @return the object corresponding to this getter class
*/
public T get(ServletRequest request, Map<String, Object> expandContext) {
AttributeAccessor<T> aa = new AttributeAccessor<T>(name, expandContext, this.attributeName, this.fma, this.needsExpand);
return aa.get(request);
}
/** Based on name get from HttpSession or from List in HttpSession
* @param session
* @param expandContext
* @return the found value
*/
public T get(HttpSession session, Map<String, Object> expandContext) {
AttributeAccessor<T> aa = new AttributeAccessor<T>(name, expandContext, this.attributeName, this.fma, this.needsExpand);
return aa.get(session);
}
/** Based on name put in ServletRequest or from List in ServletRequest;
* If the brackets for a list are empty the value will be appended to the list,
* otherwise the value will be set in the position of the number in the brackets.
* If a "+" (plus sign) is included inside the square brackets before the index
* number the value will inserted/added at that point instead of set at the point.
* @param request
* @param value
* @param expandContext
*/
public void put(ServletRequest request, T value, Map<String, Object> expandContext) {
AttributeAccessor<T> aa = new AttributeAccessor<T>(name, expandContext, this.attributeName, this.fma, this.needsExpand);
aa.put(request, value);
}
/** Based on name put in HttpSession or from List in HttpSession;
* If the brackets for a list are empty the value will be appended to the list,
* otherwise the value will be set in the position of the number in the brackets.
* If a "+" (plus sign) is included inside the square brackets before the index
* number the value will inserted/added at that point instead of set at the point.
* @param session
* @param value
* @param expandContext
*/
public void put(HttpSession session, T value, Map<String, Object> expandContext) {
AttributeAccessor<T> aa = new AttributeAccessor<T>(name, expandContext, this.attributeName, this.fma, this.needsExpand);
aa.put(session, value);
}
/** Based on name remove from ServletRequest or from List in ServletRequest
* @param request
* @param expandContext
* @return the removed value
*/
public T remove(ServletRequest request, Map<String, Object> expandContext) {
AttributeAccessor<T> aa = new AttributeAccessor<T>(name, expandContext, this.attributeName, this.fma, this.needsExpand);
return aa.remove(request);
}
/** Based on name remove from HttpSession or from List in HttpSession
* @param session
* @param expandContext
* @return the removed value
*/
public T remove(HttpSession session, Map<String, Object> expandContext) {
AttributeAccessor<T> aa = new AttributeAccessor<T>(name, expandContext, this.attributeName, this.fma, this.needsExpand);
return aa.remove(session);
}
/** The equals and hashCode methods are imnplemented just case this object is ever accidently used as a Map key *
* @return the hashcode
*/
@Override
public int hashCode() {
return this.name.hashCode();
}
/** The equals and hashCode methods are imnplemented just case this object is ever accidently used as a Map key
* @param obj
* @return whether this object is equal to the passed object
*/
@Override
public boolean equals(Object obj) {
if (obj instanceof FlexibleServletAccessor<?>) {
FlexibleServletAccessor<?> flexibleServletAccessor = (FlexibleServletAccessor<?>) obj;
if (this.name == null) {
return flexibleServletAccessor.name == null;
}
return this.name.equals(flexibleServletAccessor.name);
} else {
String str = (String) obj;
if (this.name == null) {
return str == null;
}
return this.name.equals(str);
}
}
/** To be used for a string representation of the accessor, returns the original name.
* @return the name of this accessor
*/
@Override
public String toString() {
return this.name;
}
protected static class AttributeAccessor<T> implements Serializable {
protected Map<String, Object> expandContext;
protected String attributeName;
protected FlexibleMapAccessor<T> fma;
protected boolean isListReference;
protected boolean isAddAtIndex;
protected boolean isAddAtEnd;
protected int listIndex;
protected int openBrace;
protected int closeBrace;
public AttributeAccessor(String origName, Map<String, Object> expandContext, String defAttributeName, FlexibleMapAccessor<T> defFma, boolean needsExpand) {
attributeName = defAttributeName;
fma = defFma;
if (needsExpand) {
String name = FlexibleStringExpander.expandString(origName, expandContext);
int dotIndex = name.indexOf('.');
if (dotIndex != -1) {
attributeName = name.substring(0, dotIndex);
fma = FlexibleMapAccessor.getInstance(name.substring(dotIndex+1));
} else {
attributeName = name;
fma = null;
}
}
isListReference = false;
isAddAtIndex = false;
isAddAtEnd = false;
listIndex = -1;
openBrace = attributeName.indexOf('[');
closeBrace = (openBrace == -1 ? -1 : attributeName.indexOf(']', openBrace));
if (openBrace != -1 && closeBrace != -1) {
String liStr = attributeName.substring(openBrace+1, closeBrace);
//if brackets are empty, append to list
if (liStr.length() == 0) {
isAddAtEnd = true;
} else {
if (liStr.charAt(0) == '+') {
liStr = liStr.substring(1);
listIndex = Integer.parseInt(liStr);
isAddAtIndex = true;
} else {
listIndex = Integer.parseInt(liStr);
}
}
attributeName = attributeName.substring(0, openBrace);
isListReference = true;
}
}
public T get(ServletRequest request) {
Object theValue = null;
if (isListReference) {
List<T> lst = UtilGenerics.cast(request.getAttribute(attributeName));
theValue = lst.get(listIndex);
} else {
theValue = request.getAttribute(attributeName);
}
if (fma != null) {
return fma.get(UtilGenerics.<String, Object>checkMap(theValue));
} else {
return UtilGenerics.<T>cast(theValue);
}
}
public T get(HttpSession session) {
Object theValue = null;
if (isListReference) {
List<T> lst = UtilGenerics.cast(session.getAttribute(attributeName));
theValue = lst.get(listIndex);
} else {
theValue = session.getAttribute(attributeName);
}
if (fma != null) {
return fma.get(UtilGenerics.<String, Object>checkMap(theValue));
} else {
return UtilGenerics.<T>cast(theValue);
}
}
protected void putInList(List<T> lst, T value) {
//if brackets are empty, append to list
if (isAddAtEnd) {
lst.add(value);
} else {
if (isAddAtIndex) {
lst.add(listIndex, value);
} else {
lst.set(listIndex, value);
}
}
}
public void put(ServletRequest request, T value) {
if (fma == null) {
if (isListReference) {
List<T> lst = UtilGenerics.checkList(request.getAttribute(attributeName));
putInList(lst, value);
} else {
request.setAttribute(attributeName, value);
}
} else {
Object theObj = request.getAttribute(attributeName);
if (isListReference) {
List<T> lst = UtilGenerics.checkList(theObj);
fma.put(UtilGenerics.checkMap(lst.get(listIndex), String.class, Object.class), value);
} else {
fma.put(UtilGenerics.checkMap(theObj, String.class, Object.class), value);
}
}
}
public void put(HttpSession session, T value) {
if (fma == null) {
if (isListReference) {
List<T> lst = UtilGenerics.checkList(session.getAttribute(attributeName));
putInList(lst, value);
} else {
session.setAttribute(attributeName, value);
}
} else {
Object theObj = session.getAttribute(attributeName);
if (isListReference) {
List<T> lst = UtilGenerics.checkList(theObj);
fma.put(UtilGenerics.checkMap(lst.get(listIndex), String.class, Object.class), value);
} else {
fma.put(UtilGenerics.checkMap(theObj, String.class, Object.class), value);
}
}
}
public T remove(ServletRequest request) {
if (fma != null) {
Object theObj = request.getAttribute(attributeName);
if (isListReference) {
List<Object> lst = UtilGenerics.checkList(theObj);
return fma.remove(UtilGenerics.checkMap(lst.get(listIndex), String.class, Object.class));
} else {
return fma.remove(UtilGenerics.checkMap(theObj, String.class, Object.class));
}
} else {
if (isListReference) {
List<Object> lst = UtilGenerics.checkList(request.getAttribute(attributeName));
return UtilGenerics.<T>cast(lst.remove(listIndex));
} else {
Object theValue = request.getAttribute(attributeName);
request.removeAttribute(attributeName);
return UtilGenerics.<T>cast(theValue);
}
}
}
public T remove(HttpSession session) {
if (fma != null) {
Object theObj = session.getAttribute(attributeName);
if (isListReference) {
List<Object> lst = UtilGenerics.checkList(theObj);
return fma.remove(UtilGenerics.checkMap(lst.get(listIndex), String.class, Object.class));
} else {
return fma.remove(UtilGenerics.checkMap(theObj, String.class, Object.class));
}
} else {
if (isListReference) {
List<Object> lst = UtilGenerics.checkList(session.getAttribute(attributeName));
return UtilGenerics.<T>cast(lst.remove(listIndex));
} else {
Object theValue = session.getAttribute(attributeName);
session.removeAttribute(attributeName);
return UtilGenerics.<T>cast(theValue);
}
}
}
}
}