Package org.kie.scanner

Source Code of org.kie.scanner.KieRepositoryScannerImpl$ScanTask

package org.kie.scanner;

import org.drools.compiler.kie.builder.impl.InternalKieContainer;
import org.drools.compiler.kie.builder.impl.InternalKieModule;
import org.drools.compiler.kie.builder.impl.InternalKieScanner;
import org.drools.compiler.kie.builder.impl.MemoryKieModule;
import org.drools.compiler.kie.builder.impl.ResultsImpl;
import org.drools.compiler.kie.builder.impl.ZipKieModule;
import org.drools.compiler.kproject.ReleaseIdImpl;
import org.drools.compiler.kproject.models.KieModuleModelImpl;
import org.eclipse.aether.artifact.Artifact;
import org.kie.api.KieServices;
import org.kie.api.builder.KieModule;
import org.kie.api.builder.KieScanner;
import org.kie.api.builder.Message;
import org.kie.api.builder.ReleaseId;
import org.kie.api.builder.model.KieModuleModel;
import org.kie.api.runtime.KieContainer;
import org.kie.scanner.management.KieScannerMBean;
import org.kie.scanner.management.KieScannerMBeanImpl;
import org.kie.scanner.management.MBeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import static org.drools.compiler.kie.builder.impl.KieBuilderImpl.buildKieModule;
import static org.drools.compiler.kie.builder.impl.KieBuilderImpl.setDefaultsforEmptyKieModule;
import static org.kie.scanner.ArtifactResolver.getResolverFor;

public class KieRepositoryScannerImpl implements InternalKieScanner {

    private Timer timer;

    private static final Logger log = LoggerFactory.getLogger(KieScanner.class);

    private InternalKieContainer kieContainer;

    private DependencyDescriptor kieProjectDescr;

    private Map<ReleaseId, DependencyDescriptor> usedDependencies;

    private ArtifactResolver artifactResolver;

    private Status status = Status.STARTING;

    private KieScannerMBean mbean;

    public synchronized void setKieContainer(KieContainer kieContainer) {
        if (this.kieContainer != null) {
            throw new RuntimeException("Cannot change KieContainer on an already initialized KieScanner");
        }
        this.kieContainer = (InternalKieContainer)kieContainer;
        if (this.kieContainer.getContainerReleaseId() == null) {
            throw new RuntimeException("The KieContainer's ReleaseId cannot be null. Are you using a KieClasspathContainer?");
        }

        kieProjectDescr = new DependencyDescriptor(this.kieContainer.getReleaseId(),
                                                   this.kieContainer.getCreationTimestamp());

        artifactResolver = getResolverFor(kieContainer.getReleaseId(), true);
        usedDependencies = indexAtifacts(artifactResolver);

        KieScannersRegistry.register(this);
        status = Status.STOPPED;
       
        if( MBeanUtils.isMBeanEnabled() ) {
            mbean = new KieScannerMBeanImpl(this);
        }
    }

    private ArtifactResolver getArtifactResolver() {
        if (artifactResolver == null) {
            artifactResolver = new ArtifactResolver();
        }
        return artifactResolver;
    }

    public synchronized KieModule loadArtifact(ReleaseId releaseId) {
        return loadArtifact(releaseId, null);
    }

    public synchronized KieModule loadArtifact(ReleaseId releaseId, InputStream pomXml) {
        ArtifactResolver resolver = pomXml != null ?
                                    ArtifactResolver.getResolverFor(pomXml) :
                                    getArtifactResolver();
        Artifact artifact = resolver.resolveArtifact(releaseId);
        return artifact != null ? buildArtifact(artifact, resolver) : loadPomArtifact(releaseId);
    }

    public synchronized String getArtifactVersion(ReleaseId releaseId) {
        if (!releaseId.isSnapshot()) {
            return releaseId.getVersion();
        }
        Artifact artifact = getArtifactResolver().resolveArtifact(releaseId);
        return artifact != null ? artifact.getVersion() : null;
    }

    public synchronized ReleaseId getScannerReleaseId() {
        return kieContainer.getContainerReleaseId();
    }

    public synchronized ReleaseId getCurrentReleaseId() {
        return kieContainer.getReleaseId();
    }

    public synchronized Status getStatus() {
        return status;
    }

