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

📄 abstractrulebase.java

📁 jboss规则引擎
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
     * @throws RuleIntegrationException
     *             if an error prevents complete construction of the network for
     *             the <code>Rule</code>.
     * @throws FactException
     * @throws InvalidPatternException
     */
    public void addPackage(final Package newPkg) throws PackageIntegrationException {
        newPkg.checkValidity();
        final Package pkg = (Package) this.pkgs.get( newPkg.getName() );

        // Iterate each workingMemory and lock it
        // This is so we don't update the Rete network during propagation
        for ( final Iterator it = this.workingMemories.keySet().iterator(); it.hasNext(); ) {
            final AbstractWorkingMemory workingMemory = (AbstractWorkingMemory) it.next();
            workingMemory.getLock().lock();
        }

        if ( pkg != null ) {
            mergePackage( pkg,
                          newPkg );
        } else {
            this.pkgs.put( newPkg.getName(),
                           newPkg );
        }

        final Map newGlobals = newPkg.getGlobals();

        // Check that the global data is valid, we cannot change the type
        // of an already declared global variable
        for ( final Iterator it = newGlobals.keySet().iterator(); it.hasNext(); ) {
            final String identifier = (String) it.next();
            final Class type = (Class) newGlobals.get( identifier );
            if ( this.globals.containsKey( identifier ) && !this.globals.get( identifier ).equals( type ) ) {
                throw new PackageIntegrationException( pkg );
            }
        }
        this.globals.putAll( newGlobals );

        final Rule[] rules = newPkg.getRules();

        for ( int i = 0; i < rules.length; ++i ) {
            addRule( rules[i] );
        }

        this.packageClassLoader.addClassLoader( newPkg.getPackageCompilationData().getClassLoader() );

        // Iterate each workingMemory and attempt to fire any rules, that were activated as a result 
        // of the new rule addition. Unlock after fireAllRules();
        for ( final Iterator it = this.workingMemories.keySet().iterator(); it.hasNext(); ) {
            final AbstractWorkingMemory workingMemory = (AbstractWorkingMemory) it.next();

            workingMemory.fireAllRules();
            workingMemory.getLock().unlock();
        }
    }

    /**
     * Merge a new package with an existing package.
     * Most of the work is done by the concrete implementations, 
     * but this class does some work (including combining imports, compilation data, globals,
     * and the actual Rule objects into the package).
     */
    private void mergePackage(final Package pkg,
                              final Package newPkg) throws PackageIntegrationException {
        final Map globals = pkg.getGlobals();
        final List imports = pkg.getImports();
        

        // First update the binary files
        // @todo: this probably has issues if you add classes in the incorrect order - functions, rules, invokers.
        final PackageCompilationData compilationData = pkg.getPackageCompilationData();
        final PackageCompilationData newCompilationData = newPkg.getPackageCompilationData();
        final String[] files = newCompilationData.list();
        for ( int i = 0, length = files.length; i < length; i++ ) {
            compilationData.write( files[i],
                                   newCompilationData.read( files[i] ) );
        }

        // Merge imports
        imports.addAll( newPkg.getImports() );

        // Add invokers
        compilationData.putAllInvokers( newCompilationData.getInvokers() );

        // Add globals
        for ( final Iterator it = newPkg.getGlobals().keySet().iterator(); it.hasNext(); ) {
            final String identifier = (String) it.next();
            final Class type = (Class) globals.get( identifier );
            if ( globals.containsKey( identifier ) && !globals.get( identifier ).equals( type ) ) {
                throw new PackageIntegrationException( "Unable to merge new Package",
                                                       newPkg );
            }
        }
        globals.putAll( newPkg.getGlobals() );
        
        //Add rules into the RuleBase package
        //as this is needed for individual rule removal later on
        Rule[] newRules = newPkg.getRules();
        for ( int i = 0; i < newRules.length; i++ ) {
            Rule newRule = newRules[i];
            if (pkg.getRule( newRule.getName() ) == null) {
                pkg.addRule( newRule );
            }
        }
    }

    protected void addRule(final Rule rule) throws InvalidPatternException {
        if ( !rule.isValid() ) {
            throw new IllegalArgumentException( "The rule called " + rule.getName() + " is not valid. Check for compile errors reported." );
        }
    }

    public void removePackage(final String packageName) {
        final Package pkg = (Package) this.pkgs.get( packageName );
        // Iterate each workingMemory and lock it
        // This is so we don't update the Rete network during propagation
        for ( final Iterator it = this.workingMemories.keySet().iterator(); it.hasNext(); ) {
            final AbstractWorkingMemory workingMemory = (AbstractWorkingMemory) it.next();
            workingMemory.getLock().lock();
        }

        final Rule[] rules = pkg.getRules();

        for ( int i = 0; i < rules.length; ++i ) {
            removeRule( rules[i] );
        }

        this.packageClassLoader.removeClassLoader( pkg.getPackageCompilationData().getClassLoader() );

        pkg.clear();

        // getting the list of referenced globals 
        final Set referencedGlobals = new HashSet();
        for ( final Iterator it = this.pkgs.values().iterator(); it.hasNext(); ) {
            final org.drools.rule.Package pkgref = (org.drools.rule.Package) it.next();
            if ( pkgref != pkg ) {
                referencedGlobals.addAll( pkgref.getGlobals().keySet() );
            }
        }
        // removing globals declared inside the package that are not shared
        for ( final Iterator it = pkg.getGlobals().keySet().iterator(); it.hasNext(); ) {
            final String globalName = (String) it.next();
            if ( !referencedGlobals.contains( globalName ) ) {
                this.globals.remove( globalName );
            }
        }
        // removing the package itself from the list
        this.pkgs.remove( pkg.getName() );

        // Iterate and unlock
        for ( final Iterator it = this.workingMemories.keySet().iterator(); it.hasNext(); ) {
            final AbstractWorkingMemory workingMemory = (AbstractWorkingMemory) it.next();
            workingMemory.getLock().unlock();
        }
    }

    public void removeRule(final String packageName,
                           final String ruleName) {
        final Package pkg = (Package) this.pkgs.get( packageName );
        final Rule rule = pkg.getRule( ruleName );
        // Iterate each workingMemory and lock it
        // This is so we don't update the Rete network during propagation
        for ( final Iterator it = this.workingMemories.keySet().iterator(); it.hasNext(); ) {
            final AbstractWorkingMemory workingMemory = (AbstractWorkingMemory) it.next();
            workingMemory.getLock().lock();
        }
        removeRule( rule );
        pkg.removeRule( rule );

        // Iterate and unlock
        for ( final Iterator it = this.workingMemories.keySet().iterator(); it.hasNext(); ) {
            final AbstractWorkingMemory workingMemory = (AbstractWorkingMemory) it.next();
            workingMemory.getLock().unlock();
        }
    }

    protected abstract void removeRule(Rule rule);

    protected void addWorkingMemory(final WorkingMemory workingMemory,
                                    final boolean keepReference) {
        if ( keepReference ) {
            this.workingMemories.put( workingMemory,
                                      AbstractRuleBase.PRESENT );
        }
    }

    public Set getWorkingMemories() {
        return this.workingMemories.keySet();
    }

    public RuleBaseConfiguration getConfiguration() {
        return this.config;
    }
    
    public WorkingMemory newWorkingMemory(InputStream stream) throws IOException, ClassNotFoundException {
        return newWorkingMemory( stream,
                                 true );
    }    
    public WorkingMemory newWorkingMemory(InputStream stream, 
                                          boolean keepReference ) throws IOException, ClassNotFoundException {
        
        final ObjectInputStreamWithLoader streamWithLoader = new ObjectInputStreamWithLoader( stream,
                                                                                              this.packageClassLoader );
        
        AbstractWorkingMemory workingMemory = ( AbstractWorkingMemory ) streamWithLoader.readObject();
        workingMemory.setRuleBase( this );
        
        return workingMemory;
    
    }
}

⌨️ 快捷键说明

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