You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ad...@apache.org on 2012/04/20 12:26:39 UTC

svn commit: r1328302 [3/3] - in /ofbiz/trunk/framework/minilang: config/ dtd/ src/org/ofbiz/minilang/ src/org/ofbiz/minilang/method/

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangException.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangException.java?rev=1328302&r1=1328301&r2=1328302&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangException.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangException.java Fri Apr 20 10:26:38 2012
@@ -19,7 +19,7 @@
 package org.ofbiz.minilang;
 
 /**
- * MiniLangException
+ * Thrown to indicate a Mini-language error.
  */
 @SuppressWarnings("serial")
 public class MiniLangException extends org.ofbiz.base.util.GeneralException {

Added: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangRuntimeException.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangRuntimeException.java?rev=1328302&view=auto
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangRuntimeException.java (added)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangRuntimeException.java Fri Apr 20 10:26:38 2012
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.minilang;
+
+import org.ofbiz.minilang.method.MethodOperation;
+
+/**
+ * Thrown to indicate a Mini-language run-time error. 
+ */
+@SuppressWarnings("serial")
+public class MiniLangRuntimeException extends MiniLangException {
+
+    private final MethodOperation operation;
+
+    public MiniLangRuntimeException(String str, MethodOperation operation) {
+        super(str);
+        this.operation = operation;
+    }
+
+    @Override
+    public String getMessage() {
+        StringBuilder sb = new StringBuilder(super.getMessage());
+        if (operation != null) {
+            SimpleMethod method = operation.getSimpleMethod();
+            sb.append(" Method = ").append(method.methodName).append(", File = ").append(method.getFromLocation());
+            sb.append(", Element = <").append(operation.getTagName()).append(">");
+            sb.append(", Line ").append(operation.getLineNumber());
+        }
+        return sb.toString();
+    }
+}

Propchange: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangRuntimeException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangRuntimeException.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Added: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangUtil.java?rev=1328302&view=auto
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangUtil.java (added)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangUtil.java Fri Apr 20 10:26:38 2012
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * 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.minilang;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.ofbiz.base.util.ScriptUtil;
+import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+
+/**
+ * Mini-language utilities.
+ */
+public final class MiniLangUtil {
+
+    public static final String module = MiniLangUtil.class.getName();
+
+    public static final Set<String> SCRIPT_PREFIXES;
+
+    static {
+        Set<String> scriptPrefixes = new HashSet<String>();
+        for (String scriptName : ScriptUtil.SCRIPT_NAMES) {
+            scriptPrefixes.add(scriptName.concat(":"));
+        }
+        SCRIPT_PREFIXES = Collections.unmodifiableSet(scriptPrefixes);
+    }
+
+    public static boolean containsScript(String str) {
+        if (str.length() > 0) {
+            for (String scriptPrefix : SCRIPT_PREFIXES) {
+                if (str.contains(scriptPrefix)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public static boolean autoCorrectOn() {
+        return "true".equals(UtilProperties.getPropertyValue("minilang.properties", "autocorrect"));
+    }
+
+    public static void flagDocumentAsCorrected(Element element) {
+        Document doc = element.getOwnerDocument();
+        if (doc != null) {
+            doc.setUserData("autoCorrected", "true", null);
+        }
+    }
+
+    public static boolean isConstantAttribute(String attributeValue) {
+        if (attributeValue.length() > 0) {
+            return !FlexibleStringExpander.containsExpression(FlexibleStringExpander.getInstance(attributeValue));
+        }
+        return true;
+    }
+
+    public static boolean isConstantPlusExpressionAttribute(String attributeValue) {
+        if (attributeValue.length() > 0) {
+            FlexibleStringExpander fse = FlexibleStringExpander.getInstance(attributeValue);
+            return FlexibleStringExpander.containsConstant(fse);
+        }
+        return true;
+    }
+
+    public static void removeInvalidAttributes(Element element, String... validAttributeNames) {
+        Set<String> validNames = new HashSet<String>();
+        for (String name : validAttributeNames) {
+            validNames.add(name);
+        }
+        boolean elementModified = false;
+        NamedNodeMap nnm = element.getAttributes();
+        for (int i = 0; i < nnm.getLength(); i++) {
+            String attributeName = nnm.item(i).getNodeName();
+            if (!validNames.contains(attributeName)) {
+                element.removeAttribute(attributeName);
+                elementModified = true;
+            }
+        }
+        if (elementModified) {
+            flagDocumentAsCorrected(element);
+        }
+    }
+
+    private MiniLangUtil() {}
+}

Propchange: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangUtil.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Added: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangValidate.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangValidate.java?rev=1328302&view=auto
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangValidate.java (added)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangValidate.java Fri Apr 20 10:26:38 2012
@@ -0,0 +1,350 @@
+/*******************************************************************************
+ * 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.minilang;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.ScriptUtil;
+import org.ofbiz.base.util.UtilProperties;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+/**
+ * Mini-language validation.
+ */
+public final class MiniLangValidate {
+
+    public static final String module = MiniLangValidate.class.getName();
+
+    /**
+     * Tests <code>element</code> for invalid attribute names.
+     * 
+     * @param method The <code>&lt;simple-method&gt;</code> that contains <code>element</code> 
+     * @param element The <code>element</code> to test
+     * @param validAttributeNames The valid attribute names
+     * @throws ValidationException If an invalid attribute name is found and <code>validation.level=strict</code>
+     */
+    public static void attributeNames(SimpleMethod method, Element element, String... validAttributeNames) throws ValidationException {
+        Set<String> validNames = new HashSet<String>();
+        for (String name : validAttributeNames) {
+            validNames.add(name);
+        }
+        NamedNodeMap nnm = element.getAttributes();
+        for (int i = 0; i < nnm.getLength(); i++) {
+            String attributeName = nnm.item(i).getNodeName();
+            if (!validNames.contains(attributeName)) {
+                handleError("Attribute name \"" + attributeName + "\" is not valid.", method, element);
+            }
+        }
+    }
+
+    /**
+     * Tests <code>element</code> for invalid child elements.
+     * 
+     * @param method The <code>&lt;simple-method&gt;</code> that contains <code>element</code> 
+     * @param element The <code>element</code> to test
+     * @param validChildElementNames The valid child element tag names
+     * @throws ValidationException If an invalid child element is found and <code>validation.level=strict</code>
+     */
+    public static void childElements(SimpleMethod method, Element element, String... validChildElementNames) throws ValidationException {
+        Set<String> validNames = new HashSet<String>();
+        for (String name : validChildElementNames) {
+            validNames.add(name);
+        }
+        Node node = element.getFirstChild();
+        while (node != null) {
+            if (node.getNodeType() == Node.ELEMENT_NODE) {
+                Element childElement = (Element) node;
+                if (!validNames.contains(childElement.getTagName())) {
+                    handleError("Child element <" + childElement.getTagName() + "> is not valid.", method, element);
+                }
+            }
+            node = node.getNextSibling();
+        }
+    }
+
+    /**
+     * Tests if element attributes are constant type.
+     * 
+     * @param method The <code>&lt;simple-method&gt;</code> that contains <code>element</code> 
+     * @param element The <code>element</code> to test
+     * @param attributeNames The attributes to test
+     * @throws ValidationException If an invalid attribute is found and <code>validation.level=strict</code>
+     */
+    public static void constantAttributes(SimpleMethod method, Element element, String... attributeNames) throws ValidationException {
+        for (String name : attributeNames) {
+            String attributeValue = element.getAttribute(name).trim();
+            if (!MiniLangUtil.isConstantAttribute(attributeValue)) {
+                handleError("Constant attribute \"" + name + "\" cannot contain an expression.", method, element);
+            }
+        }
+    }
+
+    /**
+     * Tests if element attributes are constant+expr type.
+     * 
+     * @param method The <code>&lt;simple-method&gt;</code> that contains <code>element</code> 
+     * @param element The <code>element</code> to test
+     * @param attributeNames The attributes to test
+     * @throws ValidationException If an invalid attribute is found and <code>validation.level=strict</code>
+     */
+    public static void constantPlusExpressionAttributes(SimpleMethod method, Element element, String... attributeNames) throws ValidationException {
+        for (String name : attributeNames) {
+            String attributeValue = element.getAttribute(name).trim();
+            if (!MiniLangUtil.isConstantPlusExpressionAttribute(attributeValue)) {
+                handleError("Constant+expr attribute \"" + name + "\" is missing a constant value (expression-only constants are not allowed).", method, element);
+            }
+            if (MiniLangUtil.containsScript(attributeValue)) {
+                handleError("Constant+expr attribute \"" + name + "\" cannot contain a script (remove script).", method, element);
+            }
+        }
+    }
+
+    /**
+     * Tests <code>element</code> for a deprecated attribute.
+     * 
+     * @param method The <code>&lt;simple-method&gt;</code> that contains <code>element</code> 
+     * @param element The <code>element</code> to test
+     * @param attributeName The name of the deprecated attribute
+     * @param fixInstruction Instructions to fix the deprecated attribute
+     * @throws ValidationException If the deprecated attribute is found and <code>validation.level=strict</code>
+     */
+    public static void deprecatedAttribute(SimpleMethod method, Element element, String attributeName, String fixInstruction) throws ValidationException {
+        String attributeValue = element.getAttribute(attributeName);
+        if (attributeValue.length() > 0) {
+            handleError("Attribute \"" + attributeName + "\" is deprecated (" + fixInstruction + ")", method, element);
+        }
+    }
+
+    /**
+     * Tests if element attributes are expression type.
+     * 
+     * @param method The <code>&lt;simple-method&gt;</code> that contains <code>element</code> 
+     * @param element The <code>element</code> to test
+     * @param attributeNames The attributes to test
+     * @throws ValidationException If an invalid attribute is found and <code>validation.level=strict</code>
+     */
+    public static void expressionAttributes(SimpleMethod method, Element element, String... attributeNames) throws ValidationException {
+        for (String name : attributeNames) {
+            String attributeValue = element.getAttribute(name).trim();
+            if (attributeValue.length() > 0) {
+                if (attributeValue.startsWith("${") && attributeValue.endsWith("}")) {
+                    handleError("Expression attribute \"" + name + "\" enclosed in \"${}\" (remove enclosing ${}).", method, element);
+                }
+                if (MiniLangUtil.containsScript(attributeValue)) {
+                    handleError("Expression attribute \"" + name + "\" cannot contain a script (remove script).", method, element);
+                }
+            }
+        }
+    }
+
+    /**
+     * Handles a Mini-language validation error.
+     * 
+     * @param errorMessage The error message
+     * @param method The <code>&lt;simple-method&gt;</code> that contains <code>element</code> 
+     * @param element The <code>element</code> that contains the error
+     * @throws ValidationException If <code>validation.level=strict</code>, otherwise a warning is logged
+     */
+    public static void handleError(String errorMessage, SimpleMethod method, Element element) throws ValidationException {
+        ValidationException e = new ValidationException(errorMessage, method, element);
+        if (strictOn()) {
+            throw e;
+        } else {
+            Debug.logWarning(e.getMessage(), module);
+        }
+    }
+
+    /**
+     * Returns <code>true</code> if <code>validation.level=lenient</code>.
+     * 
+     * @return <code>true</code> if <code>validation.level=lenient</code>
+     */
+    public static boolean lenientOn() {
+        return "lenient".equals(UtilProperties.getPropertyValue("minilang.properties", "validation.level"));
+    }
+
+    /**
+     * Tests <code>element</code> for child elements.
+     * 
+     * @param method The <code>&lt;simple-method&gt;</code> that contains <code>element</code> 
+     * @param element The <code>element</code> to test
+     * @throws ValidationException If a child element is found and <code>validation.level=strict</code>
+     */
+    public static void noChildElements(SimpleMethod method, Element element) throws ValidationException {
+        Node node = element.getFirstChild();
+        while (node != null) {
+            if (node.getNodeType() == Node.ELEMENT_NODE) {
+                Element childElement = (Element) node;
+                handleError("Child element <" + childElement.getTagName() + "> is not valid.", method, element);
+            }
+            node = node.getNextSibling();
+        }
+    }
+
+    /**
+     * Tests <code>element</code> for any one required attribute from a set of attribute names.
+     * 
+     * @param method The <code>&lt;simple-method&gt;</code> that contains <code>element</code> 
+     * @param element The <code>element</code> to test
+     * @param attributeNames The required attribute names
+     * @throws ValidationException If none of the required attributes are found and <code>validation.level=strict</code>
+     */
+    public static void requireAnyAttribute(SimpleMethod method, Element element, String... attributeNames) throws ValidationException {
+        StringBuilder sb = new StringBuilder();
+        for (String name : attributeNames) {
+            String attributeValue = element.getAttribute(name).trim();
+            if (attributeValue.length() > 0) {
+                return;
+            }
+            if (sb.length() > 0) {
+                sb.append(" ");
+            }
+            sb.append("\"").append(name).append("\"");
+        }
+        handleError("Element must include one of " + sb + " attributes.", method, element);
+    }
+
+    /**
+     * Tests <code>element</code> for any one required child element from a set of tag names.
+     * 
+     * @param method The <code>&lt;simple-method&gt;</code> that contains <code>element</code> 
+     * @param element The <code>element</code> to test
+     * @param elementNames The required child element tag names
+     * @throws ValidationException If none of the required child elements are found and <code>validation.level=strict</code>
+     */
+    public static void requireAnyChildElement(SimpleMethod method, Element element, String... elementNames) throws ValidationException {
+        Set<String> childElementNames = new HashSet<String>();
+        Node node = element.getFirstChild();
+        while (node != null) {
+            if (node.getNodeType() == Node.ELEMENT_NODE) {
+                Element childElement = (Element) node;
+                childElementNames.add(childElement.getTagName());
+            }
+            node = node.getNextSibling();
+        }
+        StringBuilder sb = new StringBuilder();
+        for (String name : elementNames) {
+            if (childElementNames.contains(name)) {
+                return;
+            }
+            if (sb.length() > 0) {
+                sb.append(", ");
+            }
+            sb.append("<").append(name).append(">");
+        }
+        handleError("Element must include one of " + sb + " child elements.", method, element);
+    }
+
+    /**
+     * Tests <code>element</code> for required attributes.
+     * 
+     * @param method The <code>&lt;simple-method&gt;</code> that contains <code>element</code> 
+     * @param element The <code>element</code> to test
+     * @param attributeNames The required attribute names
+     * @throws ValidationException If any of the required attributes are not found and <code>validation.level=strict</code>
+     */
+    public static void requiredAttributes(SimpleMethod method, Element element, String... attributeNames) throws ValidationException {
+        for (String name : attributeNames) {
+            String attributeValue = element.getAttribute(name).trim();
+            if (attributeValue.length() == 0) {
+                handleError("Required attribute \"" + name + "\" is missing.", method, element);
+            }
+        }
+    }
+
+    /**
+     * Tests <code>element</code> for required child elements.
+     * 
+     * @param method The <code>&lt;simple-method&gt;</code> that contains <code>element</code> 
+     * @param element The <code>element</code> to test
+     * @param elementNames The required child element tag names
+     * @throws ValidationException If any of the required child elements are not found and <code>validation.level=strict</code>
+     */
+    public static void requiredChildElements(SimpleMethod method, Element element, String... elementNames) throws ValidationException {
+        Set<String> childElementNames = new HashSet<String>();
+        Node node = element.getFirstChild();
+        while (node != null) {
+            if (node.getNodeType() == Node.ELEMENT_NODE) {
+                Element childElement = (Element) node;
+                childElementNames.add(childElement.getTagName());
+            }
+            node = node.getNextSibling();
+        }
+        for (String name : elementNames) {
+            if (!childElementNames.contains(name)) {
+                handleError("Required child element <" + name + "> is missing.", method, element);
+            }
+        }
+    }
+
+    /**
+     * Tests if element attributes are script type.
+     * 
+     * @param method The <code>&lt;simple-method&gt;</code> that contains <code>element</code> 
+     * @param element The <code>element</code> to test
+     * @param attributeNames The attributes to test
+     * @throws ValidationException If an invalid attribute is found and <code>validation.level=strict</code>
+     */
+    public static void scriptAttributes(SimpleMethod method, Element element, String... attributeNames) throws ValidationException {
+        for (String name : attributeNames) {
+            String attributeValue = element.getAttribute(name).trim();
+            if (attributeValue.length() > 0) {
+                if (attributeValue.startsWith("${") && attributeValue.endsWith("}")) {
+                    handleError("Script attribute \"" + name + "\" enclosed in \"${}\" (remove enclosing ${}).", method, element);
+                }
+                boolean scriptFound = false;
+                for (String scriptName : ScriptUtil.SCRIPT_NAMES) {
+                    String scriptPrefix = scriptName.concat(":");
+                    if (attributeValue.contains(scriptPrefix)) {
+                        scriptFound = true;
+                        break;
+                    }
+                }
+                if (!scriptFound) {
+                    handleError("Script attribute \"" + name + "\" does not contain a script.", method, element);
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns <code>true</code> if <code>validation.level=strict</code>.
+     * 
+     * @return <code>true</code> if <code>validation.level=strict</code>
+     */
+    public static boolean strictOn() {
+        return "strict".equals(UtilProperties.getPropertyValue("minilang.properties", "validation.level"));
+    }
+
+    /**
+     * Returns <code>true</code> if <code>validation.level</code> is set to lenient or strict.
+     * 
+     * @return <code>true</code> if <code>validation.level</code> is set to lenient or strict
+     */
+    public static boolean validationOn() {
+        return !"none".equals(UtilProperties.getPropertyValue("minilang.properties", "validation.level"));
+    }
+
+    private MiniLangValidate() {}
+
+}

Propchange: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangValidate.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/MiniLangValidate.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Added: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/ValidationException.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/ValidationException.java?rev=1328302&view=auto
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/ValidationException.java (added)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/ValidationException.java Fri Apr 20 10:26:38 2012
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * 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.minilang;
+
+import org.w3c.dom.Element;
+
+/**
+ * Thrown to indicate that a Mini-language element is invalid. 
+ */
+@SuppressWarnings("serial")
+public class ValidationException extends MiniLangException {
+
+    private final SimpleMethod method;
+    private final Element element;
+
+    public ValidationException(String str, SimpleMethod method, Element element) {
+        super(str);
+        this.method = method;
+        this.element = element;
+    }
+
+    @Override
+    public String getMessage() {
+        StringBuilder sb = new StringBuilder(super.getMessage());
+        if (method != null) {
+            sb.append(" Method = ").append(method.methodName).append(", File = ").append(method.getFromLocation());
+        }
+        if (element != null) {
+            sb.append(", Element = <").append(element.getTagName()).append(">");
+            Object lineNumber = element.getUserData("startLine");
+            if (lineNumber != null) {
+                sb.append(", Line ").append(lineNumber);
+            }
+        }
+        return sb.toString();
+    }
+}

Propchange: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/ValidationException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/ValidationException.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/MethodOperation.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/MethodOperation.java?rev=1328302&r1=1328301&r2=1328302&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/MethodOperation.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/MethodOperation.java Fri Apr 20 10:26:38 2012
@@ -32,10 +32,14 @@ import org.w3c.dom.Element;
  */
 public abstract class MethodOperation {
 
+    private final Object lineNumber;
     protected final SimpleMethod simpleMethod;
+    private final String tagName;
 
     protected MethodOperation(Element element, SimpleMethod simpleMethod) {
+        this.lineNumber = element.getUserData("startLine");
         this.simpleMethod = simpleMethod;
+        this.tagName = element.getTagName().intern();
     }
 
     /** Execute the operation. Returns false if no further operations should be executed. 
@@ -45,10 +49,18 @@ public abstract class MethodOperation {
     /** Create an expanded string representation of the operation, is for the current context */
     public abstract String expandedString(MethodContext methodContext);
 
+    public String getLineNumber() {
+        return this.lineNumber == null ? "unknown" : this.lineNumber.toString();
+    }
+
     public SimpleMethod getSimpleMethod() {
         return this.simpleMethod;
     }
 
+    public String getTagName() {
+        return this.tagName;
+    }
+
     /** Create a raw string representation of the operation, would be similar to original XML */
     public abstract String rawString();