| /******************************************************************************* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| *******************************************************************************/ |
| package org.apache.ofbiz.widget.model; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.ListIterator; |
| import java.util.Map; |
| import java.util.regex.PatternSyntaxException; |
| |
| import org.apache.ofbiz.base.util.Debug; |
| import org.apache.ofbiz.base.util.UtilGenerics; |
| import org.apache.ofbiz.base.util.UtilValidate; |
| import org.apache.ofbiz.base.util.UtilXml; |
| import org.apache.ofbiz.base.util.collections.FlexibleMapAccessor; |
| import org.apache.ofbiz.base.util.string.FlexibleStringExpander; |
| import org.apache.ofbiz.entity.finder.EntityFinderUtil; |
| import org.apache.ofbiz.service.GenericServiceException; |
| import org.apache.ofbiz.service.ModelService; |
| import org.apache.ofbiz.widget.WidgetWorker; |
| import org.w3c.dom.Element; |
| |
| /** |
| * Abstract form action. |
| */ |
| public abstract class ModelFormAction { |
| |
| public static final String module = ModelFormAction.class.getName(); |
| |
| public static List<ModelAction> readSubActions(ModelForm modelForm, Element parentElement) { |
| List<? extends Element> actionElementList = UtilXml.childElementList(parentElement); |
| List<ModelAction> actions = new ArrayList<ModelAction>(actionElementList.size()); |
| for (Element actionElement : UtilXml.childElementList(parentElement)) { |
| if ("service".equals(actionElement.getNodeName())) { |
| actions.add(new Service(modelForm, actionElement)); |
| } else if ("entity-and".equals(actionElement.getNodeName()) || "entity-condition".equals(actionElement.getNodeName()) |
| || "get-related".equals(actionElement.getNodeName())) { |
| if (!actionElement.hasAttribute("list")) { |
| String listName = modelForm.getListName(); |
| if (UtilValidate.isEmpty(listName)) { |
| listName = ModelForm.DEFAULT_FORM_RESULT_LIST_NAME; |
| } |
| actionElement.setAttribute("list", listName); |
| } |
| actions.add(AbstractModelAction.newInstance(modelForm, actionElement)); |
| } else if ("call-parent-actions".equals(actionElement.getNodeName())) { |
| actions.add(new CallParentActions(modelForm, actionElement)); |
| } else { |
| actions.add(AbstractModelAction.newInstance(modelForm, actionElement)); |
| } |
| } |
| return Collections.unmodifiableList(actions); |
| } |
| |
| /** |
| * Models the <call-parent-actions> element. |
| * |
| * @see <code>widget-form.xsd</code> |
| */ |
| @SuppressWarnings("serial") |
| public static class CallParentActions extends AbstractModelAction { |
| private final ActionsKind kind; |
| private final ModelForm modelForm; |
| |
| public CallParentActions(ModelForm modelForm, Element callParentActionsElement) { |
| super(modelForm, callParentActionsElement); |
| String parentName = callParentActionsElement.getParentNode().getNodeName(); |
| if ("actions".equals(parentName)) { |
| kind = ActionsKind.ACTIONS; |
| } else if ("row-actions".equals(parentName)) { |
| kind = ActionsKind.ROW_ACTIONS; |
| } else { |
| throw new IllegalArgumentException("Action element not supported for call-parent-actions : " + parentName); |
| } |
| ModelForm parentModel = modelForm.getParentModelForm(); |
| if (parentModel == null) { |
| throw new IllegalArgumentException("call-parent-actions can only be used with form extending another form"); |
| } |
| this.modelForm = modelForm; |
| } |
| |
| @Override |
| public void accept(ModelActionVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| |
| @Override |
| public void runAction(Map<String, Object> context) { |
| ModelForm parentModel = modelForm.getParentModelForm(); |
| switch (kind) { |
| case ACTIONS: |
| parentModel.runFormActions(context); |
| break; |
| case ROW_ACTIONS: |
| AbstractModelAction.runSubActions(parentModel.getRowActions(), context); |
| break; |
| } |
| } |
| |
| protected static enum ActionsKind { |
| ACTIONS, ROW_ACTIONS |
| } |
| } |
| |
| /** |
| * Models the <service> element. |
| * |
| * @see <code>widget-form.xsd</code> |
| */ |
| @SuppressWarnings("serial") |
| public static class Service extends AbstractModelAction { |
| private final FlexibleStringExpander autoFieldMapExdr; |
| private final Map<FlexibleMapAccessor<Object>, Object> fieldMap; |
| private final boolean ignoreError; |
| private final FlexibleStringExpander resultMapListNameExdr; |
| private final FlexibleMapAccessor<Map<String, Object>> resultMapNameAcsr; |
| private final FlexibleStringExpander serviceNameExdr; |
| |
| public Service(ModelForm modelForm, Element serviceElement) { |
| super(modelForm, serviceElement); |
| this.serviceNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name")); |
| this.resultMapNameAcsr = FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map")); |
| this.autoFieldMapExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map")); |
| FlexibleStringExpander resultMapListNameExdr = FlexibleStringExpander.getInstance(""); |
| if (UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list")) |
| && UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list-name"))) { |
| if (UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list-iterator")) |
| && UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list-iterator-name"))) { |
| String lstNm = modelForm.getListName(); |
| if (UtilValidate.isEmpty(lstNm)) { |
| lstNm = ModelForm.DEFAULT_FORM_RESULT_LIST_NAME; |
| } |
| resultMapListNameExdr = FlexibleStringExpander.getInstance(lstNm); |
| } else { |
| // this is deprecated, but support it for now anyway |
| resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement |
| .getAttribute("result-map-list-iterator")); |
| if (resultMapListNameExdr.isEmpty()) |
| resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement |
| .getAttribute("result-map-list-iterator-name")); |
| } |
| } else { |
| resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-list")); |
| if (resultMapListNameExdr.isEmpty()) |
| resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement |
| .getAttribute("result-map-list-name")); |
| } |
| this.resultMapListNameExdr = resultMapListNameExdr; |
| this.fieldMap = EntityFinderUtil.makeFieldMap(serviceElement); |
| this.ignoreError = "true".equals(serviceElement.getAttribute("ignore-error")); |
| } |
| |
| @Override |
| public void accept(ModelActionVisitor visitor) throws Exception { |
| visitor.visit(this); |
| } |
| |
| public String getServiceName() { |
| return serviceNameExdr.getOriginal(); |
| } |
| |
| @Override |
| public void runAction(Map<String, Object> context) { |
| String serviceNameExpanded = this.serviceNameExdr.expandString(context); |
| if (UtilValidate.isEmpty(serviceNameExpanded)) { |
| throw new IllegalArgumentException("Service name was empty, expanded from: " + this.serviceNameExdr.getOriginal()); |
| } |
| String autoFieldMapString = this.autoFieldMapExdr.expandString(context); |
| boolean autoFieldMapBool = !"false".equals(autoFieldMapString); |
| try { |
| Map<String, Object> serviceContext = null; |
| if (autoFieldMapBool) { |
| if (!"true".equals(autoFieldMapString)) { |
| Map<String, Object> autoFieldMap = UtilGenerics.checkMap(context.get(autoFieldMapString)); |
| serviceContext = WidgetWorker.getDispatcher(context).getDispatchContext() |
| .makeValidContext(serviceNameExpanded, ModelService.IN_PARAM, autoFieldMap); |
| } else { |
| serviceContext = WidgetWorker.getDispatcher(context).getDispatchContext() |
| .makeValidContext(serviceNameExpanded, ModelService.IN_PARAM, context); |
| } |
| } else { |
| serviceContext = new HashMap<String, Object>(); |
| } |
| if (this.fieldMap != null) { |
| EntityFinderUtil.expandFieldMapToContext(this.fieldMap, context, serviceContext); |
| } |
| Map<String, Object> result = null; |
| if (this.ignoreError) { |
| result = WidgetWorker.getDispatcher(context).runSync(serviceNameExpanded, serviceContext, -1, true); |
| } else { |
| result = WidgetWorker.getDispatcher(context).runSync(serviceNameExpanded, serviceContext); |
| } |
| if (!this.resultMapNameAcsr.isEmpty()) { |
| this.resultMapNameAcsr.put(context, result); |
| String queryString = (String) result.get("queryString"); |
| context.put("queryString", queryString); |
| context.put("queryStringMap", result.get("queryStringMap")); |
| if (UtilValidate.isNotEmpty(queryString)) { |
| try { |
| String queryStringEncoded = queryString.replaceAll("&", "%26"); |
| context.put("queryStringEncoded", queryStringEncoded); |
| } catch (PatternSyntaxException e) { |
| |
| } |
| } |
| } else { |
| context.putAll(result); |
| } |
| String listName = resultMapListNameExdr.expandString(context); |
| Object listObj = result.get(listName); |
| if (listObj != null) { |
| if (!(listObj instanceof List<?>) && !(listObj instanceof ListIterator<?>)) { |
| throw new IllegalArgumentException("Error in form [" + this.getModelWidget().getName() |
| + "] calling service with name [" + serviceNameExpanded |
| + "]: the result that is supposed to be a List or ListIterator and is not."); |
| } |
| context.put("listName", listName); |
| context.put(listName, listObj); |
| } |
| } catch (GenericServiceException e) { |
| String errMsg = "Error in form [" + this.getModelWidget().getName() + "] calling service with name [" |
| + serviceNameExpanded + "]: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| if (!this.ignoreError) { |
| throw new IllegalArgumentException(errMsg); |
| } |
| } |
| } |
| |
| public FlexibleStringExpander getAutoFieldMapExdr() { |
| return autoFieldMapExdr; |
| } |
| |
| public Map<FlexibleMapAccessor<Object>, Object> getFieldMap() { |
| return fieldMap; |
| } |
| |
| public boolean getIgnoreError() { |
| return ignoreError; |
| } |
| |
| public FlexibleStringExpander getResultMapListNameExdr() { |
| return resultMapListNameExdr; |
| } |
| |
| public FlexibleMapAccessor<Map<String, Object>> getResultMapNameAcsr() { |
| return resultMapNameAcsr; |
| } |
| |
| public FlexibleStringExpander getServiceNameExdr() { |
| return serviceNameExdr; |
| } |
| } |
| } |