All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.manydesigns.portofino.code.AggregateCodeBase Maven / Gradle / Ivy

The newest version!
package com.manydesigns.portofino.code;

import io.reactivex.disposables.Disposable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.CopyOnWriteArrayList;

public class AggregateCodeBase extends AbstractCodeBase {

    private static final Logger logger = LoggerFactory.getLogger(AggregateCodeBase.class);
    protected final List codeBases = new CopyOnWriteArrayList<>();

    public AggregateCodeBase() {
        super(null);
    }

    public AggregateCodeBase(CodeBase parent, ClassLoader classLoader) {
        super(null, parent, classLoader);
    }

    @Override
    protected Class loadLocalClass(String className) throws IOException, ClassNotFoundException {
        for(CodeBaseWithSubscription c : codeBases) {
            try {
                Class aClass = c.codeBase.loadClass(className, SearchScope.LOCAL);
                if(aClass != null) {
                    return aClass;
                }
            } catch (ClassNotFoundException e) { //Don't catch IOExceptions. Is this the right thing to do?
                logger.debug("Class " + className + " not found in codebase " + c.codeBase, e);
            }
        }
        return null;
    }

    @Override
    public URL findResource(String name) throws IOException {
        for(CodeBaseWithSubscription c : codeBases) {
            URL resource = c.codeBase.findResource(name);
            if(resource != null) {
                return resource;
            }
        }
        if(parent != null) {
            return parent.findResource(name);
        } else {
            return null;
        }
    }

    @Override
    public void clear(boolean recursively) throws Exception {
        super.clear(recursively);
        for(CodeBaseWithSubscription c : codeBases) {
            c.codeBase.clear(recursively);
        }
    }

    @Override
    public void close() {
        super.close();
        codeBases.forEach(c -> {
            c.subscription.dispose();
            c.codeBase.close();
        });
        codeBases.clear();
    }

    public void add(CodeBase codeBase) {
        codeBases.add(subscribeToCodeBase(codeBase));
        reloads.onNext(getClass());
    }

    protected CodeBaseWithSubscription subscribeToCodeBase(CodeBase codeBase) {
        return new CodeBaseWithSubscription(codeBase, codeBase.getReloads().subscribe(reloads::onNext));
    }

    public boolean remove(CodeBase codeBase) {
        return codeBases.removeIf(c -> {
            if(c.codeBase.equals(codeBase)) {
                c.subscription.dispose();
                reloads.onNext(getClass());
                return true;
            }
            return false;
        });
    }

    public boolean replace(CodeBase oldCodeBase, CodeBase newCodeBase) {
        ListIterator iterator = codeBases.listIterator();
        while(iterator.hasNext()) {
            CodeBaseWithSubscription next = iterator.next();
            if(next.codeBase.equals(oldCodeBase)) {
                next.subscription.dispose();
                iterator.remove();
                iterator.add(subscribeToCodeBase(newCodeBase));
                reloads.onNext(getClass());
                return true;
            }
        }
        return false;
    }
}

class CodeBaseWithSubscription {
    CodeBase codeBase;
    Disposable subscription;
    CodeBaseWithSubscription(CodeBase codeBase, Disposable subscription) {
        this.codeBase = codeBase;
        this.subscription = subscription;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy