[jboss-svn-commits] JBL Code SVN: r35944 - labs/jbossrules/trunk/drools-templates/src/main/java/org/drools/template/parser.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Nov 11 07:36:36 EST 2010


Author: laune
Date: 2010-11-11 07:36:36 -0500 (Thu, 11 Nov 2010)
New Revision: 35944

Modified:
   labs/jbossrules/trunk/drools-templates/src/main/java/org/drools/template/parser/DefaultTemplateContainer.java
Log:
many checks added: undeclared and duplicate parameters, missing and duplicate template names, unterminated and nested templates
bug fixes: JIRA-2786; handling of text around templates; recognition of indented keywords
add line numbers to error messages


Modified: labs/jbossrules/trunk/drools-templates/src/main/java/org/drools/template/parser/DefaultTemplateContainer.java
===================================================================
--- labs/jbossrules/trunk/drools-templates/src/main/java/org/drools/template/parser/DefaultTemplateContainer.java	2010-11-11 01:22:45 UTC (rev 35943)
+++ labs/jbossrules/trunk/drools-templates/src/main/java/org/drools/template/parser/DefaultTemplateContainer.java	2010-11-11 12:36:36 UTC (rev 35944)
@@ -15,14 +15,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.LineNumberReader;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * 
@@ -33,144 +35,197 @@
  * 
  */
 public class DefaultTemplateContainer implements TemplateContainer {
-	private String header;
+    private String header;
 
-	private Map<String, Column> columnMap = new HashMap<String, Column>();
+    private Map<String, Column> columnMap = new HashMap<String, Column>();
 
-	private List<Column> columns = new ArrayList<Column>();
+    private List<Column> columns = new ArrayList<Column>();
 
-	private Map<String, RuleTemplate> templates = new HashMap<String, RuleTemplate>();
+    private Map<String, RuleTemplate> templates = new HashMap<String, RuleTemplate>();
 
-	public DefaultTemplateContainer(final String template) {
-		this(DefaultTemplateContainer.class.getResourceAsStream(template));
-	}
+    public DefaultTemplateContainer(final String template) {
+        this(DefaultTemplateContainer.class.getResourceAsStream(template));
+    }
 
-	public DefaultTemplateContainer(final InputStream templateStream) {
-		parseTemplate(templateStream);
-		validateTemplate();
-	}
+    public DefaultTemplateContainer(final InputStream templateReader) {
+        parseTemplate(templateReader);
+        validateTemplate();
+    }
 
-	private void validateTemplate() {
-		if (columns.size() == 0) {
-			throw new DecisionTableParseException("Missing header columns");
-		}
-		if (templates.size() == 0) {
-			throw new DecisionTableParseException("Missing templates");
-		}
+    private void validateTemplate() {
+        if (columns.size() == 0) {
+            throw new DecisionTableParseException("No template parameters");
+        }
+        if (templates.size() == 0) {
+            throw new DecisionTableParseException("No templates");
+        }
+    }
 
-	}
+    Pattern parPattern = Pattern.compile( "@\\{([^}]+)\\}" );
 
-	private void parseTemplate(final InputStream templateStream) {
-		try {
-			final ColumnFactory cf = new ColumnFactory();
-			final BufferedReader templateReader = new BufferedReader(
-					new InputStreamReader(templateStream));
-			String line = null;
-			StringBuffer header = new StringBuffer();
-			boolean inTemplate = false;
-			boolean inHeader = false;
-			boolean inContents = false;
-			RuleTemplate template = null;
-			StringBuffer contents = new StringBuffer();
-			while ((line = templateReader.readLine()) != null) {
-				if (line.trim().length() > 0) {
-					if (line.startsWith("template header")) {
-						inHeader = true;
-					} else if (line.startsWith("template")) {
-						inTemplate = true;
-						String quotedName = line.substring(8).trim();
-						quotedName = quotedName.substring(1, quotedName
-								.length() - 1);
-						template = new RuleTemplate(quotedName, this);
-						addTemplate(template);
+    /**
+     * Check whether all parameters have been defined.
+     * @param line a line in a rule
+     * qparam lno the line number
+     */
+    private void checkLine( String line, int lno ){
+        Matcher parMatcher = parPattern.matcher( line );
+        while( parMatcher.find() ){
+            String par = parMatcher.group( 1 ).trim();
+            if( ! columnMap.containsKey( par ) ){
+                throw new DecisionTableParseException( "Undeclared parameter '" + par + "' in line " + lno );
+            }
+        }
+    }
 
-					} else if (line.startsWith("package")) {
-						if (inHeader == false) {
-							throw new DecisionTableParseException(
-									"Missing header");
-						}
-						inHeader = false;
-						header.append(line).append("\n");
-					} else if (inHeader) {
-						addColumn(cf.getColumn(line.trim()));
-					} else if (!inTemplate && !inHeader) {
-						header.append(line).append("\n");
-					} else if (!inContents && line.startsWith("rule")) {
-						inContents = true;
-						contents.append(line).append("\n");
-					} else if (line.equals("end template")) {
-						template.setContents(contents.toString());
-						contents.setLength(0);
-						inTemplate = false;
-						inContents = false;
-					} else if (inContents) {
-						contents.append(line).append("\n");
-					} else if (inTemplate) {
-						template.addColumn(line.trim());
-					}
-				}
+    private void parseTemplate(final InputStream givenStream) {
+        try {
+            InputStreamReader isr =  new InputStreamReader( givenStream );
+            LineNumberReader templateReader = new LineNumberReader( isr );
+            final ColumnFactory cf = new ColumnFactory();
+            String line = null;
+            StringBuilder header = new StringBuilder();
+            boolean inTemplate = false;
+            boolean inHeader = false;
+            boolean inContents = false;
+            RuleTemplate template = null;
+            StringBuilder contents = new StringBuilder();
+            String lastTemplateName = "?";
+            int    lastTemplateLine = 0;
+            while ((line = templateReader.readLine()) != null) {
+                String trimmed = line.trim();
+                if( trimmed.length() > 0 ){
+                    int lineNo = templateReader.getLineNumber();
 
-			}
-			if (inTemplate) {
-				throw new DecisionTableParseException("Missing end template");
-			}
-			this.header = header.toString();
+                    if( trimmed.matches( "template\\s+header" ) ){
+                        inHeader = true;
 
-		} catch (IOException e) {
-			throw new RuntimeException(e);
-		} finally {
-			if (templateStream != null)
-				closeStream(templateStream);
-		}
-	}
+                    } else if (trimmed.startsWith("template")) {
+                        if( inTemplate ){
+                            throw new DecisionTableParseException(
+                                    "Nested template, within '" + lastTemplateName + "'. at line " + lineNo );
+                        }
+                        inTemplate = true;
+                        String quotedName = line.substring(8).trim();						
+                        if( quotedName.startsWith( "\"" ) && quotedName.endsWith( "\"" ) ||
+                            quotedName.startsWith( "'" ) && quotedName.endsWith( "'" ) ){
+                            quotedName = quotedName.substring(1, quotedName.length() - 1);
+                        }
+                        if( quotedName.length() == 0 ){
+                            throw new DecisionTableParseException(
+                                    "Template name missing at line " + lineNo );
+                        }
+                        if( templates.containsKey( quotedName ) ){
+                            throw new DecisionTableParseException(
+                                    "Duplicate template name '" + quotedName + "' at line " + lineNo );
+                        }
+                        lastTemplateName = quotedName;
+                        lastTemplateLine = lineNo;
+                        template = new RuleTemplate( quotedName, this);
+                        addTemplate(template);
 
-	private void addTemplate(RuleTemplate template) {
-		templates.put(template.getName(), template);
-	}
+                    } else if ( trimmed.startsWith("package") ) {
+                        if ( ! inHeader ) {
+                            throw new DecisionTableParseException(
+                                    "Missing header at line " + lineNo );
+                        }
+                        inHeader = false;
+                        header.append(line).append("\n");
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.drools.decisiontable.parser.TemplateContainer#getTemplates()
-	 */
-	public Map<String, RuleTemplate> getTemplates() {
-		return templates;
-	}
+                    } else if ( inHeader ) {
+                        if( ! addColumn(cf.getColumn(trimmed)) ){
+                            throw new DecisionTableParseException( "Duplicate parameter '" +
+                                    trimmed + "' at line " + lineNo);
+                        }
 
-	private void addColumn(Column c) {
-		columns.add(c);
-		columnMap.put(c.getName(), c);
-	}
+                    } else if (!inTemplate && !inHeader) {
+                        header.append(line).append("\n");
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.drools.decisiontable.parser.TemplateContainer#getColumns()
-	 */
-	public Column[] getColumns() {
-		return (Column[]) columns.toArray(new Column[columns.size()]);
-	}
+                    } else if (!inContents && trimmed.startsWith("rule")) {
+                        if( !inTemplate ){
+                            header.append(line).append("\n");
+                        } else {
+                            inContents = true;
+                            checkLine( line, lineNo );
+                            contents.append(line).append("\n");	    					
+                        }
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.drools.decisiontable.parser.TemplateContainer#getHeader()
-	 */
-	public String getHeader() {
-		return header;
-	}
+                    } else if (trimmed.matches("end\\s+template")) {
+                        template.setContents(contents.toString());
+                        contents.setLength(0);
+                        inTemplate = false;
+                        inContents = false;
 
-	private void closeStream(final InputStream stream) {
-		try {
-			stream.close();
-		} catch (final Exception e) {
-			System.err.print("WARNING: Wasn't able to "
-					+ "correctly close stream for decision table. "
-					+ e.getMessage());
-		}
-	}
+                    } else if (inContents) {
+                        checkLine( line, lineNo );
+                        contents.append(line).append("\n");
 
-	public Column getColumn(final String name) {
-		return (Column) columnMap.get(name);
-	}
+                    } else if (inTemplate) {
+                        template.addColumn( trimmed );
+                    }
+                }
+            }
+            if (inTemplate) {
+                throw new DecisionTableParseException( "Unterminated template '" +
+                        lastTemplateName + "', started in line " + lastTemplateLine );
+            }
+            this.header = header.toString();
+
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (givenStream != null)
+                closeStream(givenStream);
+        }
+    }
+
+    private void addTemplate(RuleTemplate template) {
+        templates.put(template.getName(), template);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.drools.decisiontable.parser.TemplateContainer#getTemplates()
+     */
+    public Map<String, RuleTemplate> getTemplates() {
+        return templates;
+    }
+
+    private boolean addColumn(Column c) {
+        columns.add(c);
+        return null == columnMap.put(c.getName(), c);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.drools.decisiontable.parser.TemplateContainer#getColumns()
+     */
+    public Column[] getColumns() {
+        return (Column[]) columns.toArray(new Column[columns.size()]);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.drools.decisiontable.parser.TemplateContainer#getHeader()
+     */
+    public String getHeader() {
+        return header;
+    }
+
+    private void closeStream(final InputStream stream) {
+        try {
+            stream.close();
+        } catch (final Exception e) {
+            System.err.print("Warning: Unable to "
+                    + "close stream for decision table template. "
+                    + e.getMessage());
+        }
+    }
+
+    public Column getColumn(final String name) {
+        return (Column) columnMap.get(name);
+    }
 }



More information about the jboss-svn-commits mailing list