Package org.locationtech.udig.project.internal.impl

Source Code of org.locationtech.udig.project.internal.impl.BlackboardImpl$PersisterProcessor

/**
* <copyright>
* </copyright>
*
* $Id$
*/
package org.locationtech.udig.project.internal.impl;

import java.io.Serializable;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import org.locationtech.udig.core.internal.ExtensionPointProcessor;
import org.locationtech.udig.core.internal.ExtensionPointUtil;
import org.locationtech.udig.project.BlackboardEvent;
import org.locationtech.udig.project.IBlackboard;
import org.locationtech.udig.project.IBlackboardListener;
import org.locationtech.udig.project.IPersister;
import org.locationtech.udig.project.IProvider;
import org.locationtech.udig.project.internal.Blackboard;
import org.locationtech.udig.project.internal.BlackboardEntry;
import org.locationtech.udig.project.internal.ProjectPackage;
import org.locationtech.udig.project.internal.ProjectPlugin;
import org.locationtech.udig.ui.PlatformGIS;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.EObjectImpl;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.ui.XMLMemento;
import org.osgi.framework.Bundle;

/**
* A blackboard that saves its state out as an EObject.
*
* @author Jesse
* @since 1.0.0
* @generated
*/
public class BlackboardImpl extends EObjectImpl implements Blackboard {

    /**
     * underlying container *
     *
     * @uml.property name="blackboard"
     * @uml.associationEnd qualifier="key:java.lang.Object
     *                     org.locationtech.udig.project.internal.impl.BlackboardEntryImpl"
     */
    HashMap<String, BlackboardEntry> blackboard = new HashMap<String, BlackboardEntry>();

    /** persisters */
    ArrayList<IPersister<?>> persisters;

    /** providers * */
    ArrayList<IProvider<Object>> providers;

    boolean initialized = false;

    /**
     * The cached value of the '{@link #getEntries() <em>Entries</em>}' containment reference list.
     * <!-- begin-user-doc --> <!-- end-user-doc -->
     * @see #getEntries()
     * @generated
     * @ordered
     */
    protected EList<BlackboardEntry> entries;

    /**
     * <!-- begin-user-doc --> <!-- end-user-doc -->
     * @generated
     */
    protected BlackboardImpl() {
        super();
    }

    /**
     * <!-- begin-user-doc --> <!-- end-user-doc -->
     * @generated
     */
    @Override
    protected EClass eStaticClass() {
        return ProjectPackage.Literals.BLACKBOARD;
    }

