You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by je...@apache.org on 2008/02/01 10:46:27 UTC

svn commit: r617413 - in /xmlgraphics/fop/branches/Temp_ProcessingFeedback: src/java/org/apache/fop/events/ src/java/org/apache/fop/util/ test/java/org/apache/fop/events/ test/java/org/apache/fop/util/

Author: jeremias
Date: Fri Feb  1 01:46:26 2008
New Revision: 617413

URL: http://svn.apache.org/viewvc?rev=617413&view=rev
Log:
Extracted formatting functionality into utility class AdvancedMessageFormat.java.
AdvancedMessageFormat.java now supports conditional sub-groups (delimited by []).

Added:
    xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/util/AdvancedMessageFormat.java   (with props)
    xmlgraphics/fop/branches/Temp_ProcessingFeedback/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java   (with props)
Removed:
    xmlgraphics/fop/branches/Temp_ProcessingFeedback/test/java/org/apache/fop/events/EventFormatterTestCase.java
Modified:
    xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/events/EventFormatter.java

Modified: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/events/EventFormatter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/events/EventFormatter.java?rev=617413&r1=617412&r2=617413&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/events/EventFormatter.java (original)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/events/EventFormatter.java Fri Feb  1 01:46:26 2008
@@ -19,11 +19,9 @@
 
 package org.apache.fop.events;
 
-import java.util.Map;
 import java.util.ResourceBundle;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
+import org.apache.fop.util.AdvancedMessageFormat;
 import org.apache.fop.util.XMLResourceBundle;
 
 /**
@@ -43,33 +41,9 @@
         return format(event, template);
     }
 
-    public static String format(Event event, String template) {
-        Map params = event.getParams();
-        Pattern p = Pattern.compile("\\$\\{[^\\}]+\\}");
-        Matcher m = p.matcher(template);
-        StringBuffer sb = new StringBuffer();
-        while (m.find()) {
-            String formatElement = m.group();
-            formatElement = formatElement.substring(2, formatElement.length() - 1);
-            //TODO Handle conditional sub-formats
-            //TODO Add advanced formatting like in MessageFormat here
-            String key = formatElement;
-            if (!params.containsKey(key)) {
-                throw new IllegalArgumentException(
-                        "Message template contains unsupported variable key: " + key);
-            }
-            Object obj = params.get(key);
-            String value;
-            if (obj == null) {
-                value = "";
-            } else {
-                value = obj.toString();
-            }
-            m.appendReplacement(sb, value);
-        }
-        m.appendTail(sb);
-        
-        return sb.toString();
+    public static String format(Event event, String pattern) {
+        AdvancedMessageFormat format = new AdvancedMessageFormat(pattern);
+        return format.format(event.getParams());
     }
-
+    
 }

Added: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/util/AdvancedMessageFormat.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/util/AdvancedMessageFormat.java?rev=617413&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/util/AdvancedMessageFormat.java (added)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/util/AdvancedMessageFormat.java Fri Feb  1 01:46:26 2008
@@ -0,0 +1,223 @@
+/*
+ * 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.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.util;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Formats messages based on a template and with a set of named parameters. This is similar to
+ * {@link java.util.MessageFormat} but uses named parameters and supports conditional sub-groups.
+ * <p>
+ * Example:
+ * </p>
+ * <p><code>Missing field "{fieldName}"[ at location: {location}]!</code></p>
+ */
+public class AdvancedMessageFormat {
+
+    private CompositePart rootPart;
+    
+    public AdvancedMessageFormat(CharSequence pattern) {
+        parsePattern(pattern);
+    }
+    
+    private void parsePattern(CharSequence pattern) {
+        rootPart = new CompositePart(false);
+        StringBuffer sb = new StringBuffer();
+        parseInnerPattern(pattern, rootPart, sb, 0);
+    }
+    
+    private int parseInnerPattern(CharSequence pattern, CompositePart parent, StringBuffer sb, int start) {
+        assert sb.length() == 0;
+        int i = start;
+        int len = pattern.length();
+        loop:
+        while (i < len) {
+            char ch = pattern.charAt(i);
+            switch (ch) {
+            case '{':
+                if (sb.length() > 0) {
+                    parent.addChild(new TextPart(sb.toString()));
+                    sb.setLength(0);
+                }
+                i++;
+                while (i < len) {
+                    ch = pattern.charAt(i);
+                    if (ch == '}') {
+                        i++;
+                        break;
+                    }
+                    sb.append(ch);
+                    i++;
+                }
+                parent.addChild(parseField(sb.toString()));
+                sb.setLength(0);
+                break;
+            case ']':
+                i++;
+                break loop; //Current composite is finished
+            case '[':
+                if (sb.length() > 0) {
+                    parent.addChild(new TextPart(sb.toString()));
+                    sb.setLength(0);
+                }
+                i++;
+                CompositePart composite = new CompositePart(true);
+                parent.addChild(composite);
+                i += parseInnerPattern(pattern, composite, sb, i);
+                break;
+            case '\\':
+                if (i < len - 1) {
+                    i++;
+                    ch = pattern.charAt(i);
+                }
+                //no break here! Must be right before "default" section
+            default:
+                sb.append(ch);
+                i++;
+            }
+        }
+        if (sb.length() > 0) {
+            parent.addChild(new TextPart(sb.toString()));
+            sb.setLength(0);
+        }
+        return i - start;
+    }
+    
+    private Part parseField(String field) {
+        //TODO Add advanced formatting like in MessageFormat here
+        return new SimpleFieldPart(field);
+    }
+
+    /**
+     * Formats a message with the given parameters.
+     * @param params a Map of named parameters (Contents: <String, Object>)
+     * @return the formatted message
+     */
+    public String format(Map params) {
+        StringBuffer sb = new StringBuffer();
+        rootPart.write(sb, params);
+        return sb.toString();
+    }
+
+    private interface Part {
+        void write(StringBuffer sb, Map params);
+        boolean isGenerated(Map params);
+    }
+    
+    private class TextPart implements Part {
+        
+        private String text;
+        
+        public TextPart(String text) {
+            this.text = text;
+        }
+        
+        public void write(StringBuffer sb, Map params) {
+            sb.append(text);
+        }
+        
+        public boolean isGenerated(Map params) {
+            return true;
+        }
+
+        /** {@inheritDoc} */
+        public String toString() {
+            return this.text;
+        }
+    }
+    
+    private class SimpleFieldPart implements Part {
+        
+        private String fieldName;
+        
+        public SimpleFieldPart(String fieldName) {
+            this.fieldName = fieldName;
+        }
+        
+        public void write(StringBuffer sb, Map params) {
+            if (!params.containsKey(fieldName)) {
+                throw new IllegalArgumentException(
+                        "Message pattern contains unsupported field name: " + fieldName);
+            }
+            Object obj = params.get(fieldName);
+            String value;
+            if (obj == null) {
+                value = "";
+            } else {
+                value = obj.toString();
+            }
+            sb.append(value);
+        }
+
+        public boolean isGenerated(Map params) {
+            Object obj = params.get(fieldName);
+            return obj != null;
+        }
+        
+        /** {@inheritDoc} */
+        public String toString() {
+            return "{" + this.fieldName + "}";
+        }
+    }
+    
+    private class CompositePart implements Part {
+        
+        private List parts = new java.util.ArrayList();
+        private boolean conditional;
+        
+        public CompositePart(boolean conditional) {
+            this.conditional = conditional;
+        }
+        
+        public void addChild(Part part) {
+            this.parts.add(part);
+        }
+
+        public void write(StringBuffer sb, Map params) {
+            if (isGenerated(params)) {
+                Iterator iter = this.parts.iterator();
+                while (iter.hasNext()) {
+                    Part part = (Part)iter.next();
+                    part.write(sb, params);
+                }
+            }
+        }
+
+        public boolean isGenerated(Map params) {
+            if (conditional) {
+                Iterator iter = this.parts.iterator();
+                while (iter.hasNext()) {
+                    Part part = (Part)iter.next();
+                    if (!part.isGenerated(params)) {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+        
+        /** {@inheritDoc} */
+        public String toString() {
+            return this.parts.toString();
+        }
+    }
+}

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/util/AdvancedMessageFormat.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/src/java/org/apache/fop/util/AdvancedMessageFormat.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: xmlgraphics/fop/branches/Temp_ProcessingFeedback/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ProcessingFeedback/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java?rev=617413&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ProcessingFeedback/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java (added)
+++ xmlgraphics/fop/branches/Temp_ProcessingFeedback/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java Fri Feb  1 01:46:26 2008
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.util;
+
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for EventFormatter.
+ */
+public class AdvancedMessageFormatTestCase extends TestCase {
+
+    public void testFormatting() throws Exception {
+        String msg;
+        AdvancedMessageFormat format;
+        
+        String pattern
+            = "Element \"{elementName}\" is missing[ required property \"{propertyName}\"]!";
+        format = new AdvancedMessageFormat(pattern);
+
+        Map params = new java.util.HashMap();
+        params.put("node", new Object());
+        params.put("elementName", "fo:external-graphic");
+        params.put("propertyName", "src");
+        
+        msg = format.format(params);
+        assertEquals("Element \"fo:external-graphic\" is missing required property \"src\"!", msg);
+        
+        params.remove("propertyName");
+        msg = format.format(params);
+        assertEquals("Element \"fo:external-graphic\" is missing!", msg);
+        
+        pattern
+            = "Testing \\{escaped \\[characters\\], now a normal field {elementName}!";
+        format = new AdvancedMessageFormat(pattern);
+        msg = format.format(params);
+        assertEquals("Testing {escaped [characters], now a normal field fo:external-graphic!", msg);
+    }
+    
+}

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_ProcessingFeedback/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Id



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org