    private KieModule loadPomArtifact(ReleaseId releaseId) {
        ArtifactResolver resolver = getResolverFor(releaseId, false);
        if (resolver == null) {
            return null;
        }

        MemoryKieModule kieModule = new MemoryKieModule(releaseId);
        addDependencies(kieModule, resolver, resolver.getPomDirectDependencies());
        build(kieModule);
        return kieModule;
    }

    private InternalKieModule buildArtifact(Artifact artifact, ArtifactResolver resolver) {
        DependencyDescriptor dependencyDescriptor = new DependencyDescriptor(artifact);
        ReleaseId releaseId = dependencyDescriptor.getReleaseId();
        if (releaseId.isSnapshot()) {
            ((ReleaseIdImpl)releaseId).setSnapshotVersion(artifact.getVersion());
        }
        ZipKieModule kieModule = createZipKieModule(releaseId, artifact.getFile());
        if (kieModule != null) {
            addDependencies(kieModule, resolver, resolver.getArtifactDependecies(dependencyDescriptor.toString()));
            build(kieModule);
        }
        return kieModule;
    }
   
    private void addDependencies(InternalKieModule kieModule, ArtifactResolver resolver, List<DependencyDescriptor> dependencies) {
        for (DependencyDescriptor dep : dependencies) {
            InternalKieModule dependency = (InternalKieModule) KieServices.Factory.get().getRepository().getKieModule(dep.getReleaseId());
            if (dependency != null) {
                kieModule.addKieDependency(dependency);
            } else {
                Artifact depArtifact = resolver.resolveArtifact(dep.getReleaseId());
                if (depArtifact != null && isKJar(depArtifact.getFile())) {
                    ReleaseId depReleaseId = new DependencyDescriptor(depArtifact).getReleaseId();
                    ZipKieModule zipKieModule = createZipKieModule(depReleaseId, depArtifact.getFile());
                    if (zipKieModule != null) {
                        kieModule.addKieDependency(zipKieModule);
                    }
                }
            }
        }
    }

    private static ZipKieModule createZipKieModule(ReleaseId releaseId, File jar) {
        KieModuleModel kieModuleModel = getKieModuleModelFromJar(jar);
        return kieModuleModel != null ? new ZipKieModule(releaseId, kieModuleModel, jar) : null;
    }

    private static KieModuleModel getKieModuleModelFromJar(File jar) {
        ZipFile zipFile = null;
        try {
            zipFile = new ZipFile( jar );
            ZipEntry zipEntry = zipFile.getEntry(KieModuleModelImpl.KMODULE_JAR_PATH);
            KieModuleModel kieModuleModel = KieModuleModelImpl.fromXML(zipFile.getInputStream(zipEntry));
            setDefaultsforEmptyKieModule(kieModuleModel);
            return kieModuleModel;
        } catch ( Exception e ) {
        } finally {
      if (zipFile != null) {
        try {
          zipFile.close();
        } catch (IOException e) {
        }
      }
        }
        return null;
    }

    private ResultsImpl build(InternalKieModule kieModule) {
        ResultsImpl messages = new ResultsImpl();
        buildKieModule(kieModule, messages);
        return messages;
    }

    public synchronized void start(long pollingInterval) {
        if (getStatus() == Status.SHUTDOWN ) {
            throw new IllegalStateException("The scanner was shut down and can no longer be started.");
        }
        if (pollingInterval <= 0) {
            throw new IllegalArgumentException("pollingInterval must be positive");
        }
        if (timer != null) {
            throw new IllegalStateException("The scanner is already running");
        }
        startScanTask(pollingInterval);
    }

    public synchronized void stop() {
        if (getStatus() == Status.SHUTDOWN ) {
            throw new IllegalStateException("The scanner was already shut down.");
        }
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
        status = Status.STOPPED;
    }
   
    public void shutdown() {
        if( getStatus() != Status.SHUTDOWN ) {
            stop(); // making sure it is stopped
            status = Status.SHUTDOWN;
        }
    }

    private void startScanTask(long pollingInterval) {
        status = Status.RUNNING;
        timer = new Timer(true);
        timer.schedule(new ScanTask(), pollingInterval, pollingInterval);
    }

    private class ScanTask extends TimerTask {
        public void run() {
            scanNow();
            status = Status.RUNNING;
        }
    }

