Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/CommonWidgetModels.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/CommonWidgetModels.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/CommonWidgetModels.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/CommonWidgetModels.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,629 @@ +/******************************************************************************* + * 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.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.ofbiz.base.util.Debug; +import org.ofbiz.base.util.UtilCodec; +import org.ofbiz.base.util.UtilDateTime; +import org.ofbiz.base.util.UtilValidate; +import org.ofbiz.base.util.UtilXml; +import org.ofbiz.base.util.collections.FlexibleMapAccessor; +import org.ofbiz.base.util.string.FlexibleStringExpander; +import org.ofbiz.entity.Delegator; +import org.ofbiz.entity.GenericValue; +import org.ofbiz.entity.model.ModelEntity; +import org.ofbiz.entity.model.ModelField; +import org.ofbiz.service.GenericServiceException; +import org.ofbiz.service.LocalDispatcher; +import org.ofbiz.service.ModelParam; +import org.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) { + this.name = imageElement.getAttribute("name"); + String src = imageElement.getAttribute("image-location"); + if (src.isEmpty()) { + src = imageElement.getAttribute("src"); + } else { + // Form field version, log warning. + } + this.srcExdr = FlexibleStringExpander.getInstance(src); + 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 alt = imageElement.getAttribute("alternate"); + if (alt.isEmpty()) { + alt = imageElement.getAttribute("alt"); // Common version, no warning. + } else { + // Form field version, log warning. + } + this.alt = FlexibleStringExpander.getInstance(alt); + String urlMode = imageElement.getAttribute("url-mode"); + if (urlMode.isEmpty()) { + urlMode = "content"; + } + this.urlMode = urlMode; + String title = imageElement.getAttribute("image-title"); + if (title.isEmpty()) { + title = imageElement.getAttribute("title"); + } else { + // Form field version, log warning. + } + this.titleExdr = FlexibleStringExpander.getInstance(title); + } + + 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; + // FIXME: These don't belong in this class + 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 { + // TODO: Look for ModelFormField attributes + this.image = null; + } + 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.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.width = ""; + this.height = ""; + } + + public AutoEntityParameters getAutoEntityParameters() { + return autoEntityParameters; + } + + public AutoServiceParameters getAutoServiceParameters() { + return autoServiceParameters; + } + + 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) { + 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 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 <parameter> 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.DATE_FORMAT, timeZone, null); + returnValue = df.format((java.util.Date) retVal); + } else if (retVal instanceof java.sql.Time) { + DateFormat df = UtilDateTime.toTimeFormat(UtilDateTime.TIME_FORMAT, timeZone, null); + returnValue = df.format((java.util.Date) retVal); + } else if (retVal instanceof java.sql.Timestamp) { + DateFormat df = UtilDateTime.toDateTimeFormat(UtilDateTime.DATE_TIME_FORMAT, 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; + } + } + } +} Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/FieldInfo.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/FieldInfo.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/FieldInfo.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/FieldInfo.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,154 @@ +/******************************************************************************* + * 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.widget.model; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.ofbiz.base.util.Debug; +import org.ofbiz.widget.renderer.FormStringRenderer; +import org.w3c.dom.Element; + +/** + * Form field abstract class. + */ +public abstract class FieldInfo { + + public static final String module = FieldInfo.class.getName(); + + public static final int DISPLAY = 1; + public static final int HYPERLINK = 2; + public static final int TEXT = 3; + public static final int TEXTAREA = 4; + public static final int DATE_TIME = 5; + public static final int DROP_DOWN = 6; + public static final int CHECK = 7; + public static final int RADIO = 8; + public static final int SUBMIT = 9; + public static final int RESET = 10; + public static final int HIDDEN = 11; + public static final int IGNORED = 12; + public static final int TEXTQBE = 13; + public static final int DATEQBE = 14; + public static final int RANGEQBE = 15; + public static final int LOOKUP = 16; + public static final int FILE = 17; + public static final int PASSWORD = 18; + public static final int IMAGE = 19; + public static final int DISPLAY_ENTITY = 20; + // the numbering here represents the priority of the source; + //when setting a new fieldInfo on a modelFormField it will only set + //the new one if the fieldSource is less than or equal to the existing + //fieldSource, which should always be passed as one of the following... + public static final int SOURCE_EXPLICIT = 1; + public static final int SOURCE_AUTO_ENTITY = 2; + public static final int SOURCE_AUTO_SERVICE = 3; + private static Map<String, Integer> fieldTypeByName = createFieldTypeMap(); + + private static Map<String, Integer> createFieldTypeMap() { + Map<String, Integer> fieldTypeByName = new HashMap<String, Integer>(); + fieldTypeByName.put("display", Integer.valueOf(1)); + fieldTypeByName.put("hyperlink", Integer.valueOf(2)); + fieldTypeByName.put("text", Integer.valueOf(3)); + fieldTypeByName.put("textarea", Integer.valueOf(4)); + fieldTypeByName.put("date-time", Integer.valueOf(5)); + fieldTypeByName.put("drop-down", Integer.valueOf(6)); + fieldTypeByName.put("check", Integer.valueOf(7)); + fieldTypeByName.put("radio", Integer.valueOf(8)); + fieldTypeByName.put("submit", Integer.valueOf(9)); + fieldTypeByName.put("reset", Integer.valueOf(10)); + fieldTypeByName.put("hidden", Integer.valueOf(11)); + fieldTypeByName.put("ignored", Integer.valueOf(12)); + fieldTypeByName.put("text-find", Integer.valueOf(13)); + fieldTypeByName.put("date-find", Integer.valueOf(14)); + fieldTypeByName.put("range-find", Integer.valueOf(15)); + fieldTypeByName.put("lookup", Integer.valueOf(16)); + fieldTypeByName.put("file", Integer.valueOf(17)); + fieldTypeByName.put("password", Integer.valueOf(18)); + fieldTypeByName.put("image", Integer.valueOf(19)); + fieldTypeByName.put("display-entity", Integer.valueOf(20)); + fieldTypeByName.put("container", Integer.valueOf(21)); + return Collections.unmodifiableMap(fieldTypeByName); + } + + public static int findFieldTypeFromName(String name) { + Integer fieldTypeInt = FieldInfo.fieldTypeByName.get(name); + if (fieldTypeInt != null) { + return fieldTypeInt; + } else { + throw new IllegalArgumentException("Could not get fieldType for field type name " + name); + } + } + + private final int fieldType; + private final int fieldSource; + private final ModelFormField modelFormField; + + /** XML Constructor */ + protected FieldInfo(Element element, ModelFormField modelFormField) { + this.fieldSource = FieldInfo.SOURCE_EXPLICIT; + this.fieldType = findFieldTypeFromName(element.getTagName()); + this.modelFormField = modelFormField; + } + + /** Value Constructor */ + protected FieldInfo(int fieldSource, int fieldType, ModelFormField modelFormField) { + this.fieldType = fieldType; + this.fieldSource = fieldSource; + this.modelFormField = modelFormField; + } + + public abstract void accept(ModelFieldVisitor visitor) throws Exception; + + /** + * Returns a new instance of this object. + * + * @param modelFormField + */ + public abstract FieldInfo copy(ModelFormField modelFormField); + + public int getFieldSource() { + return fieldSource; + } + + public int getFieldType() { + return fieldType; + } + + public ModelFormField getModelFormField() { + return modelFormField; + } + + public abstract void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer) + throws IOException; + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + ModelFieldVisitor visitor = new XmlWidgetFieldVisitor(sb); + try { + accept(visitor); + } catch (Exception e) { + Debug.logWarning(e, "Exception thrown in XmlWidgetFieldVisitor: ", module); + } + return sb.toString(); + } +} Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/FormFactory.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/FormFactory.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/FormFactory.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/FormFactory.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,131 @@ +/******************************************************************************* + * 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.widget.model; + +import java.io.IOException; +import java.net.URL; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.xml.parsers.ParserConfigurationException; + +import org.ofbiz.base.location.FlexibleLocation; +import org.ofbiz.base.util.UtilHttp; +import org.ofbiz.base.util.UtilXml; +import org.ofbiz.base.util.cache.UtilCache; +import org.ofbiz.entity.Delegator; +import org.ofbiz.entity.model.ModelReader; +import org.ofbiz.service.DispatchContext; +import org.ofbiz.service.LocalDispatcher; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + + +/** + * Widget Library - Form factory class + */ +public class FormFactory { + + public static final String module = FormFactory.class.getName(); + private static final UtilCache<String, ModelForm> formLocationCache = UtilCache.createUtilCache("widget.form.locationResource", 0, 0, false); + private static final UtilCache<String, ModelForm> formWebappCache = UtilCache.createUtilCache("widget.form.webappResource", 0, 0, false); + + public static Map<String, ModelForm> getFormsFromLocation(String resourceName, ModelReader entityModelReader, DispatchContext dispatchContext) + throws IOException, SAXException, ParserConfigurationException { + URL formFileUrl = FlexibleLocation.resolveLocation(resourceName); + Document formFileDoc = UtilXml.readXmlDocument(formFileUrl, true, true); + return readFormDocument(formFileDoc, entityModelReader, dispatchContext, resourceName); + } + + public static ModelForm getFormFromLocation(String resourceName, String formName, ModelReader entityModelReader, DispatchContext dispatchContext) + throws IOException, SAXException, ParserConfigurationException { + StringBuilder sb = new StringBuilder(dispatchContext.getDelegator().getDelegatorName()); + sb.append(":").append(resourceName).append("#").append(formName); + String cacheKey = sb.toString(); + ModelForm modelForm = formLocationCache.get(cacheKey); + if (modelForm == null) { + URL formFileUrl = FlexibleLocation.resolveLocation(resourceName); + Document formFileDoc = UtilXml.readXmlDocument(formFileUrl, true, true); + if (formFileDoc == null) { + throw new IllegalArgumentException("Could not find resource [" + resourceName + "]"); + } + modelForm = createModelForm(formFileDoc, entityModelReader, dispatchContext, resourceName, formName); + modelForm = formLocationCache.putIfAbsentAndGet(cacheKey, modelForm); + } + if (modelForm == null) { + throw new IllegalArgumentException("Could not find form with name [" + formName + "] in class resource [" + resourceName + "]"); + } + return modelForm; + } + + public static ModelForm getFormFromWebappContext(String resourceName, String formName, HttpServletRequest request) + throws IOException, SAXException, ParserConfigurationException { + String webappName = UtilHttp.getApplicationName(request); + String cacheKey = webappName + "::" + resourceName + "::" + formName; + ModelForm modelForm = formWebappCache.get(cacheKey); + if (modelForm == null) { + ServletContext servletContext = (ServletContext) request.getAttribute("servletContext"); + Delegator delegator = (Delegator) request.getAttribute("delegator"); + LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); + URL formFileUrl = servletContext.getResource(resourceName); + Document formFileDoc = UtilXml.readXmlDocument(formFileUrl, true, true); + Element formElement = UtilXml.firstChildElement(formFileDoc.getDocumentElement(), "form", "name", formName); + modelForm = new ModelForm(formElement, resourceName, delegator.getModelReader(), dispatcher.getDispatchContext()); + modelForm = formWebappCache.putIfAbsentAndGet(cacheKey, modelForm); + } + if (modelForm == null) { + throw new IllegalArgumentException("Could not find form with name [" + formName + "] in webapp resource [" + resourceName + "] in the webapp [" + webappName + "]"); + } + return modelForm; + } + + public static Map<String, ModelForm> readFormDocument(Document formFileDoc, ModelReader entityModelReader, DispatchContext dispatchContext, String formLocation) { + Map<String, ModelForm> modelFormMap = new HashMap<String, ModelForm>(); + if (formFileDoc != null) { + // read document and construct ModelForm for each form element + Element rootElement = formFileDoc.getDocumentElement(); + List<? extends Element> formElements = UtilXml.childElementList(rootElement, "form"); + for (Element formElement : formElements) { + String formName = formElement.getAttribute("name"); + String cacheKey = formLocation + "#" + formName; + ModelForm modelForm = formLocationCache.get(cacheKey); + if (modelForm == null) { + modelForm = createModelForm(formElement, entityModelReader, dispatchContext, formLocation, formName); + modelForm = formLocationCache.putIfAbsentAndGet(cacheKey, modelForm); + } + modelFormMap.put(formName, modelForm); + } + } + return modelFormMap; + } + + public static ModelForm createModelForm(Document formFileDoc, ModelReader entityModelReader, DispatchContext dispatchContext, String formLocation, String formName) { + Element formElement = UtilXml.firstChildElement(formFileDoc.getDocumentElement(), "form", "name", formName); + return createModelForm(formElement, entityModelReader, dispatchContext, formLocation, formName); + } + + public static ModelForm createModelForm(Element formElement, ModelReader entityModelReader, DispatchContext dispatchContext, String formLocation, String formName) { + ModelForm modelForm = new ModelForm(formElement, formLocation, entityModelReader, dispatchContext); + return modelForm; + } +} Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/HtmlWidget.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/HtmlWidget.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/HtmlWidget.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/HtmlWidget.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,311 @@ +/******************************************************************************* + * 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.widget.model; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.ofbiz.base.util.Debug; +import org.ofbiz.base.util.GeneralException; +import org.ofbiz.base.util.UtilCodec; +import org.ofbiz.base.util.UtilGenerics; +import org.ofbiz.base.util.UtilValidate; +import org.ofbiz.base.util.UtilXml; +import org.ofbiz.base.util.cache.UtilCache; +import org.ofbiz.base.util.collections.MapStack; +import org.ofbiz.base.util.string.FlexibleStringExpander; +import org.ofbiz.base.util.template.FreeMarkerWorker; +import org.ofbiz.widget.renderer.ScreenRenderer; +import org.ofbiz.widget.renderer.ScreenStringRenderer; +import org.ofbiz.widget.renderer.html.HtmlWidgetRenderer; +import org.w3c.dom.Element; + +import freemarker.ext.beans.BeansWrapper; +import freemarker.ext.beans.CollectionModel; +import freemarker.ext.beans.StringModel; +import freemarker.template.Configuration; +import freemarker.template.Template; +import freemarker.template.TemplateException; +import freemarker.template.TemplateModel; +import freemarker.template.TemplateModelException; +import freemarker.template.Version; + +/** + * Widget Library - Screen model HTML class. + */ +@SuppressWarnings("serial") +public class HtmlWidget extends ModelScreenWidget { + public static final String module = HtmlWidget.class.getName(); + + private static final UtilCache<String, Template> specialTemplateCache = UtilCache.createUtilCache("widget.screen.template.ftl.general", 0, 0, false); + protected static Configuration specialConfig = FreeMarkerWorker.makeConfiguration(new ExtendedWrapper(FreeMarkerWorker.version)); + + // not sure if this is the best way to get FTL to use my fancy MapModel derivative, but should work at least... + public static class ExtendedWrapper extends BeansWrapper { + public ExtendedWrapper(Version version) { + super(version); + } + + @Override + public TemplateModel wrap(Object object) throws TemplateModelException { + // This StringHtmlWrapperForFtl option seems to be the best option + // and handles most things without causing too many problems + if (object instanceof String) { + return new StringHtmlWrapperForFtl((String) object, this); + } else if (object instanceof Collection && !(object instanceof Map)) { + // An additional wrapper to ensure ${aCollection} is properly encoded for html + return new CollectionHtmlWrapperForFtl((Collection<?>) object, this); + } + return super.wrap(object); + } + } + + public static class StringHtmlWrapperForFtl extends StringModel { + public StringHtmlWrapperForFtl(String str, BeansWrapper wrapper) { + super(str, wrapper); + } + @Override + public String getAsString() { + return UtilCodec.getEncoder("html").encode(super.getAsString()); + } + } + + public static class CollectionHtmlWrapperForFtl extends CollectionModel { + + public CollectionHtmlWrapperForFtl(Collection<?> collection, BeansWrapper wrapper) { + super(collection, wrapper); + } + + @Override + public String getAsString() { + return UtilCodec.getEncoder("html").encode(super.getAsString()); + } + + } + + // End Static, begin class section + + private final List<ModelScreenWidget> subWidgets; + + public HtmlWidget(ModelScreen modelScreen, Element htmlElement) { + super(modelScreen, htmlElement); + List<? extends Element> childElementList = UtilXml.childElementList(htmlElement); + if (childElementList.isEmpty()) { + this.subWidgets = Collections.emptyList(); + } else { + List<ModelScreenWidget> subWidgets = new ArrayList<ModelScreenWidget>(childElementList.size()); + for (Element childElement : childElementList) { + if ("html-template".equals(childElement.getNodeName())) { + subWidgets.add(new HtmlTemplate(modelScreen, childElement)); + } else if ("html-template-decorator".equals(childElement.getNodeName())) { + subWidgets.add(new HtmlTemplateDecorator(modelScreen, childElement)); + } else { + throw new IllegalArgumentException("Tag not supported under the platform-specific -> html tag with name: " + + childElement.getNodeName()); + } + } + this.subWidgets = Collections.unmodifiableList(subWidgets); + } + } + + public List<ModelScreenWidget> getSubWidgets() { + return subWidgets; + } + + @Override + public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException { + for (ModelScreenWidget subWidget : subWidgets) { + subWidget.renderWidgetString(writer, context, screenStringRenderer); + } + } + + public static void renderHtmlTemplate(Appendable writer, FlexibleStringExpander locationExdr, Map<String, Object> context) { + String location = locationExdr.expandString(context); + //Debug.logInfo("Rendering template at location [" + location + "] with context: \n" + context, module); + + if (UtilValidate.isEmpty(location)) { + throw new IllegalArgumentException("Template location is empty"); + } + + if (location.endsWith(".ftl")) { + try { + Map<String, ? extends Object> parameters = UtilGenerics.checkMap(context.get("parameters")); + boolean insertWidgetBoundaryComments = ModelWidget.widgetBoundaryCommentsEnabled(parameters); + if (insertWidgetBoundaryComments) { + writer.append(HtmlWidgetRenderer.formatBoundaryComment("Begin", "Template", location)); + } + + //FreeMarkerWorker.renderTemplateAtLocation(location, context, writer); + Template template = null; + if (location.endsWith(".fo.ftl")) { // FOP can't render correctly escaped characters + template = FreeMarkerWorker.getTemplate(location); + } else { + template = FreeMarkerWorker.getTemplate(location, specialTemplateCache, specialConfig); + } + FreeMarkerWorker.renderTemplate(template, context, writer); + + if (insertWidgetBoundaryComments) { + writer.append(HtmlWidgetRenderer.formatBoundaryComment("End", "Template", location)); + } + } catch (IllegalArgumentException e) { + String errMsg = "Error rendering included template at location [" + location + "]: " + e.toString(); + Debug.logError(e, errMsg, module); + writeError(writer, errMsg); + } catch (MalformedURLException e) { + String errMsg = "Error rendering included template at location [" + location + "]: " + e.toString(); + Debug.logError(e, errMsg, module); + writeError(writer, errMsg); + } catch (TemplateException e) { + String errMsg = "Error rendering included template at location [" + location + "]: " + e.toString(); + Debug.logError(e, errMsg, module); + writeError(writer, errMsg); + } catch (IOException e) { + String errMsg = "Error rendering included template at location [" + location + "]: " + e.toString(); + Debug.logError(e, errMsg, module); + writeError(writer, errMsg); + } + } else { + throw new IllegalArgumentException("Rendering not yet supported for the template at location: " + location); + } + } + + // TODO: We can make this more fancy, but for now this is very functional + public static void writeError(Appendable writer, String message) { + try { + writer.append(message); + } catch (IOException e) { + } + } + + public static class HtmlTemplate extends ModelScreenWidget { + protected FlexibleStringExpander locationExdr; + + public HtmlTemplate(ModelScreen modelScreen, Element htmlTemplateElement) { + super(modelScreen, htmlTemplateElement); + this.locationExdr = FlexibleStringExpander.getInstance(htmlTemplateElement.getAttribute("location")); + } + + public String getLocation(Map<String, Object> context) { + return locationExdr.expandString(context); + } + + @Override + public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) { + renderHtmlTemplate(writer, this.locationExdr, context); + } + + @Override + public void accept(ModelWidgetVisitor visitor) throws Exception { + visitor.visit(this); + } + + public FlexibleStringExpander getLocationExdr() { + return locationExdr; + } + } + + public static class HtmlTemplateDecorator extends ModelScreenWidget { + protected FlexibleStringExpander locationExdr; + protected Map<String, ModelScreenWidget> sectionMap = new HashMap<String, ModelScreenWidget>(); + + public HtmlTemplateDecorator(ModelScreen modelScreen, Element htmlTemplateDecoratorElement) { + super(modelScreen, htmlTemplateDecoratorElement); + this.locationExdr = FlexibleStringExpander.getInstance(htmlTemplateDecoratorElement.getAttribute("location")); + + List<? extends Element> htmlTemplateDecoratorSectionElementList = UtilXml.childElementList(htmlTemplateDecoratorElement, "html-template-decorator-section"); + for (Element htmlTemplateDecoratorSectionElement: htmlTemplateDecoratorSectionElementList) { + String name = htmlTemplateDecoratorSectionElement.getAttribute("name"); + this.sectionMap.put(name, new HtmlTemplateDecoratorSection(modelScreen, htmlTemplateDecoratorSectionElement)); + } + } + + @Override + public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) { + // isolate the scope + MapStack<String> contextMs; + if (!(context instanceof MapStack<?>)) { + contextMs = MapStack.create(context); + context = contextMs; + } else { + contextMs = UtilGenerics.cast(context); + } + + // create a standAloneStack, basically a "save point" for this SectionsRenderer, and make a new "screens" object just for it so it is isolated and doesn't follow the stack down + MapStack<String> standAloneStack = contextMs.standAloneChildStack(); + standAloneStack.put("screens", new ScreenRenderer(writer, standAloneStack, screenStringRenderer)); + SectionsRenderer sections = new SectionsRenderer(this.sectionMap, standAloneStack, writer, screenStringRenderer); + + // put the sectionMap in the context, make sure it is in the sub-scope, ie after calling push on the MapStack + contextMs.push(); + context.put("sections", sections); + + renderHtmlTemplate(writer, this.locationExdr, context); + contextMs.pop(); + } + + @Override + public void accept(ModelWidgetVisitor visitor) throws Exception { + visitor.visit(this); + } + + public FlexibleStringExpander getLocationExdr() { + return locationExdr; + } + + public Map<String, ModelScreenWidget> getSectionMap() { + return sectionMap; + } + } + + public static class HtmlTemplateDecoratorSection extends ModelScreenWidget { + protected List<ModelScreenWidget> subWidgets; + + public HtmlTemplateDecoratorSection(ModelScreen modelScreen, Element htmlTemplateDecoratorSectionElement) { + super(modelScreen, htmlTemplateDecoratorSectionElement); + List<? extends Element> subElementList = UtilXml.childElementList(htmlTemplateDecoratorSectionElement); + this.subWidgets = ModelScreenWidget.readSubWidgets(getModelScreen(), subElementList); + } + + @Override + public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException { + // render sub-widgets + renderSubWidgetsString(this.subWidgets, writer, context, screenStringRenderer); + } + + @Override + public void accept(ModelWidgetVisitor visitor) throws Exception { + visitor.visit(this); + } + + public List<ModelScreenWidget> getSubWidgets() { + return subWidgets; + } + } + + @Override + public void accept(ModelWidgetVisitor visitor) throws Exception { + visitor.visit(this); + } +} Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/IterateSectionWidget.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/IterateSectionWidget.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/IterateSectionWidget.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/IterateSectionWidget.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,387 @@ +/******************************************************************************* + * 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.widget.model; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.ofbiz.base.util.Debug; +import org.ofbiz.base.util.GeneralException; +import org.ofbiz.base.util.UtilGenerics; +import org.ofbiz.base.util.UtilHttp; +import org.ofbiz.base.util.UtilMisc; +import org.ofbiz.base.util.UtilProperties; +import org.ofbiz.base.util.UtilValidate; +import org.ofbiz.base.util.UtilXml; +import org.ofbiz.base.util.collections.FlexibleMapAccessor; +import org.ofbiz.base.util.collections.MapStack; +import org.ofbiz.base.util.string.FlexibleStringExpander; +import org.ofbiz.webapp.control.RequestHandler; +import org.ofbiz.widget.WidgetWorker; +import org.ofbiz.widget.renderer.ScreenStringRenderer; +import org.w3c.dom.Element; + + +/** + * Widget Library - Screen model HTML class + */ +@SuppressWarnings("serial") +public class IterateSectionWidget extends ModelScreenWidget { + + public static final String module = IterateSectionWidget.class.getName(); + public static int DEFAULT_PAGE_SIZE = 5; + public static int MAX_PAGE_SIZE = 10000; + + private final List<ModelScreenWidget.Section> sectionList; + private final FlexibleMapAccessor<Object> listNameExdr; + private final FlexibleStringExpander entryNameExdr; + private final FlexibleStringExpander keyNameExdr; + private final FlexibleStringExpander paginateTarget; + private final FlexibleStringExpander paginate; + private final int viewSize; + + public IterateSectionWidget(ModelScreen modelScreen, Element iterateSectionElement) { + super(modelScreen, iterateSectionElement); + String listName = iterateSectionElement.getAttribute("list"); + if (listName.isEmpty()) { + listName = iterateSectionElement.getAttribute("list-name"); + } + this.listNameExdr = FlexibleMapAccessor.getInstance(listName); + String entryName = iterateSectionElement.getAttribute("entry"); + if (entryName.isEmpty()) { + entryName = iterateSectionElement.getAttribute("entry-name"); + } + this.entryNameExdr = FlexibleStringExpander.getInstance(entryName); + String keyName = iterateSectionElement.getAttribute("key"); + if (keyName.isEmpty()) { + keyName = iterateSectionElement.getAttribute("key-name"); + } + this.keyNameExdr = FlexibleStringExpander.getInstance(keyName); + this.paginateTarget = FlexibleStringExpander.getInstance(iterateSectionElement.getAttribute("paginate-target")); + this.paginate = FlexibleStringExpander.getInstance(iterateSectionElement.getAttribute("paginate")); + int viewSize = DEFAULT_PAGE_SIZE; + String viewSizeStr = iterateSectionElement.getAttribute("view-size"); + if (!viewSizeStr.isEmpty()) { + viewSize = Integer.parseInt(viewSizeStr); + } + this.viewSize = viewSize; + List<? extends Element> childElementList = UtilXml.childElementList(iterateSectionElement); + if (childElementList.isEmpty()) { + this.sectionList = Collections.emptyList(); + } else { + List<ModelScreenWidget.Section> sectionList = new ArrayList<ModelScreenWidget.Section>(childElementList.size()); + for (Element sectionElement: childElementList) { + ModelScreenWidget.Section section = new ModelScreenWidget.Section(modelScreen, sectionElement, false); + sectionList.add(section); + } + this.sectionList = Collections.unmodifiableList(sectionList); + } + } + + public List<ModelScreenWidget.Section> getSectionList() { + return sectionList; + } + + @Override + public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException { + int viewIndex = 0; + int viewSize = this.viewSize; + int lowIndex = -1; + int highIndex = -1; + int listSize = 0; + int actualPageSize = 0; + + boolean isEntrySet = false; + // create a standAloneStack, basically a "save point" for this SectionsRenderer, and make a new "screens" object just for it so it is isolated and doesn't follow the stack down + MapStack<String> contextMs = MapStack.create(context); + + String entryName = this.entryNameExdr.expandString(context); + String keyName = this.keyNameExdr.expandString(context); + Object obj = listNameExdr.get(context); + if (obj == null) { + Debug.logError("No object found for listName:" + listNameExdr.toString(), module); + return; + } + List<?> theList = null; + if (obj instanceof Map<?, ?>) { + Set<Map.Entry<String, Object>> entrySet = UtilGenerics.<Map<String, Object>>cast(obj).entrySet(); + Object [] a = entrySet.toArray(); + theList = Arrays.asList(a); + isEntrySet = true; + } else if (obj instanceof List<?>) { + theList = (List<?>)obj; + } else { + Debug.logError("Object not list or map type", module); + return; + } + listSize = theList.size(); + WidgetWorker.incrementPaginatorNumber(context); + int startPageNumber = WidgetWorker.getPaginatorNumber(context); + + if (getPaginate(context)) { + try { + Map<String, String> params = UtilGenerics.cast(context.get("parameters")); + String viewIndexString = params.get("VIEW_INDEX" + "_" + WidgetWorker.getPaginatorNumber(context)); + String viewSizeString = params.get("VIEW_SIZE" + "_" + WidgetWorker.getPaginatorNumber(context)); + viewIndex = Integer.parseInt(viewIndexString); + viewSize = Integer.parseInt(viewSizeString); + } catch (Exception e) { + try { + viewIndex = ((Integer) context.get("viewIndex")).intValue(); + } catch (Exception e2) { + viewIndex = 0; + } + } + context.put("viewIndex", Integer.valueOf(viewIndex)); + lowIndex = viewIndex * viewSize; + highIndex = (viewIndex + 1) * viewSize; + } else { + viewIndex = 0; + viewSize = MAX_PAGE_SIZE; + lowIndex = 0; + highIndex = MAX_PAGE_SIZE; + } + Iterator<?> iter = theList.iterator(); + int itemIndex = -1; + int iterateIndex = 0; + while (iter.hasNext()) { + itemIndex++; + if (itemIndex >= highIndex) { + break; + } + Object item = iter.next(); + if (itemIndex < lowIndex) { + continue; + } + if (isEntrySet) { + Map.Entry<String, ?> entry = UtilGenerics.cast(item); + contextMs.put(entryName, entry.getValue()); + contextMs.put(keyName, entry.getKey()); + } else { + contextMs.put(entryName, item); + } + contextMs.put("itemIndex", Integer.valueOf(itemIndex)); + + if (iterateIndex < listSize) { + contextMs.put("iterateId",String.valueOf(entryName+iterateIndex)); + iterateIndex++; + } + for (ModelScreenWidget.Section section: this.sectionList) { + section.renderWidgetString(writer, contextMs, screenStringRenderer); + } + } + + if ((itemIndex + 1) < highIndex) { + highIndex = itemIndex + 1; + } + actualPageSize = highIndex - lowIndex; + if (getPaginate(context)) { + try { + Integer lastPageNumber = null; + Map<String, Object> globalCtx = UtilGenerics.checkMap(context.get("globalContext")); + if (globalCtx != null) { + lastPageNumber = (Integer)globalCtx.get("PAGINATOR_NUMBER"); + globalCtx.put("PAGINATOR_NUMBER", Integer.valueOf(startPageNumber)); + } + renderNextPrev(writer, context, listSize, actualPageSize); + if (globalCtx != null) { + globalCtx.put("PAGINATOR_NUMBER", lastPageNumber); + } + } catch (IOException e) { + Debug.logError(e, module); + throw new RuntimeException(e.getMessage()); + } + } + + } + /* + * @return + */ + public String getPaginateTarget(Map<String, Object> context) { + return this.paginateTarget.expandString(context); + } + + public boolean getPaginate(Map<String, Object> context) { + if (!this.paginate.isEmpty() && UtilValidate.isNotEmpty(this.paginate.expandString(context))) { + return Boolean.valueOf(this.paginate.expandString(context)).booleanValue(); + } else { + return true; + } + } + + public int getViewSize() { + return viewSize; + } + + public void renderNextPrev(Appendable writer, Map<String, Object> context, int listSize, int actualPageSize) throws IOException { + String targetService = this.getPaginateTarget(context); + if (targetService == null) { + targetService = "${targetService}"; + } + + Map<String, Object> inputFields = UtilGenerics.checkMap(context.get("requestParameters")); + Map<String, Object> queryStringMap = UtilGenerics.toMap(context.get("queryStringMap")); + if (UtilValidate.isNotEmpty(queryStringMap)) { + inputFields.putAll(queryStringMap); + } + + String queryString = UtilHttp.urlEncodeArgs(inputFields); + int paginatorNumber = WidgetWorker.getPaginatorNumber(context); + queryString = UtilHttp.stripViewParamsFromQueryString(queryString, "" + paginatorNumber); + + + + + if (UtilValidate.isEmpty(targetService)) { + Debug.logWarning("TargetService is empty.", module); + return; + } + + int viewIndex = -1; + try { + viewIndex = ((Integer) context.get("viewIndex")).intValue(); + } catch (Exception e) { + viewIndex = 0; + } + + int viewSize = -1; + try { + viewSize = ((Integer) context.get("viewSize")).intValue(); + } catch (Exception e) { + viewSize = this.getViewSize(); + } + + + /* + int highIndex = -1; + try { + highIndex = modelForm.getHighIndex(); + } catch (Exception e) { + highIndex = 0; + } + + int lowIndex = -1; + try { + lowIndex = modelForm.getLowIndex(); + } catch (Exception e) { + lowIndex = 0; + } + */ + + int lowIndex = viewIndex * viewSize; + int highIndex = (viewIndex + 1) * viewSize; + // if this is all there seems to be (if listSize < 0, then size is unknown) + if (actualPageSize >= listSize && listSize > 0) { + return; + } + + HttpServletRequest request = (HttpServletRequest) context.get("request"); + HttpServletResponse response = (HttpServletResponse) context.get("response"); + + ServletContext ctx = (ServletContext) request.getAttribute("servletContext"); + RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_"); + + writer.append("<table border=\"0\" width=\"100%\" cellpadding=\"2\">\n"); + writer.append(" <tr>\n"); + writer.append(" <td align=\"right\">\n"); + writer.append(" <b>\n"); + if (viewIndex > 0) { + writer.append(" <a href=\""); + StringBuilder linkText = new StringBuilder(targetService); + if (linkText.indexOf("?") < 0) linkText.append("?"); + else linkText.append("&"); + //if (queryString != null && !queryString.equals("null")) linkText += queryString + "&"; + if (UtilValidate.isNotEmpty(queryString)) { + linkText.append(queryString).append("&"); + } + linkText.append("VIEW_SIZE_"+ paginatorNumber + "=").append(viewSize).append("&VIEW_INDEX_" + paginatorNumber + "=").append(viewIndex - 1).append("\""); + + // make the link + writer.append(rh.makeLink(request, response, linkText.toString(), false, false, false)); + String previous = UtilProperties.getMessage("CommonUiLabels", "CommonPrevious", (Locale) context.get("locale")); + writer.append(" class=\"buttontext\">[").append(previous).append("]</a>\n"); + + } + if (listSize > 0) { + Map<String, Integer> messageMap = UtilMisc.toMap("lowCount", Integer.valueOf(lowIndex + 1), "highCount", Integer.valueOf(lowIndex + actualPageSize), "total", Integer.valueOf(listSize)); + String commonDisplaying = UtilProperties.getMessage("CommonUiLabels", "CommonDisplaying", messageMap, (Locale) context.get("locale")); + writer.append(" <span class=\"tabletext\">").append(commonDisplaying).append("</span> \n"); + } + if (highIndex < listSize) { + writer.append(" <a href=\""); + StringBuilder linkText = new StringBuilder(targetService); + if (linkText.indexOf("?") < 0) linkText.append("?"); + else linkText.append("&"); + if (UtilValidate.isNotEmpty(queryString)) { + linkText.append(queryString).append("&"); + } + linkText.append("VIEW_SIZE_" + paginatorNumber + "=").append(viewSize).append("&VIEW_INDEX_" + paginatorNumber + "=").append(viewIndex + 1).append("\""); + + // make the link + writer.append(rh.makeLink(request, response, linkText.toString(), false, false, false)); + String next = UtilProperties.getMessage("CommonUiLabels", "CommonNext", (Locale) context.get("locale")); + writer.append(" class=\"buttontext\">[").append(next).append("]</a>\n"); + + } + writer.append(" </b>\n"); + writer.append(" </td>\n"); + writer.append(" </tr>\n"); + writer.append("</table>\n"); + + } + + @Override + public void accept(ModelWidgetVisitor visitor) throws Exception { + visitor.visit(this); + } + + public FlexibleMapAccessor<Object> getListNameExdr() { + return listNameExdr; + } + + public FlexibleStringExpander getEntryNameExdr() { + return entryNameExdr; + } + + public FlexibleStringExpander getKeyNameExdr() { + return keyNameExdr; + } + + public FlexibleStringExpander getPaginateTarget() { + return paginateTarget; + } + + public FlexibleStringExpander getPaginate() { + return paginate; + } + +} + + Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/MenuFactory.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/MenuFactory.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/MenuFactory.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/MenuFactory.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,118 @@ +/******************************************************************************* + * 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.widget.model; + +import java.io.IOException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.xml.parsers.ParserConfigurationException; + +import org.ofbiz.base.location.FlexibleLocation; +import org.ofbiz.base.util.UtilHttp; +import org.ofbiz.base.util.UtilValidate; +import org.ofbiz.base.util.UtilXml; +import org.ofbiz.base.util.cache.UtilCache; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + + +/** + * Widget Library - Menu factory class + */ +public class MenuFactory { + + public static final String module = MenuFactory.class.getName(); + + public static final UtilCache<String, Map<String, ModelMenu>> menuWebappCache = UtilCache.createUtilCache("widget.menu.webappResource", 0, 0, false); + public static final UtilCache<String, Map<String, ModelMenu>> menuLocationCache = UtilCache.createUtilCache("widget.menu.locationResource", 0, 0, false); + + public static ModelMenu getMenuFromWebappContext(String resourceName, String menuName, HttpServletRequest request) + throws IOException, SAXException, ParserConfigurationException { + String webappName = UtilHttp.getApplicationName(request); + String cacheKey = webappName + "::" + resourceName; + + Map<String, ModelMenu> modelMenuMap = menuWebappCache.get(cacheKey); + if (modelMenuMap == null) { + synchronized (MenuFactory.class) { + modelMenuMap = menuWebappCache.get(cacheKey); + if (modelMenuMap == null) { + ServletContext servletContext = (ServletContext) request.getAttribute("servletContext"); + + URL menuFileUrl = servletContext.getResource(resourceName); + Document menuFileDoc = UtilXml.readXmlDocument(menuFileUrl, true, true); + modelMenuMap = readMenuDocument(menuFileDoc, cacheKey); + menuWebappCache.put(cacheKey, modelMenuMap); + } + } + } + + if (UtilValidate.isEmpty(modelMenuMap)) { + throw new IllegalArgumentException("Could not find menu file in webapp resource [" + resourceName + "] in the webapp [" + webappName + "]"); + } + + ModelMenu modelMenu = modelMenuMap.get(menuName); + if (modelMenu == null) { + throw new IllegalArgumentException("Could not find menu with name [" + menuName + "] in webapp resource [" + resourceName + "] in the webapp [" + webappName + "]"); + } + return modelMenu; + } + + public static Map<String, ModelMenu> readMenuDocument(Document menuFileDoc, String menuLocation) { + Map<String, ModelMenu> modelMenuMap = new HashMap<String, ModelMenu>(); + if (menuFileDoc != null) { + // read document and construct ModelMenu for each menu element + Element rootElement = menuFileDoc.getDocumentElement(); + for (Element menuElement: UtilXml.childElementList(rootElement, "menu")){ + ModelMenu modelMenu = new ModelMenu(menuElement, menuLocation); + modelMenuMap.put(modelMenu.getName(), modelMenu); + } + } + return modelMenuMap; + } + + public static ModelMenu getMenuFromLocation(String resourceName, String menuName) throws IOException, SAXException, ParserConfigurationException { + Map<String, ModelMenu> modelMenuMap = menuLocationCache.get(resourceName); + if (modelMenuMap == null) { + synchronized (MenuFactory.class) { + modelMenuMap = menuLocationCache.get(resourceName); + if (modelMenuMap == null) { + URL menuFileUrl = FlexibleLocation.resolveLocation(resourceName); + Document menuFileDoc = UtilXml.readXmlDocument(menuFileUrl, true, true); + modelMenuMap = readMenuDocument(menuFileDoc, resourceName); + menuLocationCache.put(resourceName, modelMenuMap); + } + } + } + + if (UtilValidate.isEmpty(modelMenuMap)) { + throw new IllegalArgumentException("Could not find menu file in location [" + resourceName + "]"); + } + + ModelMenu modelMenu = modelMenuMap.get(menuName); + if (modelMenu == null) { + throw new IllegalArgumentException("Could not find menu with name [" + menuName + "] in location [" + resourceName + "]"); + } + return modelMenu; + } +} Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelAction.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelAction.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelAction.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelAction.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,36 @@ +/******************************************************************************* + * 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.widget.model; + +import java.util.Map; + +import org.ofbiz.base.util.GeneralException; + +public interface ModelAction { + + void accept(ModelActionVisitor visitor) throws Exception; + + /** + * Executes this action. + * + * @param context + * @throws GeneralException + */ + void runAction(Map<String, Object> context) throws GeneralException; +} Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelActionVisitor.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelActionVisitor.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelActionVisitor.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelActionVisitor.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,59 @@ +/******************************************************************************* + * 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") throws Exception ; 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.widget.model; + +/** + * A <code>ModelAction</code> visitor. + */ +public interface ModelActionVisitor { + + void visit(ModelFormAction.CallParentActions callParentActions) throws Exception; + + void visit(AbstractModelAction.EntityAnd entityAnd) throws Exception; + + void visit(AbstractModelAction.EntityCondition entityCondition) throws Exception; + + void visit(AbstractModelAction.EntityOne entityOne) throws Exception; + + void visit(AbstractModelAction.GetRelated getRelated) throws Exception; + + void visit(AbstractModelAction.GetRelatedOne getRelatedOne) throws Exception; + + void visit(AbstractModelAction.PropertyMap propertyMap) throws Exception; + + void visit(AbstractModelAction.PropertyToField propertyToField) throws Exception; + + void visit(AbstractModelAction.Script script) throws Exception; + + void visit(AbstractModelAction.Service service) throws Exception; + + void visit(AbstractModelAction.SetField setField) throws Exception; + + void visit(ModelFormAction.Service service) throws Exception; + + void visit(ModelMenuAction.SetField setField) throws Exception; + + void visit(ModelTreeAction.Script script) throws Exception; + + void visit(ModelTreeAction.Service service) throws Exception; + + void visit(ModelTreeAction.EntityAnd entityAnd) throws Exception; + + void visit(ModelTreeAction.EntityCondition entityCondition) throws Exception; +} Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelCondition.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelCondition.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelCondition.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelCondition.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,28 @@ +/******************************************************************************* + * 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.widget.model; + +import java.util.Map; + +public interface ModelCondition { + + void accept(ModelConditionVisitor visitor) throws Exception; + + boolean eval(Map<String, Object> context); +} |
Free forum by Nabble | Edit this page |