/**
* 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.eclipse;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.drools.compiler.Dialect;
import org.drools.compiler.DialectCompiletimeRegistry;
import org.drools.compiler.DroolsError;
import org.drools.lang.descr.AttributeDescr;
import org.drools.lang.descr.FunctionDescr;
import org.drools.lang.descr.PackageDescr;
import org.drools.lang.descr.RuleDescr;
import org.drools.rule.DialectRuntimeRegistry;
import org.drools.rule.LineMappings;
import org.drools.rule.Package;
public class DRLInfo {
private static final DroolsError[] EMPTY_DROOLS_ERROR_ARRAY = new DroolsError[0];
private static final List<DroolsError> EMPTY_LIST = Collections.unmodifiableList(new ArrayList<DroolsError>());
private String sourcePathName;
private PackageDescr packageDescr;
private List<DroolsError> parserErrors;
private Package compiledPackage;
private DroolsError[] builderErrors;
// cached entry
private transient RuleInfo[] ruleInfos;
private transient FunctionInfo[] functionInfos;
private DialectCompiletimeRegistry dialectRegistry;
public DRLInfo(String sourcePathName, PackageDescr packageDescr, List<DroolsError> parserErrors, DialectCompiletimeRegistry dialectRegistry) {
if (sourcePathName == null) {
throw new IllegalArgumentException("Invalid sourcePathName " + sourcePathName);
}
this.sourcePathName = sourcePathName;
this.packageDescr = packageDescr;
this.parserErrors =
parserErrors == null ? EMPTY_LIST : Collections.unmodifiableList(parserErrors);
this.builderErrors = EMPTY_DROOLS_ERROR_ARRAY;
this.dialectRegistry = dialectRegistry;
}
public DRLInfo(String pathName, PackageDescr packageDescr, List<DroolsError> parserErrors, Package compiledPackage, DroolsError[] builderErrors, DialectCompiletimeRegistry dialectRegistry) {
this(pathName, packageDescr, parserErrors, dialectRegistry);
if (compiledPackage == null) {
throw new IllegalArgumentException("Null package");
}
this.compiledPackage = compiledPackage;
this.builderErrors =
builderErrors == null ? EMPTY_DROOLS_ERROR_ARRAY : builderErrors;
}
public String getSourcePathName() {
return sourcePathName;
}
public PackageDescr getPackageDescr() {
return packageDescr;
}
public List<DroolsError> getParserErrors() {
return parserErrors;
}
public Package getPackage() {
return compiledPackage;
}
public DroolsError[] getBuilderErrors() {
return builderErrors;
}
public String getPackageName() {
return packageDescr == null ? null : packageDescr.getName();
}
public boolean isCompiled() {
return compiledPackage != null;
}
public RuleInfo[] getRuleInfos() {
if (ruleInfos == null) {
List<RuleInfo> ruleInfosList = new ArrayList<RuleInfo>();
if (packageDescr != null) {
for (RuleDescr ruleDescr: packageDescr.getRules()) {
RuleInfo ruleInfo = new RuleInfo(ruleDescr);
ruleInfosList.add(ruleInfo);
}
}
ruleInfos = (RuleInfo[]) ruleInfosList.toArray(new RuleInfo[0]);
}
return ruleInfos;
}
public RuleInfo getRuleInfo(int drlLineNumber) {
RuleInfo[] ruleInfos = getRuleInfos();
int ruleLine = -1;
RuleInfo result = null;
for (int i = 0; i < ruleInfos.length; i++) {
int ruleDrlLineNumber = ruleInfos[i].getDrlLineNumber();
if (ruleDrlLineNumber > ruleLine
&& ruleDrlLineNumber <= drlLineNumber + 1) {
ruleLine = ruleDrlLineNumber;
result = ruleInfos[i];
}
}
return result;
}
public DialectCompiletimeRegistry getDialectRegistry() {
return dialectRegistry;
}
public class RuleInfo {
private final RuleDescr ruleDescr;
// cached entries
private transient String className;
private transient int consequenceJavaLineNumber = -1;
public RuleInfo(RuleDescr ruleDescr) {
if (ruleDescr == null) {
throw new IllegalArgumentException("Null ruleDescr");
}
this.ruleDescr = ruleDescr;
}
public String getDialectName() {
String dialectName = null;
dialectName = ruleDescr.getAttributes().get("dialect").getValue();
if (dialectName == null && packageDescr != null) {
for (AttributeDescr attribute: DRLInfo.this.packageDescr.getAttributes()) {
if ("dialect".equals(attribute.getName())) {
dialectName = (String) attribute.getValue();
break;
}
}
}
return dialectName;
}
public Dialect getDialect() {
String dialectName = getDialectName();
if (dialectName == null) {
return null;
}
return DRLInfo.this.dialectRegistry.getDialect(dialectName);
}
public String getSourcePathName() {
return DRLInfo.this.getSourcePathName();
}
public String getClassName() {
// ruleDescr is only filled in during compilation
if (!isCompiled()) {
throw new IllegalArgumentException("Package has not been compiled");
}
if (className == null) {
String packageName = getPackageName();
className = (packageName == null ? "" : packageName + ".") + ruleDescr.getClassName();
}
return className;
}
public int getDrlLineNumber() {
return ruleDescr.getLine();
}
public int getConsequenceDrlLineNumber() {
return ruleDescr.getConsequenceLine();
}
public int getConsequenceJavaLineNumber() {
if (consequenceJavaLineNumber == -1) {
if (!isCompiled()) {
throw new IllegalArgumentException("Package has not been compiled");
}
DialectRuntimeRegistry datas = compiledPackage.getDialectRuntimeRegistry();
LineMappings mappings = datas.getLineMappings(className);
consequenceJavaLineNumber = mappings.getOffset();
}
return consequenceJavaLineNumber;
}
public String getPackageName() {
return packageDescr == null ? null : packageDescr.getName();
}
public String getRuleName() {
return ruleDescr.getName();
}
}
public FunctionInfo[] getFunctionInfos() {
if (functionInfos == null) {
List<FunctionInfo> functionInfosList = new ArrayList<FunctionInfo>();
if (packageDescr != null) {
for (FunctionDescr functionDescr: packageDescr.getFunctions()) {
FunctionInfo functionInfo = new FunctionInfo(functionDescr);
functionInfosList.add(functionInfo);
}
}
functionInfos = (FunctionInfo[]) functionInfosList.toArray(new FunctionInfo[0]);
}
return functionInfos;
}
public FunctionInfo getFunctionInfo(int drlLineNumber) {
FunctionInfo[] functionInfos = getFunctionInfos();
int functionLine = -1;
FunctionInfo result = null;
for (int i = 0; i < functionInfos.length; i++) {
int functionDrlLineNumber = functionInfos[i].getDrlLineNumber();
if (functionDrlLineNumber > functionLine
&& functionDrlLineNumber <= drlLineNumber + 1) {
functionLine = functionDrlLineNumber;
result = functionInfos[i];
}
}
return result;
}
public class FunctionInfo {
private FunctionDescr functionDescr;
// cached entries
private transient String className;
private transient int javaLineNumber = -1;
public FunctionInfo(FunctionDescr functionDescr) {
if (functionDescr == null) {
throw new IllegalArgumentException("Null functionDescr");
}
this.functionDescr = functionDescr;
}
public String getSourcePathName() {
return DRLInfo.this.getSourcePathName();
}
public String getClassName() {
// functionDescr is only filled in during compilation
if (!isCompiled()) {
throw new IllegalArgumentException("Package has not been compiled");
}
if (className == null) {
className = functionDescr.getClassName();
}
return className;
}
public int getDrlLineNumber() {
return functionDescr.getLine();
}
public int getJavaLineNumber() {
if (javaLineNumber == -1) {
if (!isCompiled()) {
throw new IllegalArgumentException("Package has not been compiled");
}
javaLineNumber = compiledPackage.getDialectRuntimeRegistry().getLineMappings(className).getOffset();
}
return javaLineNumber;
}
public String getPackageName() {
return packageDescr == null ? null : packageDescr.getName();
}
public String getFunctionName() {
return functionDescr.getName();
}
}
}