    public synchronized void scanNow() {
        if (getStatus() == Status.SHUTDOWN ) {
            throw new IllegalStateException("The scanner was already shut down and can no longer be used.");
        }
        try {
            status = Status.SCANNING;
            Map<DependencyDescriptor, Artifact> updatedArtifacts = scanForUpdates();
            if (updatedArtifacts.isEmpty()) {
                status = Status.STOPPED;
                return;
            }
            status = Status.UPDATING;

            // build the dependencies first
            Map.Entry<DependencyDescriptor, Artifact> containerEntry = null;
            for (Map.Entry<DependencyDescriptor, Artifact> entry : updatedArtifacts.entrySet()) {
                if (entry.getKey().isSameArtifact(kieContainer.getContainerReleaseId())) {
                    containerEntry = entry;
                } else {
                    updateKieModule(entry.getKey(), entry.getValue());
                }
            }
            if (containerEntry != null) {
                updateKieModule(containerEntry.getKey(), containerEntry.getValue());
            }

            log.info("The following artifacts have been updated: " + updatedArtifacts);
           
            // show we catch exceptions here and shutdown the scanner if one happens?
           
        } finally {
            status = Status.STOPPED;
        }
    }

    private void updateKieModule(DependencyDescriptor oldDependency, Artifact artifact) {
        ReleaseId newReleaseId = new DependencyDescriptor(artifact).getReleaseId();
        ZipKieModule kieModule = createZipKieModule(newReleaseId, artifact.getFile());
        if (kieModule != null) {
            addDependencies(kieModule, artifactResolver, artifactResolver.getArtifactDependecies(newReleaseId.toString()));
            ResultsImpl messages = build(kieModule);
            if ( messages.filterMessages(Message.Level.ERROR).isEmpty()) {
                ((InternalKieContainer)kieContainer).updateDependencyToVersion(oldDependency.getArtifactReleaseId(),
                                                                               newReleaseId);
                oldDependency.setArtifactVersion(artifact.getVersion());
            }
        }
    }

    private Map<DependencyDescriptor, Artifact> scanForUpdates() {
        artifactResolver = getResolverFor(kieContainer.getReleaseId(), true);
        Map<DependencyDescriptor, Artifact> newArtifacts = new HashMap<DependencyDescriptor, Artifact>();

        Artifact newArtifact = artifactResolver.resolveArtifact(this.kieContainer.getContainerReleaseId());
        if (newArtifact != null) {
            DependencyDescriptor resolvedDep = new DependencyDescriptor(newArtifact);
            if (resolvedDep.isNewerThan(kieProjectDescr)) {
                newArtifacts.put(kieProjectDescr, newArtifact);
                kieProjectDescr = new DependencyDescriptor(newArtifact);
            }
        }

        for (DependencyDescriptor dep : artifactResolver.getAllDependecies()) {
            ReleaseId artifactId = dep.getReleaseIdWithoutVersion();
            DependencyDescriptor oldDep = usedDependencies.get(artifactId);
            if (oldDep != null) {
                newArtifact = artifactResolver.resolveArtifact(dep.getReleaseId());
                if (newArtifact != null) {
                    DependencyDescriptor newDep = new DependencyDescriptor(newArtifact);
                    if (newDep.isNewerThan(oldDep)) {
                        newArtifacts.put(oldDep, newArtifact);
                        usedDependencies.put(artifactId, newDep);
                    }
                }
            }
        }

        return newArtifacts;
    }

    private Map<ReleaseId, DependencyDescriptor> indexAtifacts(ArtifactResolver artifactResolver) {
        Map<ReleaseId, DependencyDescriptor> depsMap = new HashMap<ReleaseId, DependencyDescriptor>();
        for (DependencyDescriptor dep : artifactResolver.getAllDependecies()) {
            Artifact artifact = artifactResolver.resolveArtifact(dep.getReleaseId());
            log.debug( artifact + " resolved to  " + artifact.getFile() );
            if (isKJar(artifact.getFile())) {
                depsMap.put(dep.getReleaseIdWithoutVersion(), new DependencyDescriptor(artifact));
            }
        }
        return depsMap;
    }

    private boolean isKJar(File jar) {
        ZipFile zipFile;
        try {
            zipFile = new ZipFile( jar );
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        ZipEntry zipEntry = zipFile.getEntry( KieModuleModelImpl.KMODULE_JAR_PATH );
        return zipEntry != null;
    }
   
    public synchronized KieScannerMBean getMBean() {
        return this.mbean;
    }
}
TOP

Related Classes of org.kie.scanner.KieRepositoryScannerImpl$ScanTask

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.