Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelMenuItem.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelMenuItem.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelMenuItem.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelMenuItem.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,669 @@ +/******************************************************************************* + * 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.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import org.ofbiz.base.util.Debug; +import org.ofbiz.base.util.UtilValidate; +import org.ofbiz.base.util.UtilXml; +import org.ofbiz.base.util.string.FlexibleStringExpander; +import org.ofbiz.entity.GenericValue; +import org.ofbiz.widget.model.CommonWidgetModels.AutoEntityParameters; +import org.ofbiz.widget.model.CommonWidgetModels.AutoServiceParameters; +import org.ofbiz.widget.model.CommonWidgetModels.Image; +import org.ofbiz.widget.model.CommonWidgetModels.Link; +import org.ofbiz.widget.model.CommonWidgetModels.Parameter; +import org.ofbiz.widget.portal.PortalPageWorker; +import org.ofbiz.widget.renderer.MenuStringRenderer; +import org.w3c.dom.Element; + +/** + * Models the <menu-item> element. + * + * @see <code>widget-menu.xsd</code> + */ +@SuppressWarnings("serial") +public class ModelMenuItem extends ModelWidget { + + /* + * ----------------------------------------------------------------------- * + * DEVELOPERS PLEASE READ + * ----------------------------------------------------------------------- * + * + * This model is intended to be a read-only data structure that represents + * an XML element. Outside of object construction, the class should not + * have any behaviors. + * + * Instances of this class will be shared by multiple threads - therefore + * it is immutable. DO NOT CHANGE THE OBJECT'S STATE AT RUN TIME! + * + */ + + public static final String module = ModelMenuItem.class.getName(); + + private final List<ModelAction> actions; + private final String align; + private final String alignStyle; + private final FlexibleStringExpander associatedContentId; + private final String cellWidth; + private final ModelMenuCondition condition; + private final String disabledTitleStyle; + private final String disableIfEmpty; + private final String entityName; + private final Boolean hideIfSelected; + private final MenuLink link; + private final List<ModelMenuItem> menuItemList; + private final ModelMenu modelMenu; + private final String overrideName; + private final ModelMenuItem parentMenuItem; + private final FlexibleStringExpander parentPortalPageId; + private final Integer position; + private final String selectedStyle; + private final String subMenu; + private final FlexibleStringExpander title; + private final String titleStyle; + private final FlexibleStringExpander tooltip; + private final String tooltipStyle; + private final String widgetStyle; + + // ===== CONSTRUCTORS ===== + + public ModelMenuItem(Element menuItemElement, ModelMenu modelMenu) { + this(menuItemElement, modelMenu, null); + } + + private ModelMenuItem(Element menuItemElement, ModelMenu modelMenu, ModelMenuItem parentMenuItem) { + super(menuItemElement); + this.modelMenu = modelMenu; + this.parentMenuItem = parentMenuItem; + this.entityName = menuItemElement.getAttribute("entity-name"); + this.title = FlexibleStringExpander.getInstance(menuItemElement.getAttribute("title")); + this.tooltip = FlexibleStringExpander.getInstance(menuItemElement.getAttribute("tooltip")); + this.parentPortalPageId = FlexibleStringExpander.getInstance(menuItemElement.getAttribute("parent-portal-page-value")); + this.titleStyle = menuItemElement.getAttribute("title-style"); + this.disabledTitleStyle = menuItemElement.getAttribute("disabled-title-style"); + this.widgetStyle = menuItemElement.getAttribute("widget-style"); + this.tooltipStyle = menuItemElement.getAttribute("tooltip-style"); + this.selectedStyle = menuItemElement.getAttribute("selected-style"); + String hideIfSelected = menuItemElement.getAttribute("hide-if-selected"); + if (!hideIfSelected.isEmpty()) + if (hideIfSelected.equalsIgnoreCase("true")) + this.hideIfSelected = Boolean.TRUE; + else + this.hideIfSelected = Boolean.FALSE; + else + this.hideIfSelected = null; + this.disableIfEmpty = menuItemElement.getAttribute("disable-if-empty"); + this.align = menuItemElement.getAttribute("align"); + this.alignStyle = menuItemElement.getAttribute("align-style"); + Integer position = null; + String positionStr = menuItemElement.getAttribute("position"); + if (!positionStr.isEmpty()) { + try { + position = Integer.valueOf(positionStr); + } catch (Exception e) { + Debug.logError(e, "Could not convert position attribute of the field element to an integer: [" + positionStr + + "], using the default of the menu renderer", module); + position = null; + } + } + this.position = position; + this.associatedContentId = FlexibleStringExpander.getInstance(menuItemElement.getAttribute("associated-content-id")); + this.cellWidth = menuItemElement.getAttribute("cell-width"); + this.subMenu = menuItemElement.getAttribute("sub-menu"); + Element linkElement = UtilXml.firstChildElement(menuItemElement, "link"); + if (linkElement != null) { + this.link = new MenuLink(linkElement, this); + } else { + this.link = null; + } + // read in add item defs, add/override one by one using the menuItemList and menuItemMap + List<? extends Element> itemElements = UtilXml.childElementList(menuItemElement, "menu-item"); + if (!itemElements.isEmpty()) { + ArrayList<ModelMenuItem> menuItemList = new ArrayList<ModelMenuItem>(); + Map<String, ModelMenuItem> menuItemMap = new HashMap<String, ModelMenuItem>(); + for (Element itemElement : itemElements) { + ModelMenuItem modelMenuItem = new ModelMenuItem(itemElement, modelMenu, this); + addUpdateMenuItem(modelMenuItem, menuItemList, menuItemMap); + } + menuItemList.trimToSize(); + this.menuItemList = Collections.unmodifiableList(menuItemList); + } else { + this.menuItemList = Collections.emptyList(); + } + // read condition under the "condition" element + Element conditionElement = UtilXml.firstChildElement(menuItemElement, "condition"); + if (conditionElement != null) { + conditionElement = UtilXml.firstChildElement(conditionElement); + this.condition = new ModelMenuCondition(this, conditionElement); + } else { + this.condition = null; + } + // read all actions under the "actions" element + Element actionsElement = UtilXml.firstChildElement(conditionElement, "actions"); + if (actionsElement != null) { + this.actions = AbstractModelAction.readSubActions(this, actionsElement); + } else { + this.actions = Collections.emptyList(); + } + this.overrideName = ""; + } + + // Portal constructor + private ModelMenuItem(GenericValue portalPage, ModelMenuItem parentMenuItem, Locale locale) { + super(portalPage.getString("portalPageId")); + this.actions = Collections.emptyList(); + this.align = ""; + this.alignStyle = ""; + this.associatedContentId = FlexibleStringExpander.getInstance(""); + this.cellWidth = ""; + this.condition = null; + this.disabledTitleStyle = ""; + this.disableIfEmpty = ""; + this.entityName = ""; + this.hideIfSelected = null; + this.menuItemList = Collections.emptyList(); + this.overrideName = ""; + this.parentMenuItem = null; + this.parentPortalPageId = FlexibleStringExpander.getInstance(portalPage.getString("parentPortalPageId")); + this.position = null; + this.selectedStyle = ""; + this.subMenu = ""; + this.title = FlexibleStringExpander.getInstance((String) portalPage.get("portalPageName", locale)); + this.titleStyle = ""; + this.tooltip = FlexibleStringExpander.getInstance(""); + this.tooltipStyle = ""; + this.widgetStyle = ""; + this.link = new MenuLink(portalPage, parentMenuItem, locale); + this.modelMenu = parentMenuItem.modelMenu; + } + + // Merge constructor + private ModelMenuItem(ModelMenuItem existingMenuItem, ModelMenuItem overrideMenuItem) { + super(existingMenuItem.getName()); + this.modelMenu = existingMenuItem.modelMenu; + if (UtilValidate.isNotEmpty(overrideMenuItem.getName())) { + this.overrideName = overrideMenuItem.getName(); + } else { + this.overrideName = existingMenuItem.getName(); + } + if (UtilValidate.isNotEmpty(overrideMenuItem.entityName)) { + this.entityName = overrideMenuItem.entityName; + } else { + this.entityName = existingMenuItem.entityName; + } + if (UtilValidate.isNotEmpty(overrideMenuItem.parentPortalPageId)) { + this.parentPortalPageId = overrideMenuItem.parentPortalPageId; + } else { + this.parentPortalPageId = existingMenuItem.parentPortalPageId; + } + if (UtilValidate.isNotEmpty(overrideMenuItem.title)) { + this.title = overrideMenuItem.title; + } else { + this.title = existingMenuItem.title; + } + if (UtilValidate.isNotEmpty(overrideMenuItem.tooltip)) { + this.tooltip = overrideMenuItem.tooltip; + } else { + this.tooltip = existingMenuItem.tooltip; + } + if (UtilValidate.isNotEmpty(overrideMenuItem.titleStyle)) { + this.titleStyle = overrideMenuItem.titleStyle; + } else { + this.titleStyle = existingMenuItem.titleStyle; + } + if (UtilValidate.isNotEmpty(overrideMenuItem.selectedStyle)) { + this.selectedStyle = overrideMenuItem.selectedStyle; + } else { + this.selectedStyle = existingMenuItem.selectedStyle; + } + if (UtilValidate.isNotEmpty(overrideMenuItem.widgetStyle)) { + this.widgetStyle = overrideMenuItem.widgetStyle; + } else { + this.widgetStyle = existingMenuItem.widgetStyle; + } + if (overrideMenuItem.position != null) { + this.position = overrideMenuItem.position; + } else { + this.position = existingMenuItem.position; + } + this.actions = existingMenuItem.actions; + this.align = existingMenuItem.align; + this.alignStyle = existingMenuItem.alignStyle; + this.associatedContentId = existingMenuItem.associatedContentId; + this.cellWidth = existingMenuItem.cellWidth; + this.condition = existingMenuItem.condition; + this.disabledTitleStyle = existingMenuItem.disabledTitleStyle; + this.disableIfEmpty = existingMenuItem.disableIfEmpty; + this.hideIfSelected = existingMenuItem.hideIfSelected; + this.menuItemList = existingMenuItem.menuItemList; + this.parentMenuItem = existingMenuItem.parentMenuItem; + this.subMenu = existingMenuItem.subMenu; + this.tooltipStyle = existingMenuItem.tooltipStyle; + this.link = existingMenuItem.link; + } + + @Override + public void accept(ModelWidgetVisitor visitor) throws Exception { + visitor.visit(this); + } + + private void addUpdateMenuItem(ModelMenuItem modelMenuItem, List<ModelMenuItem> menuItemList, + Map<String, ModelMenuItem> menuItemMap) { + ModelMenuItem existingMenuItem = menuItemMap.get(modelMenuItem.getName()); + if (existingMenuItem != null) { + // does exist, update the item by doing a merge/override + ModelMenuItem mergedMenuItem = existingMenuItem.mergeOverrideModelMenuItem(modelMenuItem); + int existingItemIndex = menuItemList.indexOf(existingMenuItem); + menuItemList.set(existingItemIndex, mergedMenuItem); + menuItemMap.put(modelMenuItem.getName(), mergedMenuItem); + } else { + // does not exist, add to List and Map + menuItemList.add(modelMenuItem); + menuItemMap.put(modelMenuItem.getName(), modelMenuItem); + } + } + + public List<ModelAction> getActions() { + return actions; + } + + public String getAlign() { + if (!this.align.isEmpty()) { + return this.align; + } else if (parentMenuItem != null) { + return parentMenuItem.getAlign(); + } else { + return this.modelMenu.getDefaultAlign(); + } + } + + public String getAlignStyle() { + if (!this.alignStyle.isEmpty()) { + return this.alignStyle; + } else if (parentMenuItem != null) { + return parentMenuItem.getAlignStyle(); + } else { + return this.modelMenu.getDefaultAlignStyle(); + } + } + + public FlexibleStringExpander getAssociatedContentId() { + return associatedContentId; + } + + public String getAssociatedContentId(Map<String, Object> context) { + String retStr = null; + if (this.associatedContentId != null) { + retStr = associatedContentId.expandString(context); + } + if (retStr.isEmpty()) { + retStr = this.modelMenu.getDefaultAssociatedContentId(context); + } + return retStr; + } + + public String getCellWidth() { + if (!this.cellWidth.isEmpty()) { + return this.cellWidth; + } else { + return this.modelMenu.getDefaultCellWidth(); + } + } + + public ModelMenuCondition getCondition() { + return condition; + } + + public String getDisabledTitleStyle() { + if (!this.disabledTitleStyle.isEmpty()) { + return this.disabledTitleStyle; + } else if (parentMenuItem != null) { + return parentMenuItem.getDisabledTitleStyle(); + } else { + return this.modelMenu.getDefaultDisabledTitleStyle(); + } + } + + public String getDisableIfEmpty() { + return this.disableIfEmpty; + } + + public String getEntityName() { + if (!this.entityName.isEmpty()) { + return this.entityName; + } else if (parentMenuItem != null) { + return parentMenuItem.getEntityName(); + } else { + return this.modelMenu.getDefaultEntityName(); + } + } + + public Boolean getHideIfSelected() { + if (hideIfSelected != null) { + return this.hideIfSelected; + } else { + return this.modelMenu.getDefaultHideIfSelected(); + } + } + + public MenuLink getLink() { + return this.link; + } + + public List<ModelMenuItem> getMenuItemList() { + return menuItemList; + } + + public ModelMenu getModelMenu() { + return modelMenu; + } + + @Override + public String getName() { + if (!this.overrideName.isEmpty()) { + return this.overrideName; + } + return super.getName(); + } + + public String getOverrideName() { + return overrideName; + } + + public ModelMenuItem getParentMenuItem() { + return parentMenuItem; + } + + public FlexibleStringExpander getParentPortalPageId() { + return parentPortalPageId; + } + + public String getParentPortalPageId(Map<String, Object> context) { + return this.parentPortalPageId.expandString(context); + } + + public int getPosition() { + if (this.position == null) { + return 1; + } else { + return position.intValue(); + } + } + + public String getSelectedStyle() { + if (!this.selectedStyle.isEmpty()) { + return this.selectedStyle; + } else if (parentMenuItem != null) { + return parentMenuItem.getSelectedStyle(); + } else { + return this.modelMenu.getDefaultSelectedStyle(); + } + } + + public String getSubMenu() { + return subMenu; + } + + public FlexibleStringExpander getTitle() { + return title; + } + + public String getTitle(Map<String, Object> context) { + return title.expandString(context); + } + + public String getTitleStyle() { + if (!this.titleStyle.isEmpty()) { + return this.titleStyle; + } else if (parentMenuItem != null) { + return parentMenuItem.getTitleStyle(); + } else { + return this.modelMenu.getDefaultTitleStyle(); + } + } + + public FlexibleStringExpander getTooltip() { + return tooltip; + } + + public String getTooltip(Map<String, Object> context) { + if (UtilValidate.isNotEmpty(tooltip)) { + return tooltip.expandString(context); + } else { + return ""; + } + } + + public String getTooltipStyle() { + if (!this.tooltipStyle.isEmpty()) { + return this.tooltipStyle; + } else if (parentMenuItem != null) { + return parentMenuItem.getTooltipStyle(); + } else { + return this.modelMenu.getDefaultTooltipStyle(); + } + } + + public String getWidgetStyle() { + if (!this.widgetStyle.isEmpty()) { + return this.widgetStyle; + } else if (parentMenuItem != null) { + return parentMenuItem.getWidgetStyle(); + } else { + return this.modelMenu.getDefaultWidgetStyle(); + } + } + + public boolean isSelected(Map<String, Object> context) { + return getName().equals(modelMenu.getSelectedMenuItemContextFieldName(context)); + } + + public ModelMenuItem mergeOverrideModelMenuItem(ModelMenuItem overrideMenuItem) { + return new ModelMenuItem(this, overrideMenuItem); + } + + public void renderMenuItemString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer) + throws IOException { + if (shouldBeRendered(context)) { + AbstractModelAction.runSubActions(actions, context); + String parentPortalPageId = getParentPortalPageId(context); + if (UtilValidate.isNotEmpty(parentPortalPageId)) { + List<GenericValue> portalPages = PortalPageWorker.getPortalPages(parentPortalPageId, context); + if (UtilValidate.isNotEmpty(portalPages)) { + Locale locale = (Locale) context.get("locale"); + for (GenericValue portalPage : portalPages) { + if (UtilValidate.isNotEmpty(portalPage.getString("portalPageName"))) { + ModelMenuItem localItem = new ModelMenuItem(portalPage, this, locale); + menuStringRenderer.renderMenuItem(writer, context, localItem); + } + } + } + } else { + menuStringRenderer.renderMenuItem(writer, context, this); + } + } + } + + public boolean shouldBeRendered(Map<String, Object> context) { + if (this.condition != null) { + return this.condition.getCondition().eval(context); + } + return true; + } + + public static class MenuLink { + private final ModelMenuItem linkMenuItem; + private final Link link; + + public MenuLink(Element linkElement, ModelMenuItem parentMenuItem) { + this.linkMenuItem = parentMenuItem; + if (linkElement.getAttribute("text").isEmpty()) { + linkElement.setAttribute("text", parentMenuItem.getTitle().getOriginal()); + } + if (linkElement.getAttribute("style").isEmpty()) { + linkElement.setAttribute("style", parentMenuItem.getWidgetStyle()); + } + this.link = new Link(linkElement); + } + + public MenuLink(GenericValue portalPage, ModelMenuItem parentMenuItem, Locale locale) { + this.linkMenuItem = parentMenuItem; + ArrayList<Parameter> parameterList = new ArrayList<Parameter>(); + if (parentMenuItem.link != null) { + parameterList.addAll(parentMenuItem.link.getParameterList()); + } + parameterList.add(new Parameter("portalPageId", portalPage.getString("portalPageId"), false)); + parameterList.add(new Parameter("parentPortalPageId", portalPage.getString("parentPortalPageId"), false)); + String target = "showPortalPage"; + if (parentMenuItem.link != null) { + target= ""; + } + this.link = new Link(portalPage, parameterList, target, locale); + } + + public AutoEntityParameters getAutoEntityParameters() { + return link.getAutoEntityParameters(); + } + + public AutoServiceParameters getAutoServiceParameters() { + return link.getAutoServiceParameters(); + } + + public boolean getEncode() { + return link.getEncode(); + } + + public boolean getFullPath() { + return link.getFullPath(); + } + + public String getHeight() { + return link.getHeight(); + } + + public String getId(Map<String, Object> context) { + return link.getId(context); + } + + public FlexibleStringExpander getIdExdr() { + return link.getIdExdr(); + } + + public Image getImage() { + return link.getImage(); + } + + public String getLinkType() { + return link.getLinkType(); + } + + public String getName() { + return link.getName(); + } + + public String getName(Map<String, Object> context) { + return link.getName(context); + } + + public FlexibleStringExpander getNameExdr() { + return link.getNameExdr(); + } + + public List<Parameter> getParameterList() { + return link.getParameterList(); + } + + public Map<String, String> getParameterMap(Map<String, Object> context) { + return link.getParameterMap(context); + } + + public String getPrefix(Map<String, Object> context) { + return link.getPrefix(context); + } + + public FlexibleStringExpander getPrefixExdr() { + return link.getPrefixExdr(); + } + + public boolean getSecure() { + return link.getSecure(); + } + + public String getStyle(Map<String, Object> context) { + return link.getStyle(context); + } + + public FlexibleStringExpander getStyleExdr() { + return link.getStyleExdr(); + } + + public String getTarget(Map<String, Object> context) { + return link.getTarget(context); + } + + public FlexibleStringExpander getTargetExdr() { + return link.getTargetExdr(); + } + + public String getTargetWindow(Map<String, Object> context) { + return link.getTargetWindow(context); + } + + public FlexibleStringExpander getTargetWindowExdr() { + return link.getTargetWindowExdr(); + } + + public String getText(Map<String, Object> context) { + return link.getText(context); + } + + public FlexibleStringExpander getTextExdr() { + return link.getTextExdr(); + } + + public String getUrlMode() { + return link.getUrlMode(); + } + + public String getWidth() { + return link.getWidth(); + } + + public ModelMenuItem getLinkMenuItem() { + return linkMenuItem; + } + + public Link getLink() { + return link; + } + + public void renderLinkString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer) + throws IOException { + menuStringRenderer.renderLink(writer, context, this); + } + } +} Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelScreen.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelScreen.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelScreen.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelScreen.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,194 @@ +/******************************************************************************* + * 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.Debug; +import org.ofbiz.base.util.UtilGenerics; +import org.ofbiz.base.util.UtilValidate; +import org.ofbiz.base.util.UtilXml; +import org.ofbiz.base.util.string.FlexibleStringExpander; +import org.ofbiz.entity.Delegator; +import org.ofbiz.entity.GenericEntity; +import org.ofbiz.entity.GenericEntityException; +import org.ofbiz.entity.transaction.TransactionUtil; +import org.ofbiz.service.LocalDispatcher; +import org.ofbiz.widget.renderer.ScreenRenderException; +import org.ofbiz.widget.renderer.ScreenStringRenderer; +import org.w3c.dom.Element; + +/** + * Widget Library - Screen model class + */ +@SuppressWarnings("serial") +public class ModelScreen extends ModelWidget { + + public static final String module = ModelScreen.class.getName(); + + private final String sourceLocation; + private final FlexibleStringExpander transactionTimeoutExdr; + private final Map<String, ModelScreen> modelScreenMap; + private final boolean useTransaction; + private final boolean useCache; + private final ModelScreenWidget.Section section; + + /** XML Constructor */ + public ModelScreen(Element screenElement, Map<String, ModelScreen> modelScreenMap, String sourceLocation) { + super(screenElement); + this.sourceLocation = sourceLocation; + this.transactionTimeoutExdr = FlexibleStringExpander.getInstance(screenElement.getAttribute("transaction-timeout")); + this.modelScreenMap = modelScreenMap; + this.useTransaction = "true".equals(screenElement.getAttribute("use-transaction")); + this.useCache = "true".equals(screenElement.getAttribute("use-cache")); + + // read in the section, which will read all sub-widgets too + Element sectionElement = UtilXml.firstChildElement(screenElement, "section"); + if (sectionElement == null) { + throw new IllegalArgumentException("No section found for the screen definition with name: " + getName()); + } + this.section = new ModelScreenWidget.Section(this, sectionElement, true); + } + + @Override + public void accept(ModelWidgetVisitor visitor) throws Exception { + visitor.visit(this); + } + + public String getTransactionTimeout() { + return transactionTimeoutExdr.getOriginal(); + } + + public Map<String, ModelScreen> getModelScreenMap() { + return modelScreenMap; + } + + public boolean getUseTransaction() { + return useTransaction; + } + + public boolean getUseCache() { + return useCache; + } + + public ModelScreenWidget.Section getSection() { + return section; + } + + public String getSourceLocation() { + return sourceLocation; + } + + /** + * Renders this screen to a String, i.e. in a text format, as defined with the + * ScreenStringRenderer implementation. + * + * @param writer The Writer that the screen text will be written to + * @param context Map containing the screen context; the following are + * reserved words in this context: + * - parameters (contains any special initial parameters coming in) + * - userLogin (if a user is logged in) + * - autoUserLogin (if a user is automatically logged in, ie no password has been entered) + * - formStringRenderer + * - request, response, session, application (special case, only in HTML contexts, etc) + * - delegator, dispatcher, security + * - null (represents a null field value for entity operations) + * - sections (used for decorators to reference the sections to be decorated and render them) + * @param screenStringRenderer An implementation of the ScreenStringRenderer + * interface that is responsible for the actual text generation for + * different screen elements; implementing your own makes it possible to + * use the same screen definitions for many types of screen UIs + */ + public void renderScreenString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws ScreenRenderException { + // make sure the "nullField" object is in there for entity ops + context.put("nullField", GenericEntity.NULL_FIELD); + + // wrap the whole screen rendering in a transaction, should improve performance in querying and such + Map<String, String> parameters = UtilGenerics.cast(context.get("parameters")); + boolean beganTransaction = false; + int transactionTimeout = -1; + if (parameters != null) { + String transactionTimeoutPar = parameters.get("TRANSACTION_TIMEOUT"); + if (transactionTimeoutPar != null) { + try { + transactionTimeout = Integer.parseInt(transactionTimeoutPar); + } catch (NumberFormatException nfe) { + String msg = "TRANSACTION_TIMEOUT parameter for screen [" + this.sourceLocation + "#" + getName() + "] is invalid and it will be ignored: " + nfe.toString(); + Debug.logWarning(msg, module); + } + } + } + + if (transactionTimeout < 0 && !transactionTimeoutExdr.isEmpty()) { + // no TRANSACTION_TIMEOUT parameter, check screen attribute + String transactionTimeoutStr = transactionTimeoutExdr.expandString(context); + if (UtilValidate.isNotEmpty(transactionTimeoutStr)) { + try { + transactionTimeout = Integer.parseInt(transactionTimeoutStr); + } catch (NumberFormatException e) { + Debug.logWarning(e, "Could not parse transaction-timeout value, original=[" + transactionTimeoutExdr + "], expanded=[" + transactionTimeoutStr + "]", module); + } + } + } + + try { + // If transaction timeout is not present (i.e. is equal to -1), the default transaction timeout is used + // If transaction timeout is present, use it to start the transaction + // If transaction timeout is set to zero, no transaction is started + if (useTransaction) { + if (transactionTimeout < 0) { + beganTransaction = TransactionUtil.begin(); + } + if (transactionTimeout > 0) { + beganTransaction = TransactionUtil.begin(transactionTimeout); + } + } + + // render the screen, starting with the top-level section + this.section.renderWidgetString(writer, context, screenStringRenderer); + TransactionUtil.commit(beganTransaction); + } catch (Exception e) { + String errMsg = "Error rendering screen [" + this.sourceLocation + "#" + getName() + "]: " + e.toString(); + Debug.logError(errMsg + ". Rolling back transaction.", module); + try { + // only rollback the transaction if we started one... + TransactionUtil.rollback(beganTransaction, errMsg, e); + } catch (GenericEntityException e2) { + Debug.logError(e2, "Could not rollback transaction: " + e2.toString(), module); + } + + // throw nested exception, don't need to log details here: Debug.logError(e, errMsg, module); + + // after rolling back, rethrow the exception + throw new ScreenRenderException(errMsg, e); + } + } + + public LocalDispatcher getDispatcher(Map<String, Object> context) { + LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher"); + return dispatcher; + } + + public Delegator getDelegator(Map<String, Object> context) { + Delegator delegator = (Delegator) context.get("delegator"); + return delegator; + } +} + + Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelScreenCondition.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelScreenCondition.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelScreenCondition.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelScreenCondition.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,96 @@ +/******************************************************************************* + * 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.UtilGenerics; +import org.ofbiz.base.util.string.FlexibleStringExpander; +import org.ofbiz.widget.model.AbstractModelCondition; +import org.ofbiz.widget.model.AbstractModelCondition.DefaultConditionFactory; +import org.ofbiz.widget.model.ModelCondition; +import org.ofbiz.widget.model.ModelConditionFactory; +import org.ofbiz.widget.model.ModelConditionVisitor; +import org.ofbiz.widget.model.ModelWidget; +import org.w3c.dom.Element; + +/** + * Models the <condition> element. + * + * @see <code>widget-screen.xsd</code> + */ +@SuppressWarnings("serial") +public final class ModelScreenCondition { + + /* + * ----------------------------------------------------------------------- * + * DEVELOPERS PLEASE READ + * ----------------------------------------------------------------------- * + * + * This model is intended to be a read-only data structure that represents + * an XML element. Outside of object construction, the class should not + * have any behaviors. + * + * Instances of this class will be shared by multiple threads - therefore + * it is immutable. DO NOT CHANGE THE OBJECT'S STATE AT RUN TIME! + * + */ + + public static final String module = ModelScreenCondition.class.getName(); + public static final ModelConditionFactory SCREEN_CONDITION_FACTORY = new ScreenConditionFactory(); + + public static class IfEmptySection extends AbstractModelCondition { + private final FlexibleStringExpander sectionExdr; + + private IfEmptySection(ModelConditionFactory factory, ModelWidget modelWidget, Element condElement) { + super (factory, modelWidget, condElement); + this.sectionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("section-name")); + } + + @Override + public void accept(ModelConditionVisitor visitor) throws Exception { + visitor.visit(this); + } + + @Override + public boolean eval(Map<String, Object> context) { + Map<String, Object> sectionsMap = UtilGenerics.toMap(context.get("sections")); + return !sectionsMap.containsKey(this.sectionExdr.expandString(context)); + } + + public FlexibleStringExpander getSectionExdr() { + return sectionExdr; + } + } + + private static class ScreenConditionFactory extends DefaultConditionFactory { + + @Override + public ModelCondition newInstance(ModelWidget modelWidget, Element conditionElement) { + if (conditionElement == null) { + return DefaultConditionFactory.TRUE; + } + if ("if-empty-section".equals(conditionElement.getNodeName())) { + return new IfEmptySection(this, modelWidget, conditionElement); + } else { + return super.newInstance(this, modelWidget,conditionElement); + } + } + } +} |
Free forum by Nabble | Edit this page |