/*******************************************************************************
* Copyright (c) 2007, 2014 compeople AG and others.
* 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:
* compeople AG - initial API and implementation
*******************************************************************************/
package org.eclipse.riena.internal.ui.workarea.registry;
import java.util.Hashtable;
import java.util.SortedSet;
import java.util.TreeSet;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
import org.eclipse.riena.core.singleton.SingletonProvider;
import org.eclipse.riena.internal.ui.workarea.Activator;
import org.eclipse.riena.navigation.INavigationNode;
import org.eclipse.riena.ui.ridgets.controller.IController;
import org.eclipse.riena.ui.workarea.IWorkareaDefinition;
import org.eclipse.riena.ui.workarea.WorkareaDefinition;
import org.eclipse.riena.ui.workarea.spi.IWorkareaDefinitionRegistry;
public final class WorkareaDefinitionRegistryFacade implements IWorkareaDefinitionRegistry, ServiceTrackerCustomizer {
private final static SingletonProvider<WorkareaDefinitionRegistryFacade> WDRF = new SingletonProvider<WorkareaDefinitionRegistryFacade>(
WorkareaDefinitionRegistryFacade.class);
private final SortedSet<WorkareaDefinitionRegistryWithRank> contributedRegistries;
public static WorkareaDefinitionRegistryFacade getInstance() {
return WDRF.getInstance();
}
private WorkareaDefinitionRegistryFacade() {
contributedRegistries = new TreeSet<WorkareaDefinitionRegistryWithRank>();
registerExplicitDefinitionRegistry();
}
/**
* {@inheritDoc}
*/
public IWorkareaDefinition getDefinition(final Object id) {
for (final IWorkareaDefinitionRegistry registry : contributedRegistries) {
IWorkareaDefinition definition = registry.getDefinition(id);
if (definition != null) {
return definition;
}
if (id instanceof INavigationNode<?>) {
final INavigationNode<?> node = (INavigationNode<?>) id;
if (node.getNodeId() != null && node.getNodeId().getTypeId() != null) {
definition = registry.getDefinition(node.getNodeId().getTypeId());
if (definition != null) {
return definition;
}
}
}
}
return null;
}
/**
* Creates a workarea definition ({@code IWorkareaDefinition}) with the
* given information and registers it with the specified type ID.
*
* @param id
* type ID
* @param controllerClass
* class of the controller to be used with the view representing
* the working area
* @param viewId
* the id of this work areas view (viewId as contributed to the
* <code>org.eclipse.ui.views</code> extension point)
* @param shared
* <code>true</code> if the view associated with this node should
* be shared, <code>false</code> otherwise
* @return the registered workarea definition
*/
public IWorkareaDefinition registerDefinition(final Object id, final Class<? extends IController> controllerClass,
final Object viewId, final boolean shared) {
final WorkareaDefinition def = new WorkareaDefinition(controllerClass, viewId);
def.setViewShared(shared);
return register(id, def);
}
/**
* {@inheritDoc}
*/
public IWorkareaDefinition register(final Object id, final IWorkareaDefinition definition) {
for (final IWorkareaDefinitionRegistry registry : contributedRegistries) {
final IWorkareaDefinition def = registry.register(id, definition);
if (def != null) {
return def;
}
}
return null;
}
private void registerExplicitDefinitionRegistry() {
final BundleContext context = Activator.getDefault().getBundle().getBundleContext();
final IWorkareaDefinitionRegistry registry = ExplicitWorkareaDefinitionRegistry.getInstance();
final Hashtable<String, Object> props = new Hashtable<String, Object>();
props.put(Constants.SERVICE_RANKING, 100);
context.registerService(IWorkareaDefinitionRegistry.class.getName(), registry, props);
}
/**
* {@inheritDoc}
*/
public Object addingService(final ServiceReference reference) {
// get service and increase use count
final BundleContext bundleContext = Activator.getDefault().getBundle().getBundleContext();
final IWorkareaDefinitionRegistry registry = (IWorkareaDefinitionRegistry) bundleContext.getService(reference);
// add registry
contributedRegistries.add(createEntry(reference, registry));
return registry;
}
/**
* {@inheritDoc}
*/
public void modifiedService(final ServiceReference reference, final Object service) {
// maybe ranking has changed
final WorkareaDefinitionRegistryWithRank entry = createEntry(reference, service);
contributedRegistries.remove(entry);
contributedRegistries.add(entry);
}
/**
* {@inheritDoc}
*/
public void removedService(final ServiceReference reference, final Object service) {
// remove registry
//Object rankingProperty = reference.getProperty(Constants.SERVICE_RANKING);
contributedRegistries.remove(createEntry(reference, service));
// unget service and decrease use count
final BundleContext bundleContext = Activator.getDefault().getBundle().getBundleContext();
bundleContext.ungetService(reference);
}
private WorkareaDefinitionRegistryWithRank createEntry(final ServiceReference reference, final Object registry) {
final Object rankingProperty = reference.getProperty(Constants.SERVICE_RANKING);
final int ranking = (rankingProperty instanceof Integer) ? ((Integer) rankingProperty).intValue() : 0;
return new WorkareaDefinitionRegistryWithRank(ranking, (IWorkareaDefinitionRegistry) registry);
}
private static class WorkareaDefinitionRegistryWithRank implements IWorkareaDefinitionRegistry,
Comparable<WorkareaDefinitionRegistryWithRank> {
private final int ranking;
private final IWorkareaDefinitionRegistry registry;
WorkareaDefinitionRegistryWithRank(final int ranking, final IWorkareaDefinitionRegistry registry) {
this.ranking = ranking;
this.registry = registry;
}
public int getRanking() {
return ranking;
}
public IWorkareaDefinitionRegistry getRegistry() {
return registry;
}
/**
* @see org.eclipse.riena.ui.workarea.spi.IWorkareaDefinitionRegistry#
* getDefinition(Object)
*/
public IWorkareaDefinition getDefinition(final Object id) {
return registry.getDefinition(id);
}
/**
* @see org.eclipse.riena.ui.workarea.spi.IWorkareaDefinitionRegistry#register
* (java.lang.Object)
*/
public IWorkareaDefinition register(final Object id, final IWorkareaDefinition definition) {
return registry.register(id, definition);
}
/**
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
public int compareTo(final WorkareaDefinitionRegistryWithRank other) {
if (this.getRanking() != other.getRanking()) {
return this.getRanking() > other.getRanking() ? -1 : 1;
}
return 0;
}
@Override
public boolean equals(final Object other) {
if (other instanceof WorkareaDefinitionRegistryWithRank) {
return registry.equals(((WorkareaDefinitionRegistryWithRank) other).getRegistry());
} else {
return registry.equals(other);
}
}
@Override
public int hashCode() {
return registry.hashCode();
}
}
}