Package org.drools.guvnor.server

Source Code of org.drools.guvnor.server.RepositoryPackageService

/*
* Copyright 2011 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.guvnor.server;

import com.google.gwt.user.client.rpc.SerializationException;
import org.apache.commons.io.IOUtils;
import org.drools.*;
import org.drools.base.ClassTypeResolver;
import org.drools.common.AbstractRuleBase;
import org.drools.common.InternalRuleBase;
import org.drools.common.InternalWorkingMemory;
import org.drools.compiler.DrlParser;
import org.drools.compiler.DroolsParserException;
import org.drools.core.util.DroolsStreamUtils;
import org.drools.guvnor.client.common.AssetFormats;
import org.drools.guvnor.client.rpc.*;
import org.drools.guvnor.server.builder.AuditLogReporter;
import org.drools.guvnor.server.builder.ClassLoaderBuilder;
import org.drools.guvnor.server.cache.RuleBaseCache;
import org.drools.guvnor.server.contenthandler.ModelContentHandler;
import org.drools.guvnor.server.util.LoggingHelper;
import org.drools.ide.common.client.modeldriven.testing.Scenario;
import org.drools.lang.descr.PackageDescr;
import org.drools.lang.descr.TypeDeclarationDescr;
import org.drools.repository.*;
import org.drools.rule.Package;
import org.drools.runtime.rule.ConsequenceException;
import org.drools.testframework.RuleCoverageListener;
import org.drools.testframework.ScenarioRunner;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.remoting.WebRemote;
import org.jboss.seam.annotations.security.Restrict;

import java.io.IOException;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;

@Name("org.drools.guvnor.client.rpc.PackageService")
@AutoCreate
public class RepositoryPackageService
        implements
        PackageService {
    @In
    private RulesRepository repository;

    private static final long serialVersionUID = 901123;

    private static final LoggingHelper log = LoggingHelper.getLogger( RepositoryAssetService.class );

    private final ServiceSecurity serviceSecurity = new ServiceSecurity();

    private final RepositoryPackageOperations repositoryPackageOperations = new RepositoryPackageOperations();
    private final RepositoryAssetOperations repositoryAssetOperations = new RepositoryAssetOperations();

    @Create
    public void create() {
        repositoryPackageOperations.setRulesRepository( getRulesRepository() );
        repositoryAssetOperations.setRulesRepository( getRulesRepository() );
    }

    /* This is called in hosted mode when creating "by hand" */
    public void setRulesRepository(RulesRepository repository) {
        this.repository = repository;
        create();
    }

    public RulesRepository getRulesRepository() {
        return repository;
    }

    /**
     * Role-based Authorization check: This method only returns packages that
     * the user has permission to access. User has permission to access the
     * particular package when: The user has a package.readonly role or higher
     * (i.e., package.admin, package.developer) to this package.
     */
    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public PackageConfigData[] listPackages() {
        return listPackages( null );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public PackageConfigData[] listPackages(String workspace) {
        RepositoryFilter pf = new PackageFilter();
        return repositoryPackageOperations.listPackages(
                false,
                workspace,
                pf );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public PackageConfigData[] listArchivedPackages() {
        return listArchivedPackages( null );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public PackageConfigData[] listArchivedPackages(String workspace) {
        return repositoryPackageOperations.listPackages(
                true,
                workspace,
                new PackageFilter() );
    }

    public PackageConfigData loadGlobalPackage() {
        return repositoryPackageOperations.loadGlobalPackage();
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public void rebuildPackages() throws SerializationException {
        Iterator<PackageItem> pkit = getRulesRepository().listPackages();
        StringBuilder errs = new StringBuilder();
        while (pkit.hasNext()) {
            PackageItem pkg = pkit.next();
            try {
                BuilderResult builderResult = this.buildPackage( pkg.getUUID(),
                        true );
                if ( builderResult != null ) {
                    errs.append( "Unable to build package name [" ).append( pkg.getName() ).append( "]\n" );
                    StringBuilder buf = createStringBuilderFrom( builderResult );
                    log.warn( buf.toString() );
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error( "An error occurred building package [" + pkg.getName() + "]\n" );
                errs.append( "An error occurred building package [" ).append( pkg.getName() ).append( "]\n" );
            }
        }
    }

    private StringBuilder createStringBuilderFrom(BuilderResult res) {
        StringBuilder buf = new StringBuilder();
        for (int i = 0; i < res.getLines().size(); i++) {
            buf.append( res.getLines().get( i ).toString() );
            buf.append( '\n' );
        }
        return buf;
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public String buildPackageSource(String packageUUID) throws SerializationException {
        serviceSecurity.checkSecurityIsPackageDeveloperWithPackageUuid( packageUUID );
        return repositoryPackageOperations.buildPackageSource( packageUUID );
    }

    @WebRemote
    public String copyPackage(String sourcePackageName,
                              String destPackageName) throws SerializationException {
        serviceSecurity.checkSecurityIsAdmin();
        return repositoryPackageOperations.copyPackage( sourcePackageName,
                destPackageName );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public void removePackage(String uuid) {
        serviceSecurity.checkSecurityIsPackageAdminWithPackageUuid( uuid );
        repositoryPackageOperations.removePackage( uuid );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public String renamePackage(String uuid,
                                String newName) {
        serviceSecurity.checkSecurityIsPackageAdminWithPackageUuid( uuid );

        return repositoryPackageOperations.renamePackage( uuid,
                newName );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public byte[] exportPackages(String packageName) {
        serviceSecurity.checkSecurityIsPackageAdminWithPackageName( packageName );
        return repositoryPackageOperations.exportPackages( packageName );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    // TODO: Not working. GUVNOR-475
    public void importPackages(byte[] byteArray,
                               boolean importAsNew) {
        repositoryPackageOperations.importPackages( byteArray,
                importAsNew );
    }

    @WebRemote
    public String createPackage(String name,
                                String description,
                                String[] workspace) throws RulesRepositoryException {
        serviceSecurity.checkSecurityIsAdmin();
        return repositoryPackageOperations.createPackage( name,
                description,
                workspace );
    }

    @WebRemote
    public String createPackage(String name,
                                String description) throws RulesRepositoryException {
        return createPackage( name,
                description,
                new String[]{} );
    }

    @WebRemote
    public String createSubPackage(String name,
                                   String description,
                                   String parentNode) throws SerializationException {
        serviceSecurity.checkSecurityIsAdmin();
        return repositoryPackageOperations.createSubPackage( name,
                description,
                parentNode );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public PackageConfigData loadPackageConfig(String uuid) {
        PackageItem packageItem = getRulesRepository().loadPackageByUUID( uuid );
        // the uuid passed in is the uuid of that deployment bundle, not the
        // package uudi.
        // we have to figure out the package name.
        serviceSecurity.checkSecurityIsPackageReadOnlyWithPackageName( packageItem.getName() );
        return repositoryPackageOperations.loadPackageConfig( packageItem );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public ValidatedResponse validatePackageConfiguration(PackageConfigData data) throws SerializationException {
        serviceSecurity.checkSecurityIsPackageDeveloperWithPackageUuid( data.getUuid() );
        return repositoryPackageOperations.validatePackageConfiguration( data );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public void savePackage(PackageConfigData data) throws SerializationException {
        serviceSecurity.checkSecurityIsPackageDeveloperWithPackageUuid( data.getUuid() );
        repositoryPackageOperations.savePackage( data );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public BuilderResult buildPackage(String packageUUID,
                                      boolean force) throws SerializationException {
        return buildPackage( packageUUID,
                force,
                null,
                null,
                null,
                false,
                null,
                null,
                false,
                null );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public BuilderResult buildPackage(String packageUUID,
                                      boolean force,
                                      String buildMode,
                                      String statusOperator,
                                      String statusDescriptionValue,
                                      boolean enableStatusSelector,
                                      String categoryOperator,
                                      String category,
                                      boolean enableCategorySelector,
                                      String customSelectorName) throws SerializationException {
        serviceSecurity.checkSecurityIsPackageDeveloperWithPackageUuid( packageUUID );
        return repositoryPackageOperations.buildPackage( packageUUID,
                force,
                buildMode,
                statusOperator,
                statusDescriptionValue,
                enableStatusSelector,
                categoryOperator,
                category,
                enableCategorySelector,
                customSelectorName );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public void createPackageSnapshot(String packageName,
                                      String snapshotName,
                                      boolean replaceExisting,
                                      String comment) {
        serviceSecurity.checkSecurityIsPackageAdminWithPackageName( packageName );
        repositoryPackageOperations.createPackageSnapshot( packageName,
                snapshotName,
                replaceExisting,
                comment );

    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public void copyOrRemoveSnapshot(String packageName,
                                     String snapshotName,
                                     boolean delete,
                                     String newSnapshotName) throws SerializationException {
        serviceSecurity.checkSecurityIsPackageAdminWithPackageName( packageName );
        repositoryPackageOperations.copyOrRemoveSnapshot( packageName,
                snapshotName,
                delete,
                newSnapshotName );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public String[] listRulesInPackage(String packageName) throws SerializationException {
        serviceSecurity.checkSecurityIsPackageReadOnlyWithPackageName( packageName );
        return repositoryPackageOperations.listRulesInPackage( packageName );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public String[] listImagesInPackage(String packageName) throws SerializationException {
        serviceSecurity.checkSecurityIsPackageReadOnlyWithPackageName( packageName );
        return repositoryPackageOperations.listImagesInPackage( packageName );
    }

    @WebRemote
    public void rebuildSnapshots() throws SerializationException {
        serviceSecurity.checkSecurityIsAdmin();

        Iterator<PackageItem> pkit = getRulesRepository().listPackages();
        while (pkit.hasNext()) {
            PackageItem pkg = pkit.next();
            String[] snaps = getRulesRepository().listPackageSnapshots( pkg.getName() );
            for (String snapName : snaps) {
                PackageItem snap = getRulesRepository().loadPackageSnapshot( pkg.getName(),
                        snapName );
                BuilderResult builderResult = this.buildPackage( snap.getUUID(),
                        true );
                if ( builderResult.hasLines() ) {
                    StringBuilder stringBuilder = createStringBuilderFrom( builderResult );
                    throw new DetailedSerializationException( "Unable to rebuild snapshot [" + snapName,
                            stringBuilder.toString() + "]" );
                }
            }
        }
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public SnapshotInfo[] listSnapshots(String packageName) {
        serviceSecurity.checkSecurityIsPackageDeveloperWithPackageName( packageName );

        String[] snaps = getRulesRepository().listPackageSnapshots( packageName );
        SnapshotInfo[] snapshotInfos = new SnapshotInfo[snaps.length];
        for (int i = 0; i < snaps.length; i++) {
            PackageItem packageItem = getRulesRepository().loadPackageSnapshot( packageName,
                    snaps[i] );
            snapshotInfos[i] = packageItemToSnapshotItem( snaps[i], packageItem );
        }
        return snapshotInfos;
    }

    @Restrict("#{identity.loggedIn}")
    public SnapshotInfo loadSnapshotInfo(String packageName, String snapshotName) {
        serviceSecurity.checkSecurityIsPackageAdminWithPackageName( packageName );

        return packageItemToSnapshotItem(
                snapshotName,
                getRulesRepository().loadPackageSnapshot(
                        packageName,
                        snapshotName ) );
    }

    private SnapshotInfo packageItemToSnapshotItem(String snapshotName, PackageItem packageItem) {
        SnapshotInfo snapshotInfo = new SnapshotInfo();
        snapshotInfo.setComment( packageItem.getCheckinComment() );
        snapshotInfo.setName( snapshotName );
        snapshotInfo.setUuid( packageItem.getUUID() );
        return snapshotInfo;
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public String[] listTypesInPackage(String packageUUID) throws SerializationException {
        serviceSecurity.checkSecurityPackageReadOnlyWithPackageUuid( packageUUID );

        PackageItem pkg = this.getRulesRepository().loadPackageByUUID( packageUUID );
        List<String> res = new ArrayList<String>();
        AssetItemIterator it = pkg.listAssetsByFormat( AssetFormats.MODEL,
                AssetFormats.DRL_MODEL );

        JarInputStream jis = null;

        try {
            while (it.hasNext()) {
                AssetItem asset = (AssetItem) it.next();
                if ( !asset.isArchived() ) {
                    if ( asset.getFormat().equals( AssetFormats.MODEL ) ) {
                        jis = typesForModel( res,
                                asset );
                    } else {
                        typesForOthers( res,
                                asset );
                    }

                }
            }
            return res.toArray( new String[res.size()] );
        } catch (IOException e) {
            log.error( "Unable to read the jar files in the package: " + e.getMessage() );
            throw new DetailedSerializationException( "Unable to read the jar files in the package.",
                    e.getMessage() );
        } finally {
            IOUtils.closeQuietly( jis );
        }

    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public void updateDependency(String uuid,
                                 String dependencyPath) {
        PackageItem item = getRulesRepository().loadPackageByUUID( uuid );
        item.updateDependency( dependencyPath );
        item.checkin( "Update dependency" );
    }

    public String[] getDependencies(String uuid) {
        PackageItem item = getRulesRepository().loadPackageByUUID( uuid );
        return item.getDependencies();
    }

    private JarInputStream typesForModel(List<String> res,
                                         AssetItem asset) throws IOException {
        JarInputStream jis;
        jis = new JarInputStream( asset.getBinaryContentAttachment() );
        JarEntry entry = null;
        while ((entry = jis.getNextJarEntry()) != null) {
            if ( !entry.isDirectory() ) {
                if ( entry.getName().endsWith( ".class" ) ) {
                    res.add( ModelContentHandler.convertPathToName( entry.getName() ) );
                }
            }
        }
        return jis;
    }

    private void typesForOthers(List<String> res,
                                AssetItem asset) {
        // its delcared model
        DrlParser parser = new DrlParser();
        try {
            PackageDescr desc = parser.parse( asset.getContent() );
            List<TypeDeclarationDescr> types = desc.getTypeDeclarations();
            for (TypeDeclarationDescr typeDeclarationDescr : types) {
                res.add( typeDeclarationDescr.getTypeName() );
            }
        } catch (DroolsParserException e) {
            log.error( "An error occurred parsing rule: " + e.getMessage() );

        }
    }

    @Restrict("#{identity.loggedIn}")
    public void installSampleRepository() throws SerializationException {
        getRulesRepository().importRepository( this.getClass().getResourceAsStream( "/mortgage-sample-repository.xml" ) );
        this.rebuildPackages();
        this.rebuildSnapshots();
    }

    /**
     * @deprecated in favour of {@link #compareSnapshots(SnapshotComparisonPageRequest)}
     */
    public SnapshotDiffs compareSnapshots(String packageName,
                                          String firstSnapshotName,
                                          String secondSnapshotName) {
        return repositoryPackageOperations.compareSnapshots( packageName,
                firstSnapshotName,
                secondSnapshotName );
    }

    public SnapshotComparisonPageResponse compareSnapshots(SnapshotComparisonPageRequest request) {
        if ( request == null ) {
            throw new IllegalArgumentException( "request cannot be null" );
        }
        if ( request.getPageSize() != null && request.getPageSize() < 0 ) {
            throw new IllegalArgumentException( "pageSize cannot be less than zero." );
        }

        return repositoryPackageOperations.compareSnapshots( request );
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public SingleScenarioResult runScenario(String packageName,
                                            Scenario scenario) throws SerializationException {
        serviceSecurity.checkSecurityIsPackageDeveloperWithPackageName( packageName );

        return runScenario( packageName,
                scenario,
                null );

    }

    private SingleScenarioResult runScenario(String packageName,
                                             Scenario scenario,
                                             RuleCoverageListener coverage) throws SerializationException {
        PackageItem item = this.getRulesRepository().loadPackage( packageName );
        SingleScenarioResult result = null;
        // nasty classloader needed to make sure we use the same tree the whole
        // time.
        ClassLoader originalCL = Thread.currentThread().getContextClassLoader();
        try {
            final RuleBase rb = loadCacheRuleBase( item );

            ClassLoader cl = ((InternalRuleBase) RuleBaseCache.getInstance().get( item.getUUID() )).getRootClassLoader();
            Thread.currentThread().setContextClassLoader( cl );
            result = runScenario( scenario,
                    item,
                    cl,
                    rb,
                    coverage );
        } catch (Exception e) {
            if ( e instanceof DetailedSerializationException ) {
                DetailedSerializationException err = (DetailedSerializationException) e;
                result = new SingleScenarioResult();
                if ( err.getErrs() != null ) {
                    result.result = new ScenarioRunResult( err.getErrs(),
                            null );
                } else {
                    throw err;
                }
            } else {
                throw new DetailedSerializationException( "Unable to run the scenario.",
                        e.getMessage() );
            }
        } finally {
            Thread.currentThread().setContextClassLoader( originalCL );
        }
        return result;
    }

    /*
     * Set the Rule base in a cache
     */
    private RuleBase loadCacheRuleBase(PackageItem packageItem) throws DetailedSerializationException {
        RuleBase rb = null;
        if ( packageItem.isBinaryUpToDate() && RuleBaseCache.getInstance().contains( packageItem.getUUID() ) ) {
            rb = RuleBaseCache.getInstance().get( packageItem.getUUID() );
        } else {
            // load up the classloader we are going to use
            ClassLoaderBuilder classLoaderBuilder = new ClassLoaderBuilder( packageItem.listAssetsWithVersionsSpecifiedByDependenciesByFormat( AssetFormats.MODEL ) );
            ClassLoader buildCl = classLoaderBuilder.buildClassLoader();

            // we have to build the package, and try again.
            if ( packageItem.isBinaryUpToDate() ) {
                rb = loadRuleBase( packageItem,
                        buildCl );
                RuleBaseCache.getInstance().put( packageItem.getUUID(),
                        rb );
            } else {
                BuilderResult result = repositoryPackageOperations.buildPackage( packageItem,
                        false );
                if ( result == null || result.getLines().size() == 0 ) {
                    rb = loadRuleBase( packageItem,
                            buildCl );
                    RuleBaseCache.getInstance().put( packageItem.getUUID(),
                            rb );
                } else throw new DetailedSerializationException( "Build error",
                        result.getLines() );
            }

        }
        return rb;
    }

    private RuleBase loadRuleBase(PackageItem item,
                                  ClassLoader cl) throws DetailedSerializationException {
        try {
            return deserKnowledgebase( item,
                    cl );
        } catch (ClassNotFoundException e) {
            log.error( "Unable to load rule base.",
                    e );
            throw new DetailedSerializationException( "A required class was not found.",
                    e.getMessage() );
        } catch (Exception e) {
            log.error( "Unable to load rule base.",
                    e );
            log.info( "...but trying to rebuild binaries..." );
            try {
                BuilderResult res = repositoryPackageOperations.buildPackage( item,
                        true );
                if ( res != null && res.getLines().size() > 0 ) {
                    log.error( "There were errors when rebuilding the knowledgebase." );
                    throw new DetailedSerializationException( "There were errors when rebuilding the knowledgebase.",
                            "" );
                }
            } catch (Exception e1) {
                log.error( "Unable to rebuild the rulebase: " + e.getMessage() );
                throw new DetailedSerializationException( "Unable to rebuild the rulebase.",
                        e.getMessage() );
            }
            try {
                return deserKnowledgebase( item,
                        cl );
            } catch (Exception e2) {
                log.error( "Unable to reload knowledgebase: " + e.getMessage() );
                throw new DetailedSerializationException( "Unable to reload knowledgebase.",
                        e.getMessage() );
            }

        }
    }

    private RuleBase deserKnowledgebase(PackageItem item,
                                        ClassLoader classloader) throws IOException,
            ClassNotFoundException {
        RuleBase rulebase = RuleBaseFactory.newRuleBase( new RuleBaseConfiguration( classloader ) );
        Package bin = (Package) DroolsStreamUtils.streamIn( item.getCompiledPackageBytes(),
                classloader );
        rulebase.addPackage( bin );
        return rulebase;
    }

    private SingleScenarioResult runScenario(Scenario scenario,
                                             PackageItem item,
                                             ClassLoader cl,
                                             RuleBase rulebase,
                                             RuleCoverageListener coverage) throws DetailedSerializationException {

        Package bin = rulebase.getPackages()[0];

        Set<String> imps = bin.getImports().keySet();
        Set<String> allImps = new HashSet<String>( imps );

        if ( bin.getGlobals() != null ) {
            for (Object o : bin.getGlobals().keySet()) {
                allImps.add( bin.getGlobals().get( o ) );
            }
        }
        allImps.add( bin.getName() + ".*" ); // need this for Generated beans to
        // work

        ClassTypeResolver classTypeResolver = new ClassTypeResolver( allImps,
                cl );
        SessionConfiguration sessionConfiguration = new SessionConfiguration();
        sessionConfiguration.setClockType( ClockType.PSEUDO_CLOCK );
        sessionConfiguration.setKeepReference( false );
        InternalWorkingMemory workingMemory = (InternalWorkingMemory) rulebase.newStatefulSession( sessionConfiguration,
                null );
        if ( coverage != null ) workingMemory.addEventListener( coverage );
        try {
            AuditLogReporter logger = new AuditLogReporter( workingMemory );
            new ScenarioRunner( scenario,
                    classTypeResolver,
                    workingMemory );
            SingleScenarioResult singleScenarioresult = new SingleScenarioResult();
            singleScenarioresult.auditLog = logger.buildReport();
            singleScenarioresult.result = new ScenarioRunResult( null,
                    scenario );
            return singleScenarioresult;
        } catch (ClassNotFoundException e) {
            log.error( "Unable to load a required class.",
                    e );
            throw new DetailedSerializationException( "Unable to load a required class.",
                    e.getMessage() );
        } catch (ConsequenceException e) {
            String messageShort = "There was an error executing the consequence of rule [" + e.getRule().getName() + "]";
            String messageLong = e.getMessage();
            if ( e.getCause() != null ) {
                messageLong += "\nCAUSED BY " + e.getCause().getMessage();
            }

            log.error( messageShort + ": " + messageLong,
                    e );
            throw new DetailedSerializationException( messageShort,
                    messageLong );
        } catch (Exception e) {
            log.error( "Unable to run the scenario.",
                    e );
            throw new DetailedSerializationException( "Unable to run the scenario.",
                    e.getMessage() );
        }
    }

    @WebRemote
    @Restrict("#{identity.loggedIn}")
    public BulkTestRunResult runScenariosInPackage(String packageUUID) throws SerializationException {
        serviceSecurity.checkSecurityIsPackageDeveloperWithPackageUuid( packageUUID );
        PackageItem item = getRulesRepository().loadPackageByUUID( packageUUID );
        return runScenariosInPackage( item );
    }

    public BulkTestRunResult runScenariosInPackage(PackageItem packageItem) throws DetailedSerializationException,
            SerializationException {
        ClassLoader originalClassloader = Thread.currentThread().getContextClassLoader();
        ClassLoader classloader = null;

        try {
            if ( packageItem.isBinaryUpToDate() && RuleBaseCache.getInstance().contains( packageItem.getUUID() ) ) {

                AbstractRuleBase arb = (AbstractRuleBase) RuleBaseCache.getInstance().get( packageItem.getUUID() );
                // load up the existing class loader from before
                classloader = arb.getConfiguration().getClassLoader();
                Thread.currentThread().setContextClassLoader( classloader );
            } else {
                // load up the classloader we are going to use
                ClassLoaderBuilder classLoaderBuilder = new ClassLoaderBuilder( packageItem.listAssetsWithVersionsSpecifiedByDependenciesByFormat( AssetFormats.MODEL ) );
                classloader = classLoaderBuilder.buildClassLoader();
                Thread.currentThread().setContextClassLoader( classloader );

                // we have to build the package, and try again.
                if ( packageItem.isBinaryUpToDate() ) {
                    RuleBaseCache.getInstance().put( packageItem.getUUID(),
                            loadRuleBase( packageItem,
                                    classloader ) );
                } else {
                    BuilderResult result = repositoryPackageOperations.buildPackage( packageItem,
                            false );
                    if ( result == null || result.getLines().size() == 0 ) {
                        RuleBaseCache.getInstance().put( packageItem.getUUID(),
                                loadRuleBase( packageItem,
                                        classloader ) );
                    } else {
                        return new BulkTestRunResult( result,
                                null,
                                0,
                                null );
                    }
                }
            }

            AssetItemIterator it = packageItem.listAssetsByFormat( AssetFormats.TEST_SCENARIO );
            List<ScenarioResultSummary> resultSummaries = new ArrayList<ScenarioResultSummary>();
            RuleBase rb = RuleBaseCache.getInstance().get( packageItem.getUUID() );
            Package bin = rb.getPackages()[0];

            RuleCoverageListener coverage = new RuleCoverageListener( expectedRules( bin ) );

            while (it.hasNext()) {
                AssetItem as = it.next();
                if ( !as.getDisabled() ) {
                    RuleAsset asset = repositoryAssetOperations.loadAsset( as );
                    Scenario sc = (Scenario) asset.getContent();
                    runScenario( packageItem.getName(),
                            sc,
                            coverage );// runScenario(sc, res,
                    // workingMemory).scenario;

                    int[] totals = sc.countFailuresTotal();
                    resultSummaries.add( new ScenarioResultSummary( totals[0],
                            totals[1],
                            asset.getName(),
                            asset.getDescription(),
                            asset.getUuid() ) );
                }
            }

            ScenarioResultSummary[] summaries = resultSummaries.toArray( new ScenarioResultSummary[resultSummaries.size()] );

            return new BulkTestRunResult( null,
                    resultSummaries.toArray( summaries ),
                    coverage.getPercentCovered(),
                    coverage.getUnfiredRules() );

        } finally {
            Thread.currentThread().setContextClassLoader( originalClassloader );
        }

    }

    private HashSet<String> expectedRules(Package bin) {
        HashSet<String> h = new HashSet<String>();
        for (int i = 0; i < bin.getRules().length; i++) {
            h.add( bin.getRules()[i].getName() );
        }
        return h;
    }

}
TOP

Related Classes of org.drools.guvnor.server.RepositoryPackageService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.