    /**
     * <!-- begin-user-doc --> <!-- end-user-doc -->
     * @generated
     */
    @SuppressWarnings("unchecked")
    public List<BlackboardEntry> getEntries() {
        if (entries == null) {
            entries = new EObjectContainmentEList<BlackboardEntry>(BlackboardEntry.class, this,
                    ProjectPackage.BLACKBOARD__ENTRIES);
        }
        return entries;
    }

    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    @Override
    public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID,
            NotificationChain msgs) {
        switch (featureID) {
        case ProjectPackage.BLACKBOARD__ENTRIES:
            return ((InternalEList<?>) getEntries()).basicRemove(otherEnd, msgs);
        }
        return super.eInverseRemove(otherEnd, featureID, msgs);
    }

    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    @Override
    public Object eGet(int featureID, boolean resolve, boolean coreType) {
        switch (featureID) {
        case ProjectPackage.BLACKBOARD__ENTRIES:
            return getEntries();
        }
        return super.eGet(featureID, resolve, coreType);
    }

    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    @SuppressWarnings("unchecked")
    @Override
    public void eSet(int featureID, Object newValue) {
        switch (featureID) {
        case ProjectPackage.BLACKBOARD__ENTRIES:
            getEntries().clear();
            getEntries().addAll((Collection<? extends BlackboardEntry>) newValue);
            return;
        }
        super.eSet(featureID, newValue);
    }

    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    @Override
    public void eUnset(int featureID) {
        switch (featureID) {
        case ProjectPackage.BLACKBOARD__ENTRIES:
            getEntries().clear();
            return;
        }
        super.eUnset(featureID);
    }

    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    @Override
    public boolean eIsSet(int featureID) {
        switch (featureID) {
        case ProjectPackage.BLACKBOARD__ENTRIES:
            return entries != null && !entries.isEmpty();
        }
        return super.eIsSet(featureID);
    }

    /*
     * (non-Javadoc)
     * @see org.locationtech.udig.project.IBlackboard#contains(java.lang.String)
     */
    public boolean contains(String key) {
        return get(key) != null;
    }

    /*
     * (non-Javadoc)
     * @see org.locationtech.udig.project.IBlackboard#get(java.lang.String)
     */
    @SuppressWarnings("unchecked")//$NON-NLS-1$
    public Object get(String key) {
        if (!initialized) {
            initialize();
        }
        if (key == null)
            return null;

        // look up the entry
        BlackboardEntry entry = blackboard.get(key);
        if (entry != null) {
            if (entry.getObject() != null) {
                return entry.getObject();
            } else {
                Object object = null;
                try {
                    // have to load from memento
                    String memento2 = entry.getMemento();
                    if (memento2 == null || memento2.length() == 0) {
                        return null;
                    }
                    XMLMemento memento = XMLMemento.createReadRoot(new StringReader(memento2));
                    IPersister<Object> persister = (IPersister<Object>) findPersister(entry,
                            memento);
                    if (persister != null) {
                        object = persister.load(memento);
                        entry.setObject(object);
                        entry.setObjectClass(object.getClass());
                    } else {
                        // real object which cannot be saved between runs
                    }
                } catch (Exception e) {
                    String msg = "Error loading content: " + entry.getObjectClass(); //$NON-NLS-1$
                    IStatus status = new Status(IStatus.WARNING, ProjectPlugin.ID, 0, msg, e); //$NON-NLS-1$
                    ProjectPlugin.getPlugin().getLog().log(status);
                }

                return object;
            }
        } else {
            // object does not exists, try to find a provider
            IProvider provider = findProvider(key);
            if (provider != null) {
                try {
                    Object object = provider.provide();
                    if (object != null) {
                        createEntry(key, object);
                        return object;
                    }
                } catch (Exception e) {
                    String msg = "provider exception :" + key; //$NON-NLS-1$
                    String id = provider.getExtension().getNamespace();
                    IStatus status = new Status(IStatus.WARNING, id, 0, msg, e);

                    ProjectPlugin.getPlugin().getLog().log(status);
                }
            }
        }

        return null;
    }

    private void initialize() {
        initialized = true;
        for (BlackboardEntry entry : this.getEntries()) {
            blackboard.put(entry.getKey(), entry);
        }
    }

    public Object remove(String key) {
        if (key == null)
            return null;

        // look up the entry
        BlackboardEntry entry = blackboard.remove(key);
        if (entry == null) {
            return null;
        }
        Object oldValue = entry.getObject();
        entry.setMemento(null);
        entry.setObject(null);

        BlackboardEvent event = new BlackboardEvent(this, key, oldValue, null);
        for (IBlackboardListener l : listeners) {
            try {
                l.blackBoardChanged(event);
            } catch (Exception e) {
                ProjectPlugin.log("", e); //$NON-NLS-1$
            }
        }
        return oldValue;
    }

    /*
     * (non-Javadoc)
     * @see org.locationtech.udig.project.IBlackboard#put(java.lang.String, java.lang.Object)
     */
    public void put(String key, Object value) {
        if (key == null) {
            return; // stop you fool!
        }
        if (value == null) {
            this.remove(key);
            return;
        }
        Object oldValue = null;
        BlackboardEntry entry = blackboard.get(key);

        if (entry == null) {
            entry = createEntry(key, value);
        } else {
            oldValue = entry.getObject();
        }
        // set the cache
        entry.setObject(value);

        // find the persister to save the state
        @SuppressWarnings("unchecked")
        IPersister<Object> persister = (IPersister<Object>) findPersister(entry, null);
        try {
            if (persister != null) {
                XMLMemento memento = XMLMemento.createWriteRoot("blackboardContent"); //$NON-NLS-1$
                persister.save(value, memento);
                memento.putString("internalObjectClassStorage", entry.getObjectClass().getName()); //$NON-NLS-1$

                StringWriter writer = new StringWriter();
                memento.save(writer);
                entry.setMemento(writer.getBuffer().toString());
            } else {
                // this is a "real" object that cannot be shared between runs
            }
        } catch (Exception e) {
            String msg = "Error persisting content: " + value.getClass(); //$NON-NLS-1$
            if (persister != null) {
                IExtension ext = persister.getExtension();
                IStatus status = new Status(IStatus.WARNING, ext.getNamespaceIdentifier(), 0, msg,
                        e);
                ProjectPlugin.getPlugin().getLog().log(status);
            } else {
                ProjectPlugin.log("error loading persister", e); //$NON-NLS-1$
            }
        }
        BlackboardEvent event = new BlackboardEvent(this, key, oldValue, value);
        for (IBlackboardListener l : listeners) {
            try {
                l.blackBoardChanged(event);
            } catch (Exception e) {
                ProjectPlugin.log("", e); //$NON-NLS-1$
            }
        }
    }

    /*
     * (non-Javadoc)
     * @see org.locationtech.udig.project.IBlackboard#getFloat(java.lang.String)
     */
    public Float getFloat(String key) {
        Object o = get(key);
        if (o != null && o instanceof Float) {
            return (Float) o;
        }

        return null;
    }

    /*
     * (non-Javadoc)
     * @see org.locationtech.udig.project.IBlackboard#getInteger(java.lang.String)
     */
    public Integer getInteger(String key) {
        Object o = get(key);
        if (o != null && o instanceof Integer) {
            return (Integer) o;
        }

        return null;
    }

    /*
     * (non-Javadoc)
     * @see org.locationtech.udig.project.IBlackboard#getString(java.lang.String)
     */
    public String getString(String key) {
        Object o = get(key);
        if (o != null && o instanceof String) {
            return (String) o;
        }

        return null;
    }

    /*
     * (non-Javadoc)
     * @see org.locationtech.udig.project.IBlackboard#putFloat(java.lang.String, float)
     */
    public void putFloat(String key, float value) {
        put(key, value);
    }

    /*
     * (non-Javadoc)
     * @see org.locationtech.udig.project.IBlackboard#putInteger(java.lang.String, int)
     */
    public void putInteger(String key, int value) {
        put(key, value);

    }

    /*
     * (non-Javadoc)
     * @see org.locationtech.udig.project.IBlackboard#putString(java.lang.String, java.lang.String)
     */
    public void putString(String key, String value) {
        put(key, value);
    }

    /*
     * (non-Javadoc)
     * @see org.locationtech.udig.project.IBlackboard#clear()
     */
    public void clear() {
        blackboard.clear();
        for (IBlackboardListener l : listeners) {
            l.blackBoardCleared(this);
        }
    }

    CopyOnWriteArraySet<IBlackboardListener> listeners = new CopyOnWriteArraySet<IBlackboardListener>();

    public boolean addListener(IBlackboardListener listener) {
        return listeners.add(listener);
    }

    public boolean removeListener(IBlackboardListener listener) {
        return listeners.remove(listener);
    }

    /**
     * Flushes all the cached objects. Useful for testing.
     */
    public void flush() {
        for (BlackboardEntry entry : blackboard.values()) {
            entry.setObject(null);
        }
    }

    private IProvider findProvider(String key) {
        if (providers == null) {
            providers = new ArrayList<IProvider<Object>>();
            ProviderProcessor p = new ProviderProcessor(providers);
            ExtensionPointUtil.process(ProjectPlugin.getPlugin(), IProvider.XPID, p);
        }

        // search for provider matching key
        for (IProvider<Object> provider : providers) {
            if (provider.getKey() != null && provider.getKey().equals(key))
                return provider;
        }

        return null;
    }

    @SuppressWarnings("unchecked")
    private BlackboardEntryImpl createEntry(String key, Object object) {

        BlackboardEntryImpl entry = new BlackboardEntryImpl();

        entry.setKey(key);
        entry.setObjectClass(object != null ? object.getClass() : null);
        blackboard.put(key, entry);

        // add to entries for persistance
        getEntries().add(entry);

        return entry;
    }

    @SuppressWarnings("unchecked")
    private IPersister<?> findPersister(BlackboardEntry entry, XMLMemento memento) {
        if (persisters == null) {
            synchronized (this) {
                if (persisters == null) {
                    persisters = new ArrayList<IPersister<?>>();
                    PersisterProcessor p = new PersisterProcessor(persisters);
                    ExtensionPointUtil.process(ProjectPlugin.getPlugin(), IPersister.XPID, p);
                }
            }
        }

        // look for a class closest down in the class hierarchy
        ArrayList<IPersister<?>> possible = new ArrayList<IPersister<?>>();

        for (IPersister<?> persister : persisters) {
            Class<?> persistenceTarget = persister.getPersistee();
            if (persistenceTarget == null) {
                continue; // this persister does not seem to be set up correctly
            }
            if (entry.getObjectClass() != null) {
                Class<?> type = entry.getObjectClass();
                if (persistenceTarget.isAssignableFrom(type)) {
                    possible.add(persister);
                    continue;
                }
            }
            Class objectClass = entry.getObjectClass();
            if (objectClass == null && memento != null) {
                String className = memento.getString("internalObjectClassStorage");
                if (className.equals(persistenceTarget)) {
                    possible.add(persister);
                    continue; // we are good on this one
                } else {
                    try {
                        ClassLoader classLoader = persistenceTarget.getClassLoader();
                        if (classLoader != null) {
                            objectClass = classLoader.loadClass(className);
                        } else {
                            objectClass = Class.forName(className);
                        }
                        if (objectClass != null && objectClass.isAssignableFrom(persistenceTarget)) {
                            possible.add(persister);
                        }
                    } catch (Exception e) {
                        if (ProjectPlugin.isDebugging("blackboard")) {
                            ProjectPlugin.trace(BlackboardImpl.class, persister.getExtension()
                                    .getExtensionPointUniqueIdentifier()
                                    + "unable to load " + className, e); //$NON-NLS-1$
                        }
                        continue; // skip this one
                    }
                }
            }
        }
        if (possible.isEmpty()) {
            ProjectPlugin
                    .trace(BlackboardImpl.class, entry.getKey() + " cannot be persisted", null); //$NON-NLS-1$
            return null;
        }

        Collections.sort(possible, new Comparator<IPersister<?>>() {
            public int compare(IPersister<?> p1, IPersister<?> p2) {
                if (p1.getPersistee().equals(p2.getPersistee())) {
                    return 0;
                }
                if (p1.getPersistee().isAssignableFrom(p2.getPersistee())) {
                    return -1;
                }
                return 1;
            }
        });

        return possible.get(0);
    }

    static class ProviderProcessor implements ExtensionPointProcessor {

        List<IProvider<Object>> providers;

        ProviderProcessor(List<IProvider<Object>> providers) {
            this.providers = providers;
        }

        @SuppressWarnings("unchecked")
        public void process(IExtension extension, IConfigurationElement element) throws Exception {
            try {
                IProvider<Object> provider = (IProvider<Object>) element
                        .createExecutableExtension("class"); //$NON-NLS-1$

                if (provider != null) {
                    providers.add(provider);
                    provider.setExtension(extension);
                    if (element.getAttribute("key") != null) { //$NON-NLS-1$
                        provider.setKey(element.getAttribute("key")); //$NON-NLS-1$
                    }
                }
            } catch (Throwable t) {
                ProjectPlugin.log(t.getLocalizedMessage(), t);
            }
        }
    }

    static class PersisterProcessor implements ExtensionPointProcessor {

        List<IPersister<?>> persisters;

        PersisterProcessor(List<IPersister<?>> persisters) {
            this.persisters = persisters;
        }

        public void process(IExtension extension, IConfigurationElement element) throws Exception {

            try {
                IPersister<?> persister = (IPersister<?>) element
                        .createExecutableExtension("class"); //$NON-NLS-1$

                if (persister != null) {
                    persister.setExtension(extension);
                    persisters.add(persister);
                }
            } catch (Throwable t) {
                ProjectPlugin.log(t.getLocalizedMessage(), t);
            }

        }
    }

    public void addAll(IBlackboard blackboard) {
        Set<String> keySet = blackboard.keySet();
        for (String key : keySet) {
            put(key, blackboard.get(key));
        }
    }

    public Set<String> keySet() {
        return this.blackboard.keySet();
    }

    @SuppressWarnings("nls")
    @Override
    public String toString() {
        StringBuffer buf = new StringBuffer();
        buf.append("StyleBlackBoardImpl: ");
        buf.append(blackboard.size());
        buf.append(" entries");
        for (Map.Entry entry : blackboard.entrySet()) {
            buf.append("\n\t");
            buf.append(entry.getKey());
            buf.append("=");
            buf.append(entry.getValue());
        }
        return buf.toString();
    }
} // BlackboardImpl
TOP

Related Classes of org.locationtech.udig.project.internal.impl.BlackboardImpl$PersisterProcessor

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.