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

org.drombler.commons.context.ProxyContext Maven / Gradle / Ivy

Go to download

Drombler Commons - Context is a framework to work with objects available in a given context.

There is a newer version: 1.0
Show newest version
/*
 *         COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Notice
 *
 * The contents of this file are subject to the COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL)
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.opensource.org/licenses/cddl1.txt
 *
 * The Original Code is Drombler.org. The Initial Developer of the
 * Original Code is Florian Brunner (Sourceforge.net user: puce).
 * Copyright 2012 Drombler.org. All Rights Reserved.
 *
 * Contributor(s): .
 */
package org.drombler.commons.context;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * A {@link Context} which proxies other contexts.
 *
 * @author puce
 */
public class ProxyContext extends AbstractContext {

    private final List contexts = new ArrayList<>();

    /**
     * {@inheritDoc }
     */
    @Override
    public  T find(Class type) {
        for (Context context : contexts) {
            T result = context.find(type);
            if (result != null) {
                return result;
            }
        }
        return null;
    }

    /**
     * {@inheritDoc }
     */
    @Override
    public  Collection findAll(Class type) {
        List result = new ArrayList<>();

        contexts.forEach(context -> result.addAll(context.findAll(type)));

        return result;
    }

    /**
     * {@inheritDoc }
     */
    @Override
    public void addContextListener(Class type, ContextListener listener) {
        super.addContextListener(type, listener);

        contexts.forEach(context -> context.addContextListener(type, listener));
    }

    /**
     * {@inheritDoc }
     */
    @Override
    public void removeContextListener(Class type, ContextListener listener) {
        super.removeContextListener(type, listener);
        contexts.forEach(context -> context.removeContextListener(type, listener));
    }

//    @Override
//    public  void track(Class type, ContextListener listener) {
//        if (contexts != null) {
//            for (Context context : contexts) {
//                context.track(type, listener);
//            }
//        }
//    }
    /**
     * Adds another {@link Context} to be proxied by this context.
     *
     * @param context a Context to be proxied
     */
    public void addContext(Context context) {
        addContextOnly(context);
        fireContextEvents(Arrays.asList(context));
    }

    public void addContexts(List contexts) {
        contexts.forEach(this::addContextOnly);
        fireContextEvents(contexts);
    }

    private void addContextOnly(Context context) {
        contexts.add(context);
        getListeners().entrySet().forEach(entry
                -> entry.getValue().forEach(contextListener
                        -> context.addContextListener(entry.getKey(), contextListener)));
    }

    /**
     * Removes a {@link Context} from being proxied by this context
     *
     * @param context the context to removed
     */
    public void removeContext(Context context) {
        removeContextOnly(context);
        fireContextEvents(Arrays.asList(context));
    }

    private void removeContextOnly(Context context) {
        contexts.remove(context);
        getListeners().entrySet().forEach(entry
                -> entry.getValue().forEach(contextListener
                        -> context.removeContextListener(entry.getKey(), contextListener)));
    }

    /**
     * Sets the contexts to be proxied by this context. This will remove all contexts registered before.
     *
     * @param contexts the contexts to be proxied
     */
    public void setContexts(Context... contexts) {
        setContexts(Arrays.asList(contexts));
    }

    /**
     * Sets the contexts to be proxied by this context. This will remove all contexts registered before.
     *
     * @param contexts the contexts to be proxied
     */
    public void setContexts(List contexts) {
        List contextsToRemove = new ArrayList<>(this.contexts);
        contextsToRemove.removeAll(contexts);

        contextsToRemove.forEach(this::removeContextOnly);

        List contextsToAdd = new ArrayList<>(contexts);
        contextsToAdd.removeAll(this.contexts);

        contexts.forEach(this::addContextOnly);

        List changedContexts = new ArrayList<>(contextsToRemove);
        changedContexts.addAll(contextsToAdd);

        fireContextEvents(changedContexts);
    }

    private void fireContextEvents(List changedContexts) {
        for (Class type : getListeners().keySet()) {
            for (Context context : changedContexts) {
                if (!context.findAll(type).isEmpty()) {
                    fireContextEvent(type);
                    break; // TODO: correct?
                }
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy