/** * 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(); } } }