/**
* Copyright 2010 JBoss Inc
*
* Licensed 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.drools.verifier.misc;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class DrlRuleParser {
private static final String rulesExpr = "(^\\s*#.*?\\n)?(^\\s*rule.*?$)(.*?)(when)(.*?)(then)(.*?)(^\\s*end)";
private static final Pattern finder = Pattern.compile( rulesExpr,
Pattern.DOTALL | Pattern.MULTILINE );
private final Collection<String> header;
private final Collection<String> lhs;
private final Collection<String> rhs;
private final String name;
private final String description;
private final Collection<String> metadata;
private final Map<String, List<String>> otherInformation;
private DrlRuleParser(String ruleName,
String header,
String lhs,
String rhs,
String description,
List<String> metadata,
Map<String, List<String>> otherInformation) {
this.name = ruleName;
this.header = asList( header.split( "\n" ) );
this.lhs = asList( lhs.split( "\n" ) );
this.rhs = asList( rhs.split( "\n" ) );
this.description = description;
this.metadata = metadata;
this.otherInformation = otherInformation;
}
private Collection<String> asList(String[] array) {
Collection<String> list = new ArrayList<String>();
for ( int i = 0; i < array.length; i++ ) {
String string = array[i];
if ( !string.trim().equals( "" ) ) {
list.add( string );
}
}
return list;
}
public static List<DrlRuleParser> findRulesDataFromDrl(String drl) {
final Matcher m = finder.matcher( drl );
final List<DrlRuleParser> list = new ArrayList<DrlRuleParser>();
while ( m.find() ) {
// System.out.println( "1 " + m.group( 1 ) );
// System.out.println( "2 " + m.group( 2 ) );
// System.out.println( "3 " + m.group( 3 ) );
// System.out.println( "4 " + m.group( 4 ) );
// System.out.println( "5 " + m.group( 5 ) );
// System.out.println( "6 " + m.group( 6 ) );
// System.out.println( "7 " + m.group( 7 ) );
Comment comment = processComment( m.group( 1 ) );
String ruleName = m.group( 2 );
ruleName = trimRuleName( ruleName );
list.add( new DrlRuleParser( ruleName,
m.group( 3 ),
m.group( 5 ),
m.group( 7 ),
comment.description,
comment.metadata,
new HashMap<String, List<String>>() ) );
}
return list;
}
private static String trimRuleName(String ruleName) {
ruleName = ruleName.substring( ruleName.indexOf( "rule" ) + "rule".length() ).trim();
if ( ruleName.indexOf( "\"" ) == 0 ) {
ruleName = ruleName.substring( 1 );
}
if ( ruleName.lastIndexOf( "\"" ) == (ruleName.length() - 1) ) {
ruleName = ruleName.substring( 0,
ruleName.length() - 1 );
}
return ruleName;
}
static Comment processComment(String text) {
Comment comment = new Comment();
if ( text == null ) {
comment.description = "";
comment.metadata = new ArrayList<String>();
return comment;
}
// Sometimes the first rule in a file gets the package imports and
// comments included.
// Checking for that and fixing the description if this did happen.
StringBuilder description = new StringBuilder();
String[] commentLines = text.split( "\n" );
for ( int i = 0; i < commentLines.length; i++ ) {
String line = commentLines[i].trim();
if ( line.startsWith( "#" ) ) {
while ( line.startsWith( "#" ) ) {
line = line.substring( 1 );
}
line = line.trim();
if ( !line.startsWith( "@" ) ) {
description.append( line );
description.append( "\n" );
}
} else {
description.delete( 0,
description.length() );
}
}
comment.description = description.toString();
comment.metadata = findMetaData( text );
return comment;
}
private static List<String> findMetaData(String text) {
List<String> list = new ArrayList<String>();
while ( text.contains( "@" ) ) {
int start = text.indexOf( '@' );
text = text.substring( start + 1 );
int end = text.indexOf( "\n" );
list.add( text.substring( 0,
end ) );
text = text.substring( end );
}
return list;
}
public Collection<String> getHeader() {
return header;
}
public Collection<String> getLhs() {
return lhs;
}
public Collection<String> getRhs() {
return rhs;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public Collection<String> getMetadata() {
return metadata;
}
public Map<String, List<String>> getOtherInformation() {
return otherInformation;
}
}
class Comment {
String description;
List<String> metadata;
}