org.eclipse.viatra.query.runtime.registry.impl.AbstractRegistryView.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.viatra.query.runtime.registry.impl.AbstractRegistryView.java

Source

/*******************************************************************************
 * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Abel Hegedus - initial API and implementation
 *******************************************************************************/
package org.eclipse.viatra.query.runtime.registry.impl;

import static com.google.common.base.Preconditions.checkArgument;

import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;

import org.eclipse.viatra.query.runtime.api.GenericQueryGroup;
import org.eclipse.viatra.query.runtime.api.IQueryGroup;
import org.eclipse.viatra.query.runtime.api.IQuerySpecification;
import org.eclipse.viatra.query.runtime.registry.IQuerySpecificationRegistry;
import org.eclipse.viatra.query.runtime.registry.IQuerySpecificationRegistryEntry;
import org.eclipse.viatra.query.runtime.registry.IRegistryChangeListener;
import org.eclipse.viatra.query.runtime.registry.IRegistryView;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

/**
 * An abstract {@link IRegistryView} implementation that stores the registry, the set of listeners added to the view and
 * the FQN to entry map of the view itself. The only responsibility of subclasses is to decide whether an entry received
 * as an addition or removal notification is relevent to the view.
 * 
 * @author Abel Hegedus
 *
 */
public abstract class AbstractRegistryView implements IRegistryView, IRegistryChangeListener {

    protected IQuerySpecificationRegistry registry;
    protected Map<String, IQuerySpecificationRegistryEntry> fqnToEntryMap;
    protected Set<IRegistryChangeListener> listeners;

    /**
     * This method is called both when an addition or removal notification is received from the registry. Subclasses can
     * implement view filtering by returning false for those specifications that are not relevant for this view.
     * 
     * @param entry
     *            that is added or removed in the registry
     * @return true if the entry should be added to or removed from the view, false otherwise
     */
    protected abstract boolean isEntryRelevant(IQuerySpecificationRegistryEntry entry);

    /**
     * Creates a new view instance for the given registry. Note that views are created by the registry and the view
     * update mechanisms are also set up by the registry.
     * 
     * @param registry
     */
    public AbstractRegistryView(IQuerySpecificationRegistry registry) {
        this.registry = registry;
        this.fqnToEntryMap = Maps.newTreeMap();
        this.listeners = Sets.newHashSet();
    }

    @Override
    public IQuerySpecificationRegistry getRegistry() {
        return registry;
    }

    @Override
    public Iterable<IQuerySpecificationRegistryEntry> getEntries() {
        ImmutableSet<IQuerySpecificationRegistryEntry> entrySet = ImmutableSet.copyOf(fqnToEntryMap.values());
        return entrySet;
    }

    @Override
    public Set<String> getQuerySpecificationFQNs() {
        ImmutableSet<String> fqns = ImmutableSet.copyOf(fqnToEntryMap.keySet());
        return fqns;
    }

    @Override
    public boolean hasQuerySpecificationFQN(String fullyQualifiedName) {
        checkArgument(fullyQualifiedName != null, "FQN must not be null!");
        return fqnToEntryMap.containsKey(fullyQualifiedName);
    }

    @Override
    public IQuerySpecificationRegistryEntry getEntry(String fullyQualifiedName) {
        checkArgument(fullyQualifiedName != null, "FQN must not be null!");
        IQuerySpecificationRegistryEntry entry = fqnToEntryMap.get(fullyQualifiedName);
        if (entry == null) {
            throw new NoSuchElementException(String.format("Cannot find entry with FQN %s", fullyQualifiedName));
        }
        return entry;
    }

    /**
     * Note that calling this method will perform class loading on all included IQuerySpecifications.
     */
    @Override
    public IQueryGroup getQueryGroup() {
        Iterable<IQuerySpecification<?>> querySpecifications = Iterables.transform(fqnToEntryMap.values(),
                new Function<IQuerySpecificationRegistryEntry, IQuerySpecification<?>>() {
                    @Override
                    public IQuerySpecification<?> apply(IQuerySpecificationRegistryEntry entry) {
                        return entry.get();
                    }
                });
        IQueryGroup queryGroup = GenericQueryGroup.of(ImmutableSet.copyOf(querySpecifications));
        return queryGroup;
    }

    @Override
    public void addViewListener(IRegistryChangeListener listener) {
        listeners.add(listener);
    }

    @Override
    public void removeViewListener(IRegistryChangeListener listener) {
        listeners.remove(listener);
    }

    @Override
    public void entryAdded(IQuerySpecificationRegistryEntry entry) {
        if (isEntryRelevant(entry)) {
            String fullyQualifiedName = entry.getFullyQualifiedName();
            IQuerySpecificationRegistryEntry oldEntry = fqnToEntryMap.put(fullyQualifiedName, entry);
            if (oldEntry != null) {
                for (IRegistryChangeListener iRegistryChangeListener : listeners) {
                    iRegistryChangeListener.entryRemoved(oldEntry);
                }
            }
            for (IRegistryChangeListener iRegistryChangeListener : listeners) {
                iRegistryChangeListener.entryAdded(entry);
            }
        }
    }

    @Override
    public void entryRemoved(IQuerySpecificationRegistryEntry entry) {
        if (isEntryRelevant(entry)) {
            String fullyQualifiedName = entry.getFullyQualifiedName();
            IQuerySpecificationRegistryEntry existingEntry = fqnToEntryMap.get(fullyQualifiedName);
            if (entry.equals(existingEntry)) {
                fqnToEntryMap.remove(fullyQualifiedName);
                for (IRegistryChangeListener iRegistryChangeListener : listeners) {
                    iRegistryChangeListener.entryRemoved(entry);
                }
            }
        }
    }

}