/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.extension.ui.editors; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.ui.IWorkbenchPart; import org.teiid.designer.extension.definition.ModelExtensionDefinition; import org.teiid.designer.extension.properties.ModelExtensionPropertyDefinition; import org.teiid.designer.extension.ui.model.MedModelNode; /** * The * <code>MedSelectionSynchronizer<code> synchronizes selection between the MED editor and other views displaying MED information. */ public class MedSelectionSynchronizer implements ISelectionChangedListener, PropertyChangeListener { private IStructuredSelection currentSelection = StructuredSelection.EMPTY; private final ModelExtensionDefinitionEditor medEditor; private ModelExtensionDefinition med; private MedModelNode medNode; private final List<MedSelectionProvider> selectionProviders = new ArrayList<MedSelectionProvider>(5); /** * @param medEditor the editor where selection synchronization originates (cannot be <code>null</code>) */ public MedSelectionSynchronizer( ModelExtensionDefinitionEditor medEditor ) { this.medEditor = medEditor; setMed(this.medEditor.getMed()); } /** * @param selectionProvider the provider being added (cannot be <code>null</code>) * @return <code>true</code> if successfully registered */ public boolean addSelectionProvider( MedSelectionProvider selectionProvider ) { boolean added = false; if (!this.selectionProviders.contains(selectionProvider)) { added = this.selectionProviders.add(selectionProvider); if (added) { selectionProvider.addSelectionChangedListener(this); selectionProvider.setSelection(this.currentSelection); } } return added; } /** * Removes all selection listeners. */ public void dispose() { for (MedSelectionProvider selectionProvider : this.selectionProviders) { selectionProvider.removeSelectionChangedListener(this); } } /** * @return the MED description model node (never <code>null</code>) */ public MedModelNode getDescriptionNode() { return getMedModelNode().getDescriptionNode(); } /** * @return the MED model node (never <code>null</code>) */ public MedModelNode getMedModelNode() { return this.medNode; } /** * @param metaclass the metaclass whose model node is being requested (cannot be <code>null</code>) * @return the MED metaclass model node or <code>null</code> if not found */ public MedModelNode getMetaclassNode( String metaclass ) { return getMedModelNode().getMetaclassNode(metaclass); } /** * @return the MED metamodel URI model node (never <code>null</code>) */ public MedModelNode getMetamodelUriNode() { return getMedModelNode().getMetamodelUriNode(); } /** * @return the MED model types model node (never <code>null</code>) */ public MedModelNode getModelTypesNode() { return getMedModelNode().getModelTypesNode(); } /** * @return the MED namespace prefix model node (never <code>null</code>) */ public MedModelNode getNamespacePrefixNode() { return getMedModelNode().getNamespacePrefixNode(); } /** * @return the MED namespace prefix model node (never <code>null</code>) */ public MedModelNode getNamespaceUriNode() { return getMedModelNode().getNamespaceUriNode(); } /** * @param metaclass the metaclass whose property definition model node is being requested (cannot be <code>null</code>) * @param propDefn the property definition whose model node is being requested (cannot be <code>null</code>) * @return the MED property definition model node or <code>null</code> if not found */ public MedModelNode getPropertyDefinitionNode( String metaclass, ModelExtensionPropertyDefinition propDefn ) { return getMedModelNode().getPropertyDefinitionNode(metaclass, propDefn); } /** * @return the current selection that is being synchronized (never <code>null</code>) */ public IStructuredSelection getSelection() { return this.currentSelection; } /** * @return the MED version model node (never <code>null</code>) */ public MedModelNode getVersionNode() { return getMedModelNode().getVersionNode(); } private boolean isSynchronized() { // TODO maybe could hook this up to a preference value return true; } /** * {@inheritDoc} * * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent) */ @Override public void propertyChange( PropertyChangeEvent e ) { this.medNode = MedModelNode.createMedNode(this.med); // for now recreate model each time // inform selection providers of the change for (MedSelectionProvider selectionProvider : this.selectionProviders) { selectionProvider.refresh(); } } /** * @param selectionProvider the selection provider being removed from receiving selection events (cannot be <code>null</code>) * @return <code>true</code> if successfully removed */ public boolean removeSelectionProvider( MedSelectionProvider selectionProvider ) { boolean removed = this.selectionProviders.remove(selectionProvider); if (removed) { selectionProvider.removeSelectionChangedListener(this); } return removed; } /** * {@inheritDoc} * * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent) */ @Override public void selectionChanged( SelectionChangedEvent event ) { if (isSynchronized()) { MedSelectionProvider source = (MedSelectionProvider)event.getSelectionProvider(); ISelection newSelection = event.getSelection(); if (newSelection instanceof IStructuredSelection) { this.currentSelection = (IStructuredSelection)newSelection; // inform selection providers of selection for (MedSelectionProvider selectionProvider : this.selectionProviders) { // don't pass event to source if (selectionProvider != source) { if (selectionProvider.isApplicable(this.currentSelection)) { selectionProvider.setSelection(newSelection); // change the editor tab if necessary MedEditorPage page = selectionProvider.getMedEditorPage(); if (page != null) { IWorkbenchPart part = this.medEditor.getSite().getPage().getActivePart(); this.medEditor.selectPage(page); // set focus back to the part that had focus before sync'ing selection if (part != this.medEditor) { part.setFocus(); } } break; // just pass to first provider that accepts } } } } } } /** * @param newMed the MED whose selection synchronization needs to be managed (never <code>null</code>) */ void setMed( ModelExtensionDefinition newMed ) { if (this.med != null) { this.med.removeListener(this); } this.med = newMed; this.medNode = MedModelNode.createMedNode(this.med); this.med.addListener(this); for (MedSelectionProvider selectionProvider : this.selectionProviders) { selectionProvider.refresh(); } } }