blob: 2af171960626cb84ccf822e06af0b9f3411d6056 [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.apache.ofbiz.widget.model;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.UtilCodec;
import org.apache.ofbiz.base.util.UtilDateTime;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.base.util.UtilXml;
import org.apache.ofbiz.base.util.collections.FlexibleMapAccessor;
import org.apache.ofbiz.base.util.string.FlexibleStringExpander;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.model.ModelEntity;
import org.apache.ofbiz.entity.model.ModelField;
import org.apache.ofbiz.service.GenericServiceException;
import org.apache.ofbiz.service.LocalDispatcher;
import org.apache.ofbiz.service.ModelParam;
import org.apache.ofbiz.service.ModelService;
import org.w3c.dom.Element;
/**
* A collection of shared/reused widget models.
*
*/
public final class CommonWidgetModels {
public static final String module = CommonWidgetModels.class.getName();
private CommonWidgetModels() {
}
public static class AutoEntityParameters {
private String entityName;
List<String> excludeList = new ArrayList<String>();
boolean includeNonPk;
boolean includePk;
private String includeType;
boolean sendIfEmpty;
public AutoEntityParameters(Element autoElement) {
entityName = UtilXml.checkEmpty(autoElement.getAttribute("entity-name"));
sendIfEmpty = "true".equals(autoElement.getAttribute("send-if-empty"));
includeType = UtilXml.checkEmpty(autoElement.getAttribute("include"));
includePk = "pk".equals(includeType) || "all".equals(includeType);
includeNonPk = "nonpk".equals(includeType) || "all".equals(includeType);
List<? extends Element> excludes = UtilXml.childElementList(autoElement, "exclude");
if (excludes != null) {
for (Element exclude : excludes) {
if (UtilValidate.isNotEmpty(exclude.getAttribute("field-name"))) {
excludeList.add(exclude.getAttribute("field-name"));
}
}
}
}
@SuppressWarnings("unchecked")
public Map<String, String> getParametersMap(Map<String, Object> context, String defaultEntityName) {
Map<String, String> autEntityParams = new HashMap<String, String>();
Delegator delegator = (Delegator) context.get("delegator");
if (delegator == null) {
Debug.logError(
"We can not append auto entity Parameters since we could not find delegator in the current context",
module);
return autEntityParams;
}
if (UtilValidate.isEmpty(entityName))
entityName = defaultEntityName;
FlexibleStringExpander toExpand = FlexibleStringExpander.getInstance(entityName);
ModelEntity entity = delegator.getModelEntity(toExpand.expandString(context));
if (entity == null) {
Debug.logError("We can not append auto entity Parameters since we could not find entity with name [" + entityName
+ "]", module);
return autEntityParams;
}
Iterator<ModelField> fieldsIter = entity.getFieldsIterator();
if (fieldsIter != null) {
while (fieldsIter.hasNext()) {
ModelField field = fieldsIter.next();
String fieldName = field.getName();
FlexibleMapAccessor<Object> fma = FlexibleMapAccessor.getInstance(fieldName);
boolean shouldExclude = excludeList.contains(fieldName);
if ((!shouldExclude) && (!field.getIsAutoCreatedInternal())
&& ((field.getIsPk() && includePk) || (!field.getIsPk() && includeNonPk))) {
Object flexibleValue = fma.get(context);
if (UtilValidate.isEmpty(flexibleValue) && context.containsKey("parameters")) {
flexibleValue = fma.get((Map<String, Object>) context.get("parameters"));
}
if (UtilValidate.isNotEmpty(flexibleValue) || sendIfEmpty) {
autEntityParams.put(fieldName, String.valueOf(flexibleValue));
}
}
}
}
return autEntityParams;
}
}
public static class AutoServiceParameters {
List<String> excludeList = new ArrayList<String>();
boolean includeNonPk;
boolean includePk;
boolean sendIfEmpty;
private String serviceName;
public AutoServiceParameters(Element autoElement) {
serviceName = UtilXml.checkEmpty(autoElement.getAttribute("service-name"));
sendIfEmpty = "true".equals(autoElement.getAttribute("send-if-empty"));
List<? extends Element> excludes = UtilXml.childElementList(autoElement, "exclude");
if (excludes != null) {
for (Element exclude : excludes) {
if (UtilValidate.isNotEmpty(exclude.getAttribute("field-name"))) {
excludeList.add(exclude.getAttribute("field-name"));
}
}
}
}
@SuppressWarnings("unchecked")
public Map<String, String> getParametersMap(Map<String, Object> context, String defaultServiceName) {
Map<String, String> autServiceParams = new HashMap<String, String>();
LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");
if (dispatcher == null) {
Debug.logError(
"We can not append auto service Parameters since we could not find dispatcher in the current context",
module);
return autServiceParams;
}
if (UtilValidate.isEmpty(serviceName))
serviceName = defaultServiceName;
FlexibleStringExpander toExpand = FlexibleStringExpander.getInstance(serviceName);
ModelService service = null;
try {
service = dispatcher.getDispatchContext().getModelService(toExpand.toString());
} catch (GenericServiceException e) {
Debug.logError("Resolve service throw an error : " + e, module);
}
if (service == null) {
Debug.logError("We can not append auto service Parameters since we could not find service with name ["
+ serviceName + "]", module);
return autServiceParams;
}
Iterator<ModelParam> paramsIter = service.getInModelParamList().iterator();
if (paramsIter != null) {
while (paramsIter.hasNext()) {
ModelParam param = paramsIter.next();
if (param.getInternal())
continue;
String paramName = param.getName();
FlexibleMapAccessor<Object> fma = FlexibleMapAccessor.getInstance(paramName);
if (!excludeList.contains(paramName)) {
Object flexibleValue = fma.get(context);
if (UtilValidate.isEmpty(flexibleValue) && context.containsKey("parameters")) {
flexibleValue = fma.get((Map<String, ? extends Object>) context.get("parameters"));
}
if (UtilValidate.isNotEmpty(flexibleValue) || sendIfEmpty) {
autServiceParams.put(paramName, String.valueOf(flexibleValue));
}
}
}
}
return autServiceParams;
}
}
public static final class Image {
private final FlexibleStringExpander alt;
private final FlexibleStringExpander borderExdr;
private final FlexibleStringExpander heightExdr;
private final FlexibleStringExpander idExdr;
private final String name;
private final FlexibleStringExpander srcExdr;
private final FlexibleStringExpander styleExdr;
private final FlexibleStringExpander titleExdr;
private final String urlMode;
private final FlexibleStringExpander widthExdr;
public Image(Element imageElement) {
if (!imageElement.getAttribute("image-location").isEmpty()) {
// Form field version, log warning.
this.srcExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("image-location"));
this.alt = FlexibleStringExpander.getInstance(imageElement.getAttribute("alternate"));
this.titleExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("image-title"));
this.name = "";
this.idExdr = FlexibleStringExpander.getInstance("");
this.styleExdr = FlexibleStringExpander.getInstance("");
this.widthExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("width"));
this.heightExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("height"));
this.borderExdr = FlexibleStringExpander.getInstance("");
this.urlMode = "content";
} else {
this.srcExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("src"));
this.alt = FlexibleStringExpander.getInstance(imageElement.getAttribute("alt"));
this.titleExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("title"));
this.name = imageElement.getAttribute("name");
this.idExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("id"));
this.styleExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("style"));
this.widthExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("width"));
this.heightExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("height"));
this.borderExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("border"));
String urlMode = imageElement.getAttribute("url-mode");
if (urlMode.isEmpty()) {
urlMode = "content";
}
this.urlMode = urlMode;
}
}
public FlexibleStringExpander getAlt() {
return alt;
}
public String getAlt(Map<String, Object> context) {
String alt = this.alt.expandString(context);
// FIXME: Encoding should be done by the renderer, not by the model.
UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
if (simpleEncoder != null) {
alt = simpleEncoder.encode(alt);
}
return alt;
}
public String getBorder(Map<String, Object> context) {
return this.borderExdr.expandString(context);
}
public FlexibleStringExpander getBorderExdr() {
return borderExdr;
}
public String getHeight(Map<String, Object> context) {
return this.heightExdr.expandString(context);
}
public FlexibleStringExpander getHeightExdr() {
return heightExdr;
}
public String getId(Map<String, Object> context) {
return this.idExdr.expandString(context);
}
public FlexibleStringExpander getIdExdr() {
return idExdr;
}
public String getName() {
return name;
}
public String getSrc(Map<String, Object> context) {
return this.srcExdr.expandString(context);
}
public FlexibleStringExpander getSrcExdr() {
return srcExdr;
}
public String getStyle(Map<String, Object> context) {
return this.styleExdr.expandString(context);
}
public FlexibleStringExpander getStyleExdr() {
return styleExdr;
}
public FlexibleStringExpander getTitleExdr() {
return titleExdr;
}
public String getUrlMode() {
return this.urlMode;
}
public String getWidth(Map<String, Object> context) {
return this.widthExdr.expandString(context);
}
public FlexibleStringExpander getWidthExdr() {
return widthExdr;
}
}
public static final class Link {
// FIXME: This is a bad practice. Client code should not need to "know" what this value is.
public static final String DEFAULT_URL_MODE = "intra-app";
private final AutoEntityParameters autoEntityParameters;
private final AutoServiceParameters autoServiceParameters;
private final boolean encode;
private final boolean fullPath;
private final FlexibleStringExpander idExdr;
private final Image image;
private final String linkType; // anchor or hidden form
private final FlexibleStringExpander nameExdr;
private final List<Parameter> parameterList;
private final FlexibleStringExpander prefixExdr;
private final boolean secure;
private final Integer size;
private final FlexibleStringExpander styleExdr;
private final FlexibleStringExpander targetExdr;
private final FlexibleStringExpander targetWindowExdr;
private final FlexibleStringExpander textExdr;
private final String urlMode;
private final boolean requestConfirmation;
private final FlexibleStringExpander confirmationMsgExdr;
// FIXME: These don't belong in this class (might have been used for image)
private final String height;
private final String width;
public Link(Element linkElement) {
this.textExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("text"));
this.idExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("id"));
this.styleExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("style"));
this.nameExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("name"));
this.targetExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target"));
this.targetWindowExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target-window"));
this.prefixExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("prefix"));
this.urlMode = linkElement.getAttribute("url-mode");
this.fullPath = "true".equals(linkElement.getAttribute("full-path"));
this.secure = "true".equals(linkElement.getAttribute("secure"));
this.encode = "true".equals(linkElement.getAttribute("encode"));
Element imageElement = UtilXml.firstChildElement(linkElement, "image");
if (imageElement != null) {
this.image = new Image(imageElement);
} else {
if (!linkElement.getAttribute("image-location").isEmpty()) {
// Backwards compatibility
this.image = new Image(linkElement);
} else {
this.image = null;
}
}
//Backwards compatibility
if ("ajax-window".equals(linkElement.getAttribute("link-type"))) this.linkType = "layered-modal";
else this.linkType = linkElement.getAttribute("link-type");
List<? extends Element> parameterElementList = UtilXml.childElementList(linkElement, "parameter");
if (parameterElementList.isEmpty()) {
this.parameterList = Collections.emptyList();
} else {
List<Parameter> parameterList = new ArrayList<Parameter>(
parameterElementList.size());
for (Element parameterElement : parameterElementList) {
parameterList.add(new Parameter(parameterElement));
}
this.parameterList = Collections.unmodifiableList(parameterList);
}
Element autoServiceParamsElement = UtilXml.firstChildElement(linkElement, "auto-parameters-service");
if (autoServiceParamsElement != null) {
this.autoServiceParameters = new AutoServiceParameters(autoServiceParamsElement);
} else {
this.autoServiceParameters = null;
}
Element autoEntityParamsElement = UtilXml.firstChildElement(linkElement, "auto-parameters-entity");
if (autoEntityParamsElement != null) {
this.autoEntityParameters = new AutoEntityParameters(autoEntityParamsElement);
} else {
this.autoEntityParameters = null;
}
Integer size = null;
String sizeAttr = linkElement.getAttribute("size");
if (!sizeAttr.isEmpty()) {
size = Integer.valueOf(sizeAttr);
}
this.size = size;
this.requestConfirmation = "true".equals(linkElement.getAttribute("request-confirmation"));
this.confirmationMsgExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("confirmation-message"));
this.width = linkElement.getAttribute("width");
this.height = linkElement.getAttribute("height");
}
// Portal constructor
public Link(GenericValue portalPage, List<Parameter> parameterList, String target, Locale locale) {
this.autoEntityParameters = null;
this.autoServiceParameters = null;
this.encode = false;
this.fullPath = false;
this.idExdr = FlexibleStringExpander.getInstance("");
this.image = null;
this.linkType = "";
this.nameExdr = FlexibleStringExpander.getInstance("");
this.parameterList = Collections.unmodifiableList(parameterList);
this.prefixExdr = FlexibleStringExpander.getInstance("");
this.secure = false;
this.styleExdr = FlexibleStringExpander.getInstance("");
this.targetExdr = FlexibleStringExpander.getInstance(target);
this.targetWindowExdr = FlexibleStringExpander.getInstance("");
this.textExdr = FlexibleStringExpander.getInstance((String) portalPage.get("portalPageName", locale));
this.urlMode = "intra-app";
this.size = null;
this.requestConfirmation = false;
this.confirmationMsgExdr = FlexibleStringExpander.getInstance("");
this.width = "";
this.height = "";
}
public AutoEntityParameters getAutoEntityParameters() {
return autoEntityParameters;
}
public AutoServiceParameters getAutoServiceParameters() {
return autoServiceParameters;
}
public String getConfirmationMsg(Map<String, Object> context) {
return this.confirmationMsgExdr.expandString(context);
}
public FlexibleStringExpander getConfirmationMsgExdr() {
return confirmationMsgExdr;
}
public boolean getEncode() {
return this.encode;
}
public boolean getFullPath() {
return this.fullPath;
}
public String getHeight() {
return this.height;
}
public String getId(Map<String, Object> context) {
return this.idExdr.expandString(context);
}
public FlexibleStringExpander getIdExdr() {
return idExdr;
}
public Image getImage() {
return this.image;
}
public String getLinkType() {
return this.linkType;
}
public String getName() {
return nameExdr.getOriginal();
}
public String getName(Map<String, Object> context) {
return this.nameExdr.expandString(context);
}
public FlexibleStringExpander getNameExdr() {
return nameExdr;
}
public List<Parameter> getParameterList() {
return parameterList;
}
public Map<String, String> getParameterMap(Map<String, Object> context, String defaultEntityName, String defaultServiceName) {
Map<String, String> fullParameterMap = new HashMap<String, String>();
for (Parameter parameter : this.parameterList) {
fullParameterMap.put(parameter.getName(), parameter.getValue(context));
}
if (autoServiceParameters != null) {
fullParameterMap.putAll(autoServiceParameters.getParametersMap(context, defaultServiceName));
}
if (autoEntityParameters != null) {
fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, defaultEntityName));
}
return fullParameterMap;
}
public Map<String, String> getParameterMap(Map<String, Object> context) {
Map<String, String> fullParameterMap = new HashMap<String, String>();
for (Parameter parameter : this.parameterList) {
fullParameterMap.put(parameter.getName(), parameter.getValue(context));
}
if (autoServiceParameters != null) {
fullParameterMap.putAll(autoServiceParameters.getParametersMap(context, null));
}
if (autoEntityParameters != null) {
fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, null));
}
return fullParameterMap;
}
public String getPrefix(Map<String, Object> context) {
return this.prefixExdr.expandString(context);
}
public FlexibleStringExpander getPrefixExdr() {
return prefixExdr;
}
public boolean getRequestConfirmation() {
return this.requestConfirmation;
}
public boolean getSecure() {
return this.secure;
}
public Integer getSize() {
return size;
}
public String getStyle(Map<String, Object> context) {
return this.styleExdr.expandString(context);
}
public FlexibleStringExpander getStyleExdr() {
return styleExdr;
}
public String getTarget(Map<String, Object> context) {
Map<String, Object> expanderContext = context;
UtilCodec.SimpleEncoder simpleEncoder = context == null ? null : (UtilCodec.SimpleEncoder) context
.get("simpleEncoder");
if (simpleEncoder != null) {
expanderContext = UtilCodec.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context, simpleEncoder);
}
return this.targetExdr.expandString(expanderContext);
}
public FlexibleStringExpander getTargetExdr() {
return targetExdr;
}
public String getTargetWindow(Map<String, Object> context) {
return this.targetWindowExdr.expandString(context);
}
public FlexibleStringExpander getTargetWindowExdr() {
return targetWindowExdr;
}
public String getText(Map<String, Object> context) {
String text = this.textExdr.expandString(context);
// FIXME: Encoding should be done by the renderer, not by the model.
UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
if (simpleEncoder != null) {
text = simpleEncoder.encode(text);
}
return text;
}
public FlexibleStringExpander getTextExdr() {
return textExdr;
}
public String getUrlMode() {
return this.urlMode;
}
public String getWidth() {
return this.width;
}
}
/**
* Models the &lt;parameter&gt; element.
*
* @see <code>widget-form.xsd</code>
*/
public static class Parameter {
protected FlexibleMapAccessor<Object> fromField;
protected String name;
protected FlexibleStringExpander value;
public Parameter(Element element) {
this.name = element.getAttribute("param-name");
this.value = UtilValidate.isNotEmpty(element.getAttribute("value")) ? FlexibleStringExpander.getInstance(element
.getAttribute("value")) : null;
this.fromField = UtilValidate.isNotEmpty(element.getAttribute("from-field")) ? FlexibleMapAccessor
.getInstance(element.getAttribute("from-field")) : null;
}
public Parameter(String paramName, String paramValue, boolean isField) {
this.name = paramName;
if (isField) {
this.fromField = FlexibleMapAccessor.getInstance(paramValue);
} else {
this.value = FlexibleStringExpander.getInstance(paramValue);
}
}
public FlexibleMapAccessor<Object> getFromField() {
return fromField;
}
public String getName() {
return name;
}
public FlexibleStringExpander getValue() {
return value;
}
public String getValue(Map<String, Object> context) {
if (this.value != null) {
return this.value.expandString(context);
}
Object retVal = null;
if (this.fromField != null && this.fromField.get(context) != null) {
retVal = this.fromField.get(context);
} else {
retVal = context.get(this.name);
}
if (retVal != null) {
TimeZone timeZone = (TimeZone) context.get("timeZone");
if (timeZone == null)
timeZone = TimeZone.getDefault();
String returnValue = null;
// format string based on the user's time zone (not locale because these are parameters)
if (retVal instanceof Double || retVal instanceof Float || retVal instanceof BigDecimal) {
returnValue = retVal.toString();
} else if (retVal instanceof java.sql.Date) {
DateFormat df = UtilDateTime.toDateFormat(UtilDateTime.getDateFormat(), timeZone, null);
returnValue = df.format((java.util.Date) retVal);
} else if (retVal instanceof java.sql.Time) {
DateFormat df = UtilDateTime.toTimeFormat(UtilDateTime.getTimeFormat(), timeZone, null);
returnValue = df.format((java.util.Date) retVal);
} else if (retVal instanceof java.sql.Timestamp) {
DateFormat df = UtilDateTime.toDateTimeFormat(UtilDateTime.getDateTimeFormat(), timeZone, null);
returnValue = df.format((java.util.Date) retVal);
} else if (retVal instanceof java.util.Date) {
DateFormat df = UtilDateTime.toDateTimeFormat("EEE MMM dd hh:mm:ss z yyyy", timeZone, null);
returnValue = df.format((java.util.Date) retVal);
} else {
returnValue = retVal.toString();
}
return returnValue;
} else {
return null;
}
}
}
}