⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 packagebuilder.java

📁 jboss规则引擎
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    private TypeResolver getTypeResolver() {
        if ( this.typeResolver == null ) {
            typeResolver = new ClassTypeResolver( pkg.getImports(),
                                                  pkg.getPackageCompilationData().getClassLoader() );
            // make an automatic import for the current package
            typeResolver.addImport( pkg.getName() + ".*" );
            typeResolver.addImport( "java.lang.*" );
        }
        return this.typeResolver;
    }

    /**
     * @deprecated Do not use for compiling rules. Do a whole package at a time.
     */
    public void compileRule(final RuleBuilder builder,
                            final Rule rule,
                            final RuleDescr ruleDescr) {

        addRuleSemantics( builder,
                          rule,
                          ruleDescr );
        this.compileAll();
    }

    /**
     * This will setup the semantic components of the rule for compiling later on.
     * It will not actually call the compiler
     */
    private void addRuleSemantics(final RuleBuilder builder,
                                  final Rule rule,
                                  final RuleDescr ruleDescr) {
        // The compilation result is for th entire rule, so difficult to associate with any descr
        addClassCompileTask( this.pkg.getName() + "." + ruleDescr.getClassName(),
                             builder.getRuleClass(),
                             this.src,
                             new RuleErrorHandler( ruleDescr,
                                                   rule,
                                                   "Rule Compilation error" ) );

        for ( final Iterator it = builder.getInvokers().keySet().iterator(); it.hasNext(); ) {
            final String className = (String) it.next();

            // Check if an invoker - returnvalue, predicate, eval or consequence has been associated
            // If so we add it to the PackageCompilationData as it will get wired up on compilation
            final Object invoker = builder.getInvokerLookups().get( className );
            if ( invoker != null ) {
                this.pkg.getPackageCompilationData().putInvoker( className,
                                                                 invoker );
            }
            final String text = (String) builder.getInvokers().get( className );

            //System.out.println( className + ":\n" + text );
            final PatternDescr descr = (PatternDescr) builder.getDescrLookups().get( className );
            addClassCompileTask( className,
                                 text,
                                 this.src,
                                 new RuleInvokerErrorHandler( descr,
                                                              rule,
                                                              "Unable to generate rule invoker." ) );

        }
    }

    /**
     * @return The compiled package. The package may contain errors, which you can report on
     * by calling getErrors or printErrors. If you try to add an invalid package (or rule)
     * to a RuleBase, you will get a runtime exception.
     * 
     * Compiled packages are serializable.
     */
    public Package getPackage() {

        if ( hasErrors() ) {
            this.pkg.setError( this.printErrors() );
        }
        return this.pkg;
    }

    /**
     * This actually triggers the compiling of all the resources.
     * Errors are mapped back to the element that originally generated the semantic
     * code.
     */
    private void compileAll() {
        String[] classes = new String[this.generatedClassList.size()];
        this.generatedClassList.toArray( classes );

        final CompilationResult result = this.compiler.compile( classes,
                                                                src,
                                                                this.packageStoreWrapper,
                                                                this.pkg.getPackageCompilationData().getClassLoader() );

        //this will sort out the errors based on what class/file they happened in
        if ( result.getErrors().length > 0 ) {
            for ( int i = 0; i < result.getErrors().length; i++ ) {
                CompilationProblem err = result.getErrors()[i];
                               
                
                ErrorHandler handler = (ErrorHandler) this.errorHandlers.get( err.getFileName() );
                if (handler instanceof RuleErrorHandler) {                    
                    RuleErrorHandler rh = (RuleErrorHandler) handler;
                    
                }
                handler.addError( err );
            }

            Collection errors = this.errorHandlers.values();
            for ( Iterator iter = errors.iterator(); iter.hasNext(); ) {
                ErrorHandler handler = (ErrorHandler) iter.next();
                if (handler.isInError()) {
                    if ( !(handler instanceof RuleInvokerErrorHandler) ) {
                        this.results.add( handler.getError() );
                    } else {
                        //we don't really want to report invoker errors.
                        //mostly as they can happen when there is a syntax error in the RHS
                        //and otherwise, it is a programmatic error in drools itself.
                        System.err.println( "Warning: An error occurred compiling a semantic invoker. Errors should have been reported elsewhere.");
                    }
                }
            }
        }
    }

    /** This will return true if there were errors in the package building and compiling phase */
    public boolean hasErrors() {
        return this.results.size() > 0;
    }

    /**
     * @return A list of Error objects that resulted from building and compiling the package. 
     */
    public DroolsError[] getErrors() {
        return (DroolsError[]) this.results.toArray( new DroolsError[this.results.size()] );
    }

    /**
     * This will pretty print the errors (from getErrors())
     * into lines.
     */
    public String printErrors() {
        final StringBuffer buf = new StringBuffer();
        for ( final Iterator iter = this.results.iterator(); iter.hasNext(); ) {
            final DroolsError err = (DroolsError) iter.next();
            buf.append( err.getMessage() );
            buf.append( "\n" );
        }
        return buf.toString();
    }

    /**
     * Takes a given name and makes sure that its legal and doesn't already exist. If the file exists it increases counter appender untill it is unique.
     * 
     * @param packageName
     * @param name
     * @param ext
     * @return
     */
    private String getUniqueLegalName(final String packageName,
                                      final String name,
                                      final String ext,
                                      final ResourceReader src) {
        // replaces all non alphanumeric or $ chars with _
        String newName = "Rule_" + name.replaceAll( "[^\\w$]",
                                                    "_" );

        // make sure the class name does not exist, if it does increase the counter
        int counter = -1;
        boolean exists = true;
        while ( exists ) {

            counter++;
            final String fileName = packageName.replaceAll( "\\.",
                                                            "/" ) + newName + "_" + counter + ext;

            exists = src.isAvailable( fileName );
        }
        // we have duplicate file names so append counter
        if ( counter >= 0 ) {
            newName = newName + "_" + counter;
        }

        return newName;
    }

    private void loadCompiler() {
        switch ( configuration.getCompiler() ) {
            case PackageBuilderConfiguration.JANINO : {
                if ( !"1.4".equals( configuration.getJavaLanguageLevel() ) ) throw new RuntimeDroolsException( "Incompatible Java language level with selected compiler" );
                compiler = JavaCompilerFactory.getInstance().createCompiler( "janino" );
                break;
            }
            case PackageBuilderConfiguration.ECLIPSE :
            default : {
                EclipseJavaCompilerSettings eclipseSettings = new EclipseJavaCompilerSettings();
                eclipseSettings.getMap().put( "org.eclipse.jdt.core.compiler.codegen.targetPlatform",
                                              configuration.getJavaLanguageLevel() );
                eclipseSettings.getMap().put( "org.eclipse.jdt.core.compiler.source",
                                              configuration.getJavaLanguageLevel() );
                compiler = new EclipseJavaCompiler( eclipseSettings );
                break;
            }
        }
    }

    private String ucFirst(final String name) {
        return name.toUpperCase().charAt( 0 ) + name.substring( 1 );
    }

    public static class MissingPackageNameException extends IllegalArgumentException {
        private static final long serialVersionUID = 4056984379574366454L;

        public MissingPackageNameException(final String message) {
            super( message );
        }

    }

    /**
     * This is the super of the error handlers.
     * Each error handler knows how to report a compile error of its type, should it happen.
     * This is needed, as the compiling is done as one
     * hit at the end, and we need to be able to work out what rule/ast element
     * caused the error.
     * 
     * An error handler it created for each class task that is queued to be compiled.
     * This doesn't mean an error has occurred, it just means it *may* occur
     * in the future and we need to be able to map it back to the AST element
     * that originally spawned the code to be compiled.
     */
    public abstract static class ErrorHandler {
        private List     errors = new ArrayList();
        protected String message;
        private boolean inError = false;

        /** This needes to be checked if there is infact an error */
        public boolean isInError() {
            return inError;
        }
        
        public void addError(CompilationProblem err) {
            this.errors.add( err );
            this.inError = true;
        }

        /**
         * 
         * @return A DroolsError object populated as appropriate,
         * should the unthinkable happen and this need to be reported.
         */
        public abstract DroolsError getError();

        /**
         * We must use an error of JCI problem objects.
         * If there are no problems, null is returned.
         * These errors are placed in the DroolsError instances.
         * Its not 1 to 1 with reported errors.
         */
        protected CompilationProblem[] collectCompilerProblems() {
            if ( errors.size() == 0 ) {
                return null;
            } else {
                CompilationProblem[] list = new CompilationProblem[errors.size()];
                errors.toArray( list );
                return list;
            }
        }
    }

    public static class RuleErrorHandler extends ErrorHandler {

        private PatternDescr descr;
        private Rule         rule;

        public RuleErrorHandler(PatternDescr ruleDescr,
                                Rule rule,
                                String message) {
            this.descr = ruleDescr;
            this.rule = rule;
            this.message = message;
        }

        public DroolsError getError() {
            return new RuleError( rule,
                                  descr,
                                  collectCompilerProblems(),
                                  message );
        }

    }

    /**
     * There isn't much point in reporting invoker errors, as
     * they are no help. 
     */
    public static class RuleInvokerErrorHandler extends RuleErrorHandler {

        public RuleInvokerErrorHandler(PatternDescr ruleDescr,
                                       Rule rule,
                                       String message) {
            super( ruleDescr,
                   rule,
                   message );
        }
    }

    public static class FunctionErrorHandler extends ErrorHandler {

        private FunctionDescr descr;

        public FunctionErrorHandler(FunctionDescr functionDescr,
                                    String message) {
            this.descr = functionDescr;
            this.message = message;
        }

        public DroolsError getError() {
            return new FunctionError( descr,
                                      collectCompilerProblems(),
                                      message );
        }

    }

    private static JavaCompiler cachedJavaCompiler = null;

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -