package org.drools.template.model;
/*
* Copyright 2005 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.
*/
import java.io.UnsupportedEncodingException;
import java.util.LinkedList;
import java.util.List;
/**
* @author <a href="mailto:michael.neale@gmail.com"> Michael Neale </a>
*
* Represents a rule.
*/
public class Rule extends DRLElement
implements
DRLJavaEmitter {
private static final int MAX_ROWS = 65535;
private Integer _salience; // Integer as it may be null
private String _name;
private String _duration; // RIK: New variable to the Rule class (Defines
// a Duration tag for the rule)
private String _description; // RIK: New variable to the Rule class (Set
// the description parameter of the rule
// tag)
private String _noLoop; // RIK: New variable to the Rule class (Set the
// no-loop parameter of the rule tag)
private String _activationGroup; // RIK: New variable to the Rule class (Set the
// activation-group parameter of the rule tag)
private String _ruleFlowGroup;
private String _agendaGroup; // SJW: New variable to the Rule class (Set the
// agenda-group parameter of the rule tag
private List<Condition> _lhs;
private List<Consequence> _rhs;
private int _spreadsheetRow;
/**
* Create a new rule. Note that the rule name should be post-fixed with the row number,
* as one way of providing tracability for errors back to the originating spreadsheet.
* @param name The name of the rule. This may be used to calculate DRL row error
* to Spreadsheet row error (just need to keep track of output lines, and map spreadsheetRow to a start
* and end range in the rendered output).
* @param salience
* @param spreadsheetRow The phyical row number from the spreadsheet.
*/
public Rule(final String name,
final Integer salience,
final int spreadsheetRow) {
this._name = name;
this._salience = salience;
this._description = "";
this._lhs = new LinkedList<Condition>();
this._rhs = new LinkedList<Consequence>();
this._spreadsheetRow = spreadsheetRow;
}
public void addCondition(final Condition con) {
this._lhs.add( con );
}
public void addConsequence(final Consequence con) {
this._rhs.add( con );
}
public void renderDRL(final DRLOutput out) {
if ( isCommented() ) {
out.writeLine( "#" + getComment() );
}
out.writeLine( "rule " + "\"" + this._name + "\"" );
if ( this._description != null ) {
out.writeLine( "\t" + this._description );
}
if ( this._salience != null ) {
out.writeLine( "\tsalience " + this._salience );
}
if ( this._activationGroup != null ) {
out.writeLine( "\tactivation-group \"" + this._activationGroup + "\"" );
}
if ( this._agendaGroup != null ) {
out.writeLine( "\tagenda-group " + this._agendaGroup );
}
if ( this._noLoop != null ) {
out.writeLine( "\tno-loop " + this._noLoop );
}
if ( this._duration != null ) {
out.writeLine( "\tduration " + this._duration );
}
if ( this._ruleFlowGroup != null ) {
out.writeLine( "\truleflow-group \"" + this._ruleFlowGroup + "\"" );
}
out.writeLine( "\twhen" );
renderDRL( this._lhs,
out );
out.writeLine( "\tthen" );
renderDRL( this._rhs,
out );
out.writeLine( "end\n" );
}
private void renderDRL(final List<? extends DRLJavaEmitter> list,
final DRLOutput out) {
for ( DRLJavaEmitter item : list ) {
item.renderDRL( out );
}
}
public static int calcSalience(final int rowNumber) {
if ( rowNumber > Rule.MAX_ROWS ) {
throw new IllegalArgumentException( "That row number is above the max: " + Rule.MAX_ROWS );
}
return Rule.MAX_ROWS - rowNumber;
}
/**
* @param col -
* the column number. Start with zero.
* @return The spreadsheet name for this col number, such as "AA" or "AB" or
* "A" and such and such.
*/
public static String convertColNumToColName(final int i) {
String result;
final int div = i / 26;
final int mod = i % 26;
if ( div == 0 ) {
final byte[] c = new byte[1];
c[0] = (byte) (mod + 65);
result = byteToString( c );
} else {
final byte[] firstChar = new byte[1];
firstChar[0] = (byte) ((div - 1) + 65);
final byte[] secondChar = new byte[1];
secondChar[0] = (byte) (mod + 65);
final String first = byteToString( firstChar );
final String second = byteToString( secondChar );
result = first + second;
}
return result;
}
private static String byteToString(final byte[] secondChar) {
try {
return new String( secondChar,
"UTF-8" );
} catch ( final UnsupportedEncodingException e ) {
throw new RuntimeException( "Unable to convert char to string.",
e );
}
}
public List<Condition> getConditions() {
return this._lhs;
}
public List<Consequence> getConsequences() {
return this._rhs;
}
public void setSalience(final Integer value) // Set the salience of the rule
{
this._salience = value;
}
public Integer getSalience() {
return this._salience;
}
public void setName(final String value) // Set the name of the rule
{
this._name = value;
}
public String getName() {
return this._name;
}
public void setDescription(final String value) // Set the description of the
// rule
{
this._description = value;
}
public void appendDescription(final String value) // Set the description of the
// rule
{
this._description += value;
}
public String getDescription() {
return this._description;
}
public void setDuration(final String value) // Set the duration of the rule
{
this._duration = value;
}
public String getDuration() {
return this._duration;
}
public void setActivationGroup(final String value) // Set the duration of the rule
{
this._activationGroup = value;
}
public void setRuleFlowGroup(final String value) {
this._ruleFlowGroup = value;
}
public String getRuleFlowGroup() {
return this._ruleFlowGroup;
}
public String getActivationGroup() {
return this._activationGroup;
}
public String getAgendaGroup() {
return _agendaGroup;
}
public void setAgendaGroup(String group) // Set the agenda-group of the rule
{
_agendaGroup = group;
}
public void setNoLoop(final String value) // Set the no-loop attribute of the rule
{
this._noLoop = value;
}
/**
* @return The row in the spreadsheet this represents.
* This can be handy when mapping a line error from Parser back to the rule row.
* Will need to have a map of ranges of line numbers that each rule covers.
* Then can find out the rule that cause it, and this will give the row number to report.
*/
public int getSpreadsheetRowNumber() {
return this._spreadsheetRow;
}
}