Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelWidgetCondition.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelWidgetCondition.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelWidgetCondition.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelWidgetCondition.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,650 @@ +/******************************************************************************* + * 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.Serializable; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.TimeZone; + +import org.apache.oro.text.regex.MalformedPatternException; +import org.apache.oro.text.regex.Pattern; +import org.apache.oro.text.regex.PatternMatcher; +import org.apache.oro.text.regex.Perl5Matcher; +import org.ofbiz.base.util.Debug; +import org.ofbiz.base.util.GeneralException; +import org.ofbiz.base.util.ObjectType; +import org.ofbiz.base.util.PatternFactory; +import org.ofbiz.base.util.UtilGenerics; +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.GenericValue; +import org.ofbiz.entityext.permission.EntityPermissionChecker; +import org.ofbiz.minilang.operation.BaseCompare; +import org.ofbiz.security.Security; +import org.ofbiz.service.DispatchContext; +import org.ofbiz.service.GenericServiceException; +import org.ofbiz.service.LocalDispatcher; +import org.ofbiz.service.ModelService; +import org.ofbiz.service.ServiceUtil; +import org.w3c.dom.Element; + +/** + * Abstract base class for the condition models. + */ +@SuppressWarnings("serial") +public abstract class ModelWidgetCondition implements Serializable { + + /* + * ----------------------------------------------------------------------- * + * 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 = ModelWidgetCondition.class.getName(); + public static final ConditionFactory DEFAULT_CONDITION_FACTORY = new DefaultConditionFactory(); + + private final ModelWidget modelWidget; + private final Condition rootCondition; + + protected ModelWidgetCondition(ConditionFactory factory, ModelWidget modelWidget, Element conditionElement) { + this.modelWidget = modelWidget; + Element firstChildElement = UtilXml.firstChildElement(conditionElement); + this.rootCondition = factory.newInstance(modelWidget, firstChildElement); + } + + public boolean eval(Map<String, Object> context) { + return rootCondition.eval(context); + } + + public ModelWidget getModelWidget() { + return modelWidget; + } + + public static List<Condition> readSubConditions(ConditionFactory factory, ModelWidget modelWidget, Element conditionElement) { + List<? extends Element> subElementList = UtilXml.childElementList(conditionElement); + List<Condition> condList = new ArrayList<Condition>(subElementList.size()); + for (Element subElement : subElementList) { + condList.add(factory.newInstance(modelWidget, subElement)); + } + return Collections.unmodifiableList(condList); + } + + /** + * Models the <and> element. + * + * @see <code>widget-common.xsd</code> + */ + public static class And extends ModelWidgetCondition implements Condition { + private final List<Condition> subConditions; + + private And(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { + super(factory, modelWidget, condElement); + this.subConditions = readSubConditions(factory, modelWidget, condElement); + } + + @Override + public boolean eval(Map<String, Object> context) { + // return false for the first one in the list that is false, basic and algo + for (Condition subCondition : this.subConditions) { + if (!subCondition.eval(context)) { + return false; + } + } + return true; + } + } + + public static interface Condition { + boolean eval(Map<String, Object> context); + } + + /** + * A factory for <code>Condition</code> instances. + * + */ + public static interface ConditionFactory { + /** + * Returns a new <code>Condition</code> instance built from <code>conditionElement</code>. + * + * @param modelWidget The <code>ModelWidget</code> that contains the <code>Condition</code> instance. + * @param conditionElement The XML element used to build the <code>Condition</code> instance. + * @return A new <code>Condition</code> instance built from <code>conditionElement</code>. + * @throws IllegalArgumentException if no model was found for the XML element + */ + Condition newInstance(ModelWidget modelWidget, Element conditionElement); + } + + public static class DefaultConditionFactory implements ConditionFactory { + public static final Condition TRUE = new Condition() { + @Override + public boolean eval(Map<String, Object> context) { + return true; + } + }; + public static final Condition FALSE = new Condition() { + @Override + public boolean eval(Map<String, Object> context) { + return false; + } + }; + + public Condition newInstance(ModelWidget modelWidget, Element conditionElement) { + if (conditionElement == null) { + return TRUE; + } + if ("and".equals(conditionElement.getNodeName())) { + return new And(this, modelWidget, conditionElement); + } else if ("xor".equals(conditionElement.getNodeName())) { + return new Xor(this, modelWidget, conditionElement); + } else if ("or".equals(conditionElement.getNodeName())) { + return new Or(this, modelWidget, conditionElement); + } else if ("not".equals(conditionElement.getNodeName())) { + return new Not(this, modelWidget, conditionElement); + } else if ("if-service-permission".equals(conditionElement.getNodeName())) { + return new IfServicePermission(this, modelWidget, conditionElement); + } else if ("if-has-permission".equals(conditionElement.getNodeName())) { + return new IfHasPermission(this, modelWidget, conditionElement); + } else if ("if-validate-method".equals(conditionElement.getNodeName())) { + return new IfValidateMethod(this, modelWidget, conditionElement); + } else if ("if-compare".equals(conditionElement.getNodeName())) { + return new IfCompare(this, modelWidget, conditionElement); + } else if ("if-compare-field".equals(conditionElement.getNodeName())) { + return new IfCompareField(this, modelWidget, conditionElement); + } else if ("if-regexp".equals(conditionElement.getNodeName())) { + return new IfRegexp(this, modelWidget, conditionElement); + } else if ("if-empty".equals(conditionElement.getNodeName())) { + return new IfEmpty(this, modelWidget, conditionElement); + } else if ("if-entity-permission".equals(conditionElement.getNodeName())) { + return new IfEntityPermission(this, modelWidget, conditionElement); + } else { + throw new IllegalArgumentException("Condition element not supported with name: " + conditionElement.getNodeName()); + } + } + } + + /** + * Models the <if-compare> element. + * + * @see <code>widget-common.xsd</code> + */ + public static class IfCompare extends ModelWidgetCondition implements Condition { + private final FlexibleMapAccessor<Object> fieldAcsr; + private final FlexibleStringExpander formatExdr; + private final String operator; + private final String type; + private final FlexibleStringExpander valueExdr; + + private IfCompare(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { + super(factory, modelWidget, condElement); + String fieldAcsr = condElement.getAttribute("field"); + if (fieldAcsr.isEmpty()) + fieldAcsr = condElement.getAttribute("field-name"); + this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr); + this.valueExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("value")); + this.operator = condElement.getAttribute("operator"); + this.type = condElement.getAttribute("type"); + this.formatExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("format")); + } + + @Override + public boolean eval(Map<String, Object> context) { + String value = this.valueExdr.expandString(context); + String format = this.formatExdr.expandString(context); + Object fieldVal = this.fieldAcsr.get(context); + // always use an empty string by default + if (fieldVal == null) { + fieldVal = ""; + } + List<Object> messages = new LinkedList<Object>(); + Boolean resultBool = BaseCompare.doRealCompare(fieldVal, value, operator, type, format, messages, null, null, true); + if (messages.size() > 0) { + messages.add(0, "Error with comparison in if-compare between field [" + fieldAcsr.toString() + "] with value [" + + fieldVal + "] and value [" + value + "] with operator [" + operator + "] and type [" + type + "]: "); + + StringBuilder fullString = new StringBuilder(); + for (Object item : messages) { + fullString.append(item.toString()); + } + Debug.logWarning(fullString.toString(), module); + throw new IllegalArgumentException(fullString.toString()); + } + return resultBool.booleanValue(); + } + } + + /** + * Models the <if-compare-field> element. + * + * @see <code>widget-common.xsd</code> + */ + public static class IfCompareField extends ModelWidgetCondition implements Condition { + private final FlexibleMapAccessor<Object> fieldAcsr; + private final FlexibleStringExpander formatExdr; + private final String operator; + private final FlexibleMapAccessor<Object> toFieldAcsr; + private final String type; + + private IfCompareField(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { + super(factory, modelWidget, condElement); + String fieldAcsr = condElement.getAttribute("field"); + if (fieldAcsr.isEmpty()) + fieldAcsr = condElement.getAttribute("field-name"); + this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr); + String toFieldAcsr = condElement.getAttribute("to-field"); + if (toFieldAcsr.isEmpty()) + toFieldAcsr = condElement.getAttribute("to-field-name"); + this.toFieldAcsr = FlexibleMapAccessor.getInstance(toFieldAcsr); + this.operator = condElement.getAttribute("operator"); + this.type = condElement.getAttribute("type"); + this.formatExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("format")); + } + + @Override + public boolean eval(Map<String, Object> context) { + String format = this.formatExdr.expandString(context); + Object fieldVal = this.fieldAcsr.get(context); + Object toFieldVal = this.toFieldAcsr.get(context); + // always use an empty string by default + if (fieldVal == null) { + fieldVal = ""; + } + List<Object> messages = new LinkedList<Object>(); + Boolean resultBool = BaseCompare.doRealCompare(fieldVal, toFieldVal, operator, type, format, messages, null, null, + false); + if (messages.size() > 0) { + messages.add(0, "Error with comparison in if-compare-field between field [" + fieldAcsr.toString() + + "] with value [" + fieldVal + "] and to-field [" + toFieldAcsr.toString() + "] with value [" + + toFieldVal + "] with operator [" + operator + "] and type [" + type + "]: "); + + StringBuilder fullString = new StringBuilder(); + for (Object item : messages) { + fullString.append(item.toString()); + } + Debug.logWarning(fullString.toString(), module); + throw new IllegalArgumentException(fullString.toString()); + } + return resultBool.booleanValue(); + } + } + + /** + * Models the <if-empty> element. + * + * @see <code>widget-common.xsd</code> + */ + public static class IfEmpty extends ModelWidgetCondition implements Condition { + private final FlexibleMapAccessor<Object> fieldAcsr; + + private IfEmpty(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { + super(factory, modelWidget, condElement); + String fieldAcsr = condElement.getAttribute("field"); + if (fieldAcsr.isEmpty()) + fieldAcsr = condElement.getAttribute("field-name"); + this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr); + } + + @Override + public boolean eval(Map<String, Object> context) { + Object fieldVal = this.fieldAcsr.get(context); + return ObjectType.isEmpty(fieldVal); + } + } + + /** + * Models the <if-entity-permission> element. + * + * @see <code>widget-common.xsd</code> + */ + public static class IfEntityPermission extends ModelWidgetCondition implements Condition { + private final EntityPermissionChecker permissionChecker; + + private IfEntityPermission(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { + super(factory, modelWidget, condElement); + this.permissionChecker = new EntityPermissionChecker(condElement); + } + + @Override + public boolean eval(Map<String, Object> context) { + return permissionChecker.runPermissionCheck(context); + } + } + + /** + * Models the <if-has-permission> element. + * + * @see <code>widget-common.xsd</code> + */ + public static class IfHasPermission extends ModelWidgetCondition implements Condition { + private final FlexibleStringExpander actionExdr; + private final FlexibleStringExpander permissionExdr; + + private IfHasPermission(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { + super(factory, modelWidget, condElement); + this.permissionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("permission")); + this.actionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("action")); + } + + @Override + public boolean eval(Map<String, Object> context) { + // if no user is logged in, treat as if the user does not have permission + GenericValue userLogin = (GenericValue) context.get("userLogin"); + if (userLogin != null) { + String permission = permissionExdr.expandString(context); + String action = actionExdr.expandString(context); + Security security = (Security) context.get("security"); + if (UtilValidate.isNotEmpty(action)) { + // run hasEntityPermission + if (security.hasEntityPermission(permission, action, userLogin)) { + return true; + } + } else { + // run hasPermission + if (security.hasPermission(permission, userLogin)) { + return true; + } + } + } + return false; + } + } + + /** + * Models the <if-regexp> element. + * + * @see <code>widget-common.xsd</code> + */ + public static class IfRegexp extends ModelWidgetCondition implements Condition { + private final FlexibleStringExpander exprExdr; + private final FlexibleMapAccessor<Object> fieldAcsr; + + private IfRegexp(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { + super(factory, modelWidget, condElement); + String fieldAcsr = condElement.getAttribute("field"); + if (fieldAcsr.isEmpty()) + fieldAcsr = condElement.getAttribute("field-name"); + this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr); + this.exprExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("expr")); + } + + @Override + public boolean eval(Map<String, Object> context) { + Object fieldVal = this.fieldAcsr.get(context); + String expr = this.exprExdr.expandString(context); + Pattern pattern; + try { + pattern = PatternFactory.createOrGetPerl5CompiledPattern(expr, true); + } catch (MalformedPatternException e) { + String errMsg = "Error in evaluation in if-regexp in screen: " + e.toString(); + Debug.logError(e, errMsg, module); + throw new IllegalArgumentException(errMsg); + } + String fieldString = null; + try { + fieldString = (String) ObjectType.simpleTypeConvert(fieldVal, "String", null, (TimeZone) context.get("timeZone"), + (Locale) context.get("locale"), true); + } catch (GeneralException e) { + Debug.logError(e, "Could not convert object to String, using empty String", module); + } + // always use an empty string by default + if (fieldString == null) + fieldString = ""; + PatternMatcher matcher = new Perl5Matcher(); + return matcher.matches(fieldString, pattern); + } + } + + /** + * Models the <if-service-permission> element. + * + * @see <code>widget-common.xsd</code> + */ + public static class IfServicePermission extends ModelWidgetCondition implements Condition { + private final FlexibleStringExpander actionExdr; + private final FlexibleStringExpander ctxMapExdr; + private final FlexibleStringExpander resExdr; + private final FlexibleStringExpander serviceExdr; + + private IfServicePermission(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { + super(factory, modelWidget, condElement); + this.serviceExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("service-name")); + this.actionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("main-action")); + this.ctxMapExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("context-map")); + this.resExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("resource-description")); + } + + @Override + public boolean eval(Map<String, Object> context) { + // if no user is logged in, treat as if the user does not have permission + GenericValue userLogin = (GenericValue) context.get("userLogin"); + if (userLogin != null) { + String serviceName = serviceExdr.expandString(context); + String mainAction = actionExdr.expandString(context); + String contextMap = ctxMapExdr.expandString(context); + String resource = resExdr.expandString(context); + if (UtilValidate.isEmpty(resource)) { + resource = serviceName; + } + if (UtilValidate.isEmpty(serviceName)) { + Debug.logWarning("No permission service-name specified!", module); + return false; + } + Map<String, Object> serviceContext = UtilGenerics.toMap(context.get(contextMap)); + if (serviceContext != null) { + // copy the required internal fields + serviceContext.put("userLogin", context.get("userLogin")); + serviceContext.put("locale", context.get("locale")); + } else { + serviceContext = context; + } + // get the service engine objects + LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher"); + DispatchContext dctx = dispatcher.getDispatchContext(); + // get the service + ModelService permService; + try { + permService = dctx.getModelService(serviceName); + } catch (GenericServiceException e) { + Debug.logError(e, module); + return false; + } + if (permService != null) { + // build the context + Map<String, Object> svcCtx = permService.makeValid(serviceContext, ModelService.IN_PARAM); + svcCtx.put("resourceDescription", resource); + if (UtilValidate.isNotEmpty(mainAction)) { + svcCtx.put("mainAction", mainAction); + } + // invoke the service + Map<String, Object> resp; + try { + resp = dispatcher.runSync(permService.name, svcCtx, 300, true); + } catch (GenericServiceException e) { + Debug.logError(e, module); + return false; + } + if (ServiceUtil.isError(resp) || ServiceUtil.isFailure(resp)) { + Debug.logError(ServiceUtil.getErrorMessage(resp), module); + return false; + } + Boolean hasPermission = (Boolean) resp.get("hasPermission"); + if (hasPermission != null) { + return hasPermission.booleanValue(); + } + } + } + return false; + } + } + + /** + * Models the <if-validate-method> element. + * + * @see <code>widget-common.xsd</code> + */ + public static class IfValidateMethod extends ModelWidgetCondition implements Condition { + private final FlexibleStringExpander classExdr; + private final FlexibleMapAccessor<Object> fieldAcsr; + private final FlexibleStringExpander methodExdr; + + private IfValidateMethod(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { + super(factory, modelWidget, condElement); + String fieldAcsr = condElement.getAttribute("field"); + if (fieldAcsr.isEmpty()) + fieldAcsr = condElement.getAttribute("field-name"); + this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr); + this.methodExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("method")); + this.classExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("class")); + } + + @Override + public boolean eval(Map<String, Object> context) { + String methodName = this.methodExdr.expandString(context); + String className = this.classExdr.expandString(context); + Object fieldVal = this.fieldAcsr.get(context); + String fieldString = null; + if (fieldVal != null) { + try { + fieldString = (String) ObjectType.simpleTypeConvert(fieldVal, "String", null, + (TimeZone) context.get("timeZone"), (Locale) context.get("locale"), true); + } catch (GeneralException e) { + Debug.logError(e, "Could not convert object to String, using empty String", module); + } + } + // always use an empty string by default + if (fieldString == null) + fieldString = ""; + Class<?>[] paramTypes = new Class[] { String.class }; + Object[] params = new Object[] { fieldString }; + Class<?> valClass; + try { + valClass = ObjectType.loadClass(className); + } catch (ClassNotFoundException cnfe) { + Debug.logError("Could not find validation class: " + className, module); + return false; + } + Method valMethod; + try { + valMethod = valClass.getMethod(methodName, paramTypes); + } catch (NoSuchMethodException cnfe) { + Debug.logError("Could not find validation method: " + methodName + " of class " + className, module); + return false; + } + Boolean resultBool = Boolean.FALSE; + try { + resultBool = (Boolean) valMethod.invoke(null, params); + } catch (Exception e) { + Debug.logError(e, "Error in IfValidationMethod " + methodName + " of class " + className + + ", defaulting to false ", module); + } + return resultBool.booleanValue(); + } + } + + /** + * Models the <not> element. + * + * @see <code>widget-common.xsd</code> + */ + public static class Not extends ModelWidgetCondition implements Condition { + private final Condition subCondition; + + private Not(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { + super(factory, modelWidget, condElement); + Element firstChildElement = UtilXml.firstChildElement(condElement); + this.subCondition = factory.newInstance(modelWidget, firstChildElement); + } + + @Override + public boolean eval(Map<String, Object> context) { + return !this.subCondition.eval(context); + } + } + + /** + * Models the <or> element. + * + * @see <code>widget-common.xsd</code> + */ + public static class Or extends ModelWidgetCondition implements Condition { + private final List<Condition> subConditions; + + private Or(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { + super(factory, modelWidget, condElement); + this.subConditions = readSubConditions(factory, modelWidget, condElement); + } + + @Override + public boolean eval(Map<String, Object> context) { + // return true for the first one in the list that is true, basic or algo + for (Condition subCondition : this.subConditions) { + if (subCondition.eval(context)) { + return true; + } + } + return false; + } + } + + /** + * Models the <xor> element. + * + * @see <code>widget-common.xsd</code> + */ + public static class Xor extends ModelWidgetCondition implements Condition { + private final List<Condition> subConditions; + + private Xor(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { + super(factory, modelWidget, condElement); + this.subConditions = readSubConditions(factory, modelWidget, condElement); + } + + @Override + public boolean eval(Map<String, Object> context) { + // if more than one is true stop immediately and return false; if all are false return false; if only one is true return true + boolean foundOneTrue = false; + for (Condition subCondition : this.subConditions) { + if (subCondition.eval(context)) { + if (foundOneTrue) { + // now found two true, so return false + return false; + } else { + foundOneTrue = true; + } + } + } + return foundOneTrue; + } + } +} Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelWidgetVisitor.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelWidgetVisitor.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelWidgetVisitor.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ModelWidgetVisitor.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,89 @@ +/******************************************************************************* + * 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 org.ofbiz.widget.model.HtmlWidget; + +/** + * A <code>ModelWidget</code> visitor. + */ +public interface ModelWidgetVisitor { + + void visit(HtmlWidget htmlWidget) throws Exception; + + void visit(HtmlWidget.HtmlTemplate htmlTemplate) throws Exception; + + void visit(HtmlWidget.HtmlTemplateDecorator htmlTemplateDecorator) throws Exception; + + void visit(HtmlWidget.HtmlTemplateDecoratorSection htmlTemplateDecoratorSection) throws Exception; + + void visit(IterateSectionWidget iterateSectionWidget) throws Exception; + + void visit(ModelForm modelForm) throws Exception; + + void visit(ModelMenu modelMenu) throws Exception; + + void visit(ModelMenuItem modelMenuItem) throws Exception; + + void visit(ModelScreen modelScreen) throws Exception; + + void visit(ModelScreenWidget.ColumnContainer columnContainer) throws Exception; + + void visit(ModelScreenWidget.Container container) throws Exception; + + void visit(ModelScreenWidget.Content content) throws Exception; + + void visit(ModelScreenWidget.DecoratorScreen decoratorScreen) throws Exception; + + void visit(ModelScreenWidget.DecoratorSection decoratorSection) throws Exception; + + void visit(ModelScreenWidget.DecoratorSectionInclude decoratorSectionInclude) throws Exception; + + void visit(ModelScreenWidget.Form form) throws Exception; + + void visit(ModelScreenWidget.HorizontalSeparator horizontalSeparator) throws Exception; + + void visit(ModelScreenWidget.ScreenImage image) throws Exception; + + void visit(ModelScreenWidget.IncludeScreen includeScreen) throws Exception; + + void visit(ModelScreenWidget.Label label) throws Exception; + + void visit(ModelScreenWidget.ScreenLink link) throws Exception; + + void visit(ModelScreenWidget.Menu menu) throws Exception; + + void visit(ModelScreenWidget.PlatformSpecific platformSpecific) throws Exception; + + void visit(ModelScreenWidget.PortalPage portalPage) throws Exception; + + void visit(ModelScreenWidget.Screenlet screenlet) throws Exception; + + void visit(ModelScreenWidget.Section section) throws Exception; + + void visit(ModelScreenWidget.Tree tree) throws Exception; + + void visit(ModelTree modelTree) throws Exception; + + void visit(ModelTree.ModelNode modelNode) throws Exception; + + void visit(ModelTree.ModelNode.ModelSubNode modelSubNode) throws Exception; + + void visit(ModelScreenWidget.Column column) throws Exception; +} Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ScreenFactory.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ScreenFactory.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ScreenFactory.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/ScreenFactory.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,213 @@ +/******************************************************************************* + * 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.Debug; +import org.ofbiz.base.util.GeneralException; +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.ofbiz.widget.renderer.ScreenStringRenderer; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + + +/** + * Widget Library - Screen factory class + */ +public class ScreenFactory { + + public static final String module = ScreenFactory.class.getName(); + + public static final UtilCache<String, Map<String, ModelScreen>> screenLocationCache = UtilCache.createUtilCache("widget.screen.locationResource", 0, 0, false); + public static final UtilCache<String, Map<String, ModelScreen>> screenWebappCache = UtilCache.createUtilCache("widget.screen.webappResource", 0, 0, false); + + public static boolean isCombinedName(String combinedName) { + int numSignIndex = combinedName.lastIndexOf("#"); + if (numSignIndex == -1) { + return false; + } + if (numSignIndex + 1 >= combinedName.length()) { + return false; + } + return true; + } + + public static String getResourceNameFromCombined(String combinedName) { + // split out the name on the last "#" + int numSignIndex = combinedName.lastIndexOf("#"); + if (numSignIndex == -1) { + throw new IllegalArgumentException("Error in screen location/name: no \"#\" found to separate the location from the name; correct example: component://product/screen/product/ProductScreens.xml#EditProduct"); + } + if (numSignIndex + 1 >= combinedName.length()) { + throw new IllegalArgumentException("Error in screen location/name: the \"#\" was at the end with no screen name after it; correct example: component://product/screen/product/ProductScreens.xml#EditProduct"); + } + String resourceName = combinedName.substring(0, numSignIndex); + return resourceName; + } + + public static String getScreenNameFromCombined(String combinedName) { + // split out the name on the last "#" + int numSignIndex = combinedName.lastIndexOf("#"); + if (numSignIndex == -1) { + throw new IllegalArgumentException("Error in screen location/name: no \"#\" found to separate the location from the name; correct example: component://product/screen/product/ProductScreens.xml#EditProduct"); + } + if (numSignIndex + 1 >= combinedName.length()) { + throw new IllegalArgumentException("Error in screen location/name: the \"#\" was at the end with no screen name after it; correct example: component://product/screen/product/ProductScreens.xml#EditProduct"); + } + String screenName = combinedName.substring(numSignIndex + 1); + return screenName; + } + + public static ModelScreen getScreenFromLocation(String combinedName) + throws IOException, SAXException, ParserConfigurationException { + String resourceName = getResourceNameFromCombined(combinedName); + String screenName = getScreenNameFromCombined(combinedName); + return getScreenFromLocation(resourceName, screenName); + } + + public static ModelScreen getScreenFromLocation(String resourceName, String screenName) + throws IOException, SAXException, ParserConfigurationException { + Map<String, ModelScreen> modelScreenMap = getScreensFromLocation(resourceName); + ModelScreen modelScreen = modelScreenMap.get(screenName); + if (modelScreen == null) { + throw new IllegalArgumentException("Could not find screen with name [" + screenName + "] in class resource [" + resourceName + "]"); + } + return modelScreen; + } + + public static Map<String, ModelScreen> getScreensFromLocation(String resourceName) + throws IOException, SAXException, ParserConfigurationException { + Map<String, ModelScreen> modelScreenMap = screenLocationCache.get(resourceName); + if (modelScreenMap == null) { + synchronized (ScreenFactory.class) { + modelScreenMap = screenLocationCache.get(resourceName); + if (modelScreenMap == null) { + long startTime = System.currentTimeMillis(); + URL screenFileUrl = null; + screenFileUrl = FlexibleLocation.resolveLocation(resourceName); + if (screenFileUrl == null) { + throw new IllegalArgumentException("Could not resolve location to URL: " + resourceName); + } + Document screenFileDoc = UtilXml.readXmlDocument(screenFileUrl, true, true); + modelScreenMap = readScreenDocument(screenFileDoc, resourceName); + screenLocationCache.put(resourceName, modelScreenMap); + double totalSeconds = (System.currentTimeMillis() - startTime)/1000.0; + Debug.logInfo("Got " + modelScreenMap.size() + " screens in " + totalSeconds + "s from: " + screenFileUrl.toExternalForm(), module); + } + } + } + + if (modelScreenMap.isEmpty()) { + throw new IllegalArgumentException("Could not find screen file with name [" + resourceName + "]"); + } + return modelScreenMap; + } + + public static ModelScreen getScreenFromWebappContext(String resourceName, String screenName, HttpServletRequest request) + throws IOException, SAXException, ParserConfigurationException { + String webappName = UtilHttp.getApplicationName(request); + String cacheKey = webappName + "::" + resourceName; + + + Map<String, ModelScreen> modelScreenMap = screenWebappCache.get(cacheKey); + if (modelScreenMap == null) { + synchronized (ScreenFactory.class) { + modelScreenMap = screenWebappCache.get(cacheKey); + if (modelScreenMap == null) { + ServletContext servletContext = (ServletContext) request.getAttribute("servletContext"); + + URL screenFileUrl = servletContext.getResource(resourceName); + Document screenFileDoc = UtilXml.readXmlDocument(screenFileUrl, true, true); + modelScreenMap = readScreenDocument(screenFileDoc, resourceName); + screenWebappCache.put(cacheKey, modelScreenMap); + } + } + } + + ModelScreen modelScreen = modelScreenMap.get(screenName); + if (modelScreen == null) { + throw new IllegalArgumentException("Could not find screen with name [" + screenName + "] in webapp resource [" + resourceName + "] in the webapp [" + webappName + "]"); + } + return modelScreen; + } + + public static Map<String, ModelScreen> readScreenDocument(Document screenFileDoc, String sourceLocation) { + Map<String, ModelScreen> modelScreenMap = new HashMap<String, ModelScreen>(); + if (screenFileDoc != null) { + // read document and construct ModelScreen for each screen element + Element rootElement = screenFileDoc.getDocumentElement(); + List<? extends Element> screenElements = UtilXml.childElementList(rootElement, "screen"); + for (Element screenElement: screenElements) { + ModelScreen modelScreen = new ModelScreen(screenElement, modelScreenMap, sourceLocation); + //Debug.logInfo("Read Screen with name: " + modelScreen.getName(), module); + modelScreenMap.put(modelScreen.getName(), modelScreen); + } + } + return modelScreenMap; + } + + public static void renderReferencedScreen(String name, String location, ModelScreenWidget parentWidget, Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException { + // check to see if the name is a composite name separated by a #, if so split it up and get it by the full loc#name + if (ScreenFactory.isCombinedName(name)) { + String combinedName = name; + location = ScreenFactory.getResourceNameFromCombined(combinedName); + name = ScreenFactory.getScreenNameFromCombined(combinedName); + } + + ModelScreen modelScreen = null; + if (UtilValidate.isNotEmpty(location)) { + try { + modelScreen = ScreenFactory.getScreenFromLocation(location, name); + } catch (IOException e) { + String errMsg = "Error rendering included screen named [" + name + "] at location [" + location + "]: " + e.toString(); + Debug.logError(e, errMsg, module); + throw new RuntimeException(errMsg); + } catch (SAXException e) { + String errMsg = "Error rendering included screen named [" + name + "] at location [" + location + "]: " + e.toString(); + Debug.logError(e, errMsg, module); + throw new RuntimeException(errMsg); + } catch (ParserConfigurationException e) { + String errMsg = "Error rendering included screen named [" + name + "] at location [" + location + "]: " + e.toString(); + Debug.logError(e, errMsg, module); + throw new RuntimeException(errMsg); + } + } else { + modelScreen = parentWidget.getModelScreen().getModelScreenMap().get(name); + if (modelScreen == null) { + throw new IllegalArgumentException("Could not find screen with name [" + name + "] in the same file as the screen with name [" + parentWidget.getModelScreen().getName() + "]"); + } + } + //Debug.logInfo("parent(" + parentWidget + ") rendering(" + modelScreen + ")", module); + modelScreen.renderScreenString(writer, context, screenStringRenderer); + } +} Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/TreeFactory.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/TreeFactory.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/TreeFactory.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/TreeFactory.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,87 @@ +/******************************************************************************* + * 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.xml.parsers.ParserConfigurationException; + +import org.ofbiz.base.location.FlexibleLocation; +import org.ofbiz.base.util.UtilXml; +import org.ofbiz.base.util.cache.UtilCache; +import org.ofbiz.entity.Delegator; +import org.ofbiz.service.LocalDispatcher; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + + +/** + * Widget Library - Tree factory class + */ +public class TreeFactory { + + public static final String module = TreeFactory.class.getName(); + + public static final UtilCache<String, Map<String, ModelTree>> treeLocationCache = UtilCache.createUtilCache("widget.tree.locationResource", 0, 0, false); + + public static ModelTree getTreeFromLocation(String resourceName, String treeName, Delegator delegator, LocalDispatcher dispatcher) + throws IOException, SAXException, ParserConfigurationException { + Map<String, ModelTree> modelTreeMap = treeLocationCache.get(resourceName); + if (modelTreeMap == null) { + synchronized (TreeFactory.class) { + modelTreeMap = treeLocationCache.get(resourceName); + if (modelTreeMap == null) { + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + if (loader == null) { + loader = TreeFactory.class.getClassLoader(); + } + + URL treeFileUrl = null; + treeFileUrl = FlexibleLocation.resolveLocation(resourceName); //, loader); + Document treeFileDoc = UtilXml.readXmlDocument(treeFileUrl, true, true); + modelTreeMap = readTreeDocument(treeFileDoc, delegator, dispatcher, resourceName); + treeLocationCache.put(resourceName, modelTreeMap); + } + } + } + + ModelTree modelTree = modelTreeMap.get(treeName); + if (modelTree == null) { + throw new IllegalArgumentException("Could not find tree with name [" + treeName + "] in class resource [" + resourceName + "]"); + } + return modelTree; + } + + public static Map<String, ModelTree> readTreeDocument(Document treeFileDoc, Delegator delegator, LocalDispatcher dispatcher, String treeLocation) { + Map<String, ModelTree> modelTreeMap = new HashMap<String, ModelTree>(); + if (treeFileDoc != null) { + // read document and construct ModelTree for each tree element + Element rootElement = treeFileDoc.getDocumentElement(); + for (Element treeElement: UtilXml.childElementList(rootElement, "tree")) { + ModelTree modelTree = new ModelTree(treeElement, treeLocation); + modelTreeMap.put(modelTree.getName(), modelTree); + } + } + return modelTreeMap; + } +} Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlAbstractWidgetVisitor.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlAbstractWidgetVisitor.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlAbstractWidgetVisitor.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlAbstractWidgetVisitor.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,165 @@ +/******************************************************************************* + * 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.Collection; + +import org.ofbiz.base.util.Assert; +import org.ofbiz.base.util.collections.FlexibleMapAccessor; +import org.ofbiz.base.util.string.FlexibleStringExpander; +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; + +/** + * Abstract XML widget visitor. + * + */ +public abstract class XmlAbstractWidgetVisitor { + + protected final Appendable writer; + + public XmlAbstractWidgetVisitor(Appendable writer) { + Assert.notNull("writer", writer); + this.writer = writer; + } + + protected void visitAttribute(String attributeName, Boolean attributeValue) throws Exception { + if (attributeValue != null) { + writer.append(" ").append(attributeName).append("=\""); + writer.append(attributeValue.toString()); + writer.append("\""); + } + } + + protected void visitAttribute(String attributeName, FlexibleMapAccessor<?> attributeValue) throws Exception { + if (attributeValue != null && !attributeValue.isEmpty()) { + writer.append(" ").append(attributeName).append("=\""); + writer.append(attributeValue.getOriginalName()); + writer.append("\""); + } + } + + protected void visitAttribute(String attributeName, FlexibleStringExpander attributeValue) throws Exception { + if (attributeValue != null && !attributeValue.isEmpty()) { + writer.append(" ").append(attributeName).append("=\""); + writer.append(attributeValue.getOriginal()); + writer.append("\""); + } + } + + protected void visitAttribute(String attributeName, Integer attributeValue) throws Exception { + if (attributeValue != null) { + writer.append(" ").append(attributeName).append("=\""); + writer.append(attributeValue.toString()); + writer.append("\""); + } + } + + protected void visitAttribute(String attributeName, String attributeValue) throws Exception { + if (attributeValue != null && !attributeValue.isEmpty()) { + writer.append(" ").append(attributeName).append("=\""); + writer.append(attributeValue); + writer.append("\""); + } + } + + protected void visitAutoEntityParameters(AutoEntityParameters autoEntityParameters) throws Exception { + + } + + protected void visitAutoServiceParameters(AutoServiceParameters autoServiceParameters) throws Exception { + + } + + protected void visitImage(Image image) throws Exception { + if (image != null) { + writer.append("<image"); + visitAttribute("name", image.getName()); + visitAttribute("alt", image.getAlt()); + visitAttribute("border", image.getBorderExdr()); + visitAttribute("height", image.getHeightExdr()); + visitAttribute("id", image.getIdExdr()); + visitAttribute("src", image.getSrcExdr()); + visitAttribute("style", image.getStyleExdr()); + visitAttribute("title", image.getTitleExdr()); + visitAttribute("url-mode", image.getUrlMode()); + visitAttribute("width", image.getWidthExdr()); + writer.append("/>"); + } + } + + protected void visitLink(Link link) throws Exception { + if (link != null) { + writer.append("<link"); + visitLinkAttributes(link); + if (link.getImage() != null || link.getAutoEntityParameters() != null || link.getAutoServiceParameters() != null) { + writer.append(">"); + visitImage(link.getImage()); + visitAutoEntityParameters(link.getAutoEntityParameters()); + visitAutoServiceParameters(link.getAutoServiceParameters()); + writer.append("</link>"); + } else { + writer.append("/>"); + } + } + } + + protected void visitLinkAttributes(Link link) throws Exception { + if (link != null) { + visitAttribute("name", link.getName()); + visitAttribute("encode", link.getEncode()); + visitAttribute("full-path", link.getFullPath()); + visitAttribute("id", link.getIdExdr()); + visitAttribute("height", link.getHeight()); + visitAttribute("link-type", link.getLinkType()); + visitAttribute("prefix", link.getPrefixExdr()); + visitAttribute("secure", link.getSecure()); + visitAttribute("style", link.getStyleExdr()); + visitAttribute("target", link.getTargetExdr()); + visitAttribute("target-window", link.getTargetWindowExdr()); + visitAttribute("text", link.getTextExdr()); + visitAttribute("size", link.getSize()); + visitAttribute("url-mode", link.getUrlMode()); + visitAttribute("width", link.getWidth()); + } + } + + protected void visitModelWidget(ModelWidget widget) throws Exception { + if (widget.getName() != null && !widget.getName().isEmpty()) { + writer.append(" name=\""); + writer.append(widget.getName()); + writer.append("\""); + } + } + + protected void visitParameters(Collection<Parameter> parameters) throws Exception { + if (parameters != null) { + for (Parameter parameter : parameters) { + writer.append("<parameter"); + visitAttribute("param-name", parameter.getName()); + visitAttribute("from-field", parameter.getFromField()); + visitAttribute("value", parameter.getValue()); + writer.append("/>"); + } + } + } +} Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetActionVisitor.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetActionVisitor.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetActionVisitor.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetActionVisitor.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,210 @@ +/******************************************************************************* + * 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 org.ofbiz.widget.model.AbstractModelAction.EntityAnd; +import org.ofbiz.widget.model.AbstractModelAction.EntityCondition; +import org.ofbiz.widget.model.AbstractModelAction.EntityOne; +import org.ofbiz.widget.model.AbstractModelAction.GetRelated; +import org.ofbiz.widget.model.AbstractModelAction.GetRelatedOne; +import org.ofbiz.widget.model.AbstractModelAction.PropertyMap; +import org.ofbiz.widget.model.AbstractModelAction.PropertyToField; +import org.ofbiz.widget.model.AbstractModelAction.Script; +import org.ofbiz.widget.model.AbstractModelAction.Service; +import org.ofbiz.widget.model.AbstractModelAction.SetField; +import org.ofbiz.widget.model.ModelFormAction.CallParentActions; + +/** + * An object that generates XML from widget models. + * The generated XML is unformatted - if you want to + * "pretty print" the XML, then use a transformer. + * + */ +public class XmlWidgetActionVisitor extends XmlAbstractWidgetVisitor implements ModelActionVisitor { + + public static final String module = XmlWidgetActionVisitor.class.getName(); + + public XmlWidgetActionVisitor(Appendable writer) { + super(writer); + } + + @Override + public void visit(CallParentActions callParentActions) throws Exception { + writer.append("<call-parent-actions/>"); + } + + @Override + public void visit(EntityAnd entityAnd) throws Exception { + writer.append("<entity-and/>"); + // TODO: Create ByAndFinder visitor + } + + @Override + public void visit(org.ofbiz.widget.model.ModelTreeAction.EntityAnd entityAnd) throws Exception { + writer.append("<entity-and/>"); + // TODO: Create ByAndFinder visitor + } + + @Override + public void visit(EntityCondition entityCondition) throws Exception { + writer.append("<entity-condition/>"); + // TODO: Create ByConditionFinder visitor + } + + @Override + public void visit(org.ofbiz.widget.model.ModelTreeAction.EntityCondition entityCondition) throws Exception { + writer.append("<entity-condition/>"); + // TODO: Create ByConditionFinder visitor + } + + @Override + public void visit(EntityOne entityOne) throws Exception { + writer.append("<entity-one/>"); + // TODO: Create PrimaryKeyFinder visitor + } + + @Override + public void visit(GetRelated getRelated) throws Exception { + writer.append("<get-related"); + visitAttribute("value-field", getRelated.getValueNameAcsr()); + visitAttribute("list", getRelated.getListNameAcsr()); + visitAttribute("relation-name", getRelated.getRelationName()); + visitAttribute("map", getRelated.getMapAcsr()); + visitAttribute("order-by-list", getRelated.getOrderByListAcsr()); + visitAttribute("use-cache", getRelated.getUseCache()); + writer.append("/>"); + } + + @Override + public void visit(GetRelatedOne getRelatedOne) throws Exception { + writer.append("<get-related-one"); + visitAttribute("value-field", getRelatedOne.getValueNameAcsr()); + visitAttribute("to-value-field", getRelatedOne.getToValueNameAcsr()); + visitAttribute("relation-name", getRelatedOne.getRelationName()); + visitAttribute("use-cache", getRelatedOne.getUseCache()); + writer.append("/>"); + } + + @Override + public void visit(PropertyMap propertyMap) throws Exception { + writer.append("<property-map"); + visitAttribute("resource", propertyMap.getResourceExdr()); + visitAttribute("map-name", propertyMap.getMapNameAcsr()); + visitAttribute("global", propertyMap.getGlobalExdr()); + writer.append("/>"); + } + + @Override + public void visit(PropertyToField propertyToField) throws Exception { + writer.append("<property-map"); + visitAttribute("resource", propertyToField.getResourceExdr()); + visitAttribute("property", propertyToField.getPropertyExdr()); + visitAttribute("field", propertyToField.getFieldAcsr()); + visitAttribute("default", propertyToField.getDefaultExdr()); + visitAttribute("no-locale", propertyToField.getNoLocale()); + visitAttribute("arg-list-name", propertyToField.getArgListAcsr()); + visitAttribute("global", propertyToField.getGlobalExdr()); + writer.append("/>"); + } + + @Override + public void visit(Script script) throws Exception { + writer.append("<script"); + visitAttribute("location", script.getLocation()); + visitAttribute("method", script.getMethod()); + writer.append("/>"); + } + + @Override + public void visit(org.ofbiz.widget.model.ModelTreeAction.Script script) throws Exception { + writer.append("<script"); + visitAttribute("location", script.getLocation()); + visitAttribute("method", script.getMethod()); + writer.append("/>"); + } + + @Override + public void visit(Service service) throws Exception { + writer.append("<service"); + visitAttribute("service-name", service.getServiceNameExdr()); + visitAttribute("result-map", service.getResultMapNameAcsr()); + visitAttribute("auto-field-map", service.getAutoFieldMapExdr()); + writer.append(">"); + // TODO: Create Field Map visitor + writer.append("<field-map/>"); + writer.append("</service>"); + } + + @Override + public void visit(org.ofbiz.widget.model.ModelFormAction.Service service) throws Exception { + writer.append("<service"); + visitAttribute("service-name", service.getServiceNameExdr()); + visitAttribute("result-map", service.getResultMapNameAcsr()); + visitAttribute("auto-field-map", service.getAutoFieldMapExdr()); + visitAttribute("result-map-list", service.getResultMapListNameExdr()); + visitAttribute("ignore-error", service.getIgnoreError()); + writer.append(">"); + // TODO: Create Field Map visitor + writer.append("<field-map/>"); + writer.append("</service>"); + } + + @Override + public void visit(org.ofbiz.widget.model.ModelTreeAction.Service service) throws Exception { + writer.append("<service"); + visitAttribute("service-name", service.getServiceNameExdr()); + visitAttribute("result-map", service.getResultMapNameAcsr()); + visitAttribute("auto-field-map", service.getAutoFieldMapExdr()); + visitAttribute("result-map-list", service.getResultMapListNameExdr()); + visitAttribute("result-map-value", service.getResultMapValueNameExdr()); + visitAttribute("value", service.getValueNameExdr()); + writer.append(">"); + // TODO: Create Field Map visitor + writer.append("<field-map/>"); + writer.append("</service>"); + } + + @Override + public void visit(SetField setField) throws Exception { + writer.append("<set"); + visitAttribute("field", setField.getField()); + visitAttribute("from-field", setField.getFromField()); + visitAttribute("value", setField.getValueExdr()); + visitAttribute("default-value", setField.getDefaultExdr()); + visitAttribute("global", setField.getGlobalExdr()); + visitAttribute("type", setField.getType()); + visitAttribute("to-scope", setField.getToScope()); + visitAttribute("from-scope", setField.getFromScope()); + writer.append("/>"); + } + + @Override + public void visit(org.ofbiz.widget.model.ModelMenuAction.SetField setField) throws Exception { + writer.append("<set"); + visitAttribute("field", setField.getField()); + visitAttribute("from-field", setField.getFromField()); + visitAttribute("value", setField.getValueExdr()); + visitAttribute("default-value", setField.getDefaultExdr()); + visitAttribute("global", setField.getGlobalExdr()); + visitAttribute("type", setField.getType()); + visitAttribute("to-scope", setField.getToScope()); + visitAttribute("from-scope", setField.getFromScope()); + writer.append("/>"); + } +} Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetConditionVisitor.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetConditionVisitor.java?rev=1652852&view=auto ============================================================================== --- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetConditionVisitor.java (added) +++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/model/XmlWidgetConditionVisitor.java Sun Jan 18 21:03:40 2015 @@ -0,0 +1,178 @@ +/******************************************************************************* + * 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.Collection; + +import org.ofbiz.widget.model.AbstractModelCondition.And; +import org.ofbiz.widget.model.AbstractModelCondition.IfCompare; +import org.ofbiz.widget.model.AbstractModelCondition.IfCompareField; +import org.ofbiz.widget.model.AbstractModelCondition.IfEmpty; +import org.ofbiz.widget.model.AbstractModelCondition.IfEntityPermission; +import org.ofbiz.widget.model.AbstractModelCondition.IfHasPermission; +import org.ofbiz.widget.model.AbstractModelCondition.IfRegexp; +import org.ofbiz.widget.model.AbstractModelCondition.IfServicePermission; +import org.ofbiz.widget.model.AbstractModelCondition.IfValidateMethod; +import org.ofbiz.widget.model.AbstractModelCondition.Not; +import org.ofbiz.widget.model.AbstractModelCondition.Or; +import org.ofbiz.widget.model.AbstractModelCondition.Xor; +import org.ofbiz.widget.model.ModelScreenCondition.IfEmptySection; + +/** + * An object that generates XML from widget models. + * The generated XML is unformatted - if you want to + * "pretty print" the XML, then use a transformer. + * + */ +public class XmlWidgetConditionVisitor extends XmlAbstractWidgetVisitor implements ModelConditionVisitor { + + public XmlWidgetConditionVisitor(Appendable writer) { + super(writer); + } + + @Override + public void visit(And and) throws Exception { + writer.append("<and>"); + visitSubConditions(and.getSubConditions()); + writer.append("</and>"); + } + + @Override + public void visit(IfCompare ifCompare) throws Exception { + writer.append("<if-compare"); + visitAttribute("field", ifCompare.getFieldAcsr()); + visitAttribute("operator", ifCompare.getOperator()); + visitAttribute("value", ifCompare.getValueExdr()); + visitAttribute("type", ifCompare.getType()); + visitAttribute("format", ifCompare.getFormatExdr()); + writer.append("/>"); + } + + @Override + public void visit(IfCompareField ifCompareField) throws Exception { + writer.append("<if-compare-field"); + visitAttribute("field", ifCompareField.getFieldAcsr()); + visitAttribute("operator", ifCompareField.getOperator()); + visitAttribute("to-field", ifCompareField.getToFieldAcsr()); + visitAttribute("type", ifCompareField.getType()); + visitAttribute("format", ifCompareField.getFormatExdr()); + writer.append("/>"); + } + + @Override + public void visit(IfEmpty ifEmpty) throws Exception { + writer.append("<if-empty"); + visitAttribute("field", ifEmpty.getFieldAcsr()); + writer.append("/>"); + } + + @Override + public void visit(IfEmptySection ifEmptySection) throws Exception { + writer.append("<if-empty-section"); + visitAttribute("section-name", ifEmptySection.getSectionExdr()); + writer.append("/>"); + } + + @Override + public void visit(IfEntityPermission ifEntityPermission) throws Exception { + writer.append("<if-entity-permission"); + // TODO: Create EntityPermissionChecker visitor + writer.append("/>"); + } + + @Override + public void visit(IfHasPermission ifHasPermission) throws Exception { + writer.append("<if-has-permission"); + visitAttribute("permission", ifHasPermission.getPermissionExdr()); + visitAttribute("action", ifHasPermission.getActionExdr()); + writer.append("/>"); + } + + @Override + public void visit(IfRegexp ifRegexp) throws Exception { + writer.append("<if-regexp"); + visitAttribute("field", ifRegexp.getFieldAcsr()); + visitAttribute("expr", ifRegexp.getExprExdr()); + writer.append("/>"); + } + + @Override + public void visit(IfServicePermission ifServicePermission) throws Exception { + writer.append("<if-service-permission"); + visitAttribute("service-name", ifServicePermission.getServiceExdr()); + visitAttribute("main-action", ifServicePermission.getActionExdr()); + visitAttribute("context-map", ifServicePermission.getCtxMapExdr()); + visitAttribute("resource-description", ifServicePermission.getResExdr()); + writer.append("/>"); + } + + @Override + public void visit(IfValidateMethod ifValidateMethod) throws Exception { + writer.append("<if-validate-method"); + visitAttribute("field", ifValidateMethod.getFieldAcsr()); + visitAttribute("method", ifValidateMethod.getMethodExdr()); + visitAttribute("class", ifValidateMethod.getClassExdr()); + writer.append("/>"); + } + + @Override + public void visit(ModelMenuCondition modelMenuCondition) throws Exception { + writer.append("<condition"); + visitAttribute("pass-style", modelMenuCondition.getPassStyleExdr()); + visitAttribute("disabled-style", modelMenuCondition.getFailStyleExdr()); + writer.append("/>"); + modelMenuCondition.getCondition().accept(this); + ; + writer.append("</condition>"); + } + + @Override + public void visit(ModelTreeCondition modelTreeCondition) throws Exception { + writer.append("<condition>"); + modelTreeCondition.getCondition().accept(this); + writer.append("</condition>"); + } + + @Override + public void visit(Not not) throws Exception { + writer.append("<not>"); + not.getSubCondition().accept(this); + writer.append("</not>"); + } + + @Override + public void visit(Or or) throws Exception { + writer.append("<or>"); + visitSubConditions(or.getSubConditions()); + writer.append("</or>"); + } + + @Override + public void visit(Xor xor) throws Exception { + writer.append("<xor>"); + visitSubConditions(xor.getSubConditions()); + writer.append("</xor>"); + } + + private void visitSubConditions(Collection<ModelCondition> subConditions) throws Exception { + for (ModelCondition subCondition : subConditions) { + subCondition.accept(this); + } + } +} |
Free forum by Nabble | Edit this page |