/******************************************************************************* * Copyright (c) 2008-2010 Sonatype, Inc. * 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: * Sonatype, Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.m2e.core.ui.internal.views; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.eclipse.core.resources.WorkspaceJob; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; 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.TreeViewer; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Menu; import org.eclipse.ui.IActionBars; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.BaseSelectionListenerAction; import org.eclipse.ui.part.DrillDownAdapter; import org.eclipse.ui.part.ViewPart; import org.eclipse.m2e.core.MavenPlugin; import org.eclipse.m2e.core.internal.index.IndexListener; import org.eclipse.m2e.core.internal.index.IndexManager; import org.eclipse.m2e.core.internal.index.IndexedArtifact; import org.eclipse.m2e.core.internal.index.IndexedArtifactFile; import org.eclipse.m2e.core.internal.index.nexus.IndexedArtifactGroup; import org.eclipse.m2e.core.internal.index.nexus.NexusIndex; import org.eclipse.m2e.core.repository.IRepository; import org.eclipse.m2e.core.ui.internal.M2EUIPluginActivator; import org.eclipse.m2e.core.ui.internal.MavenImages; import org.eclipse.m2e.core.ui.internal.Messages; import org.eclipse.m2e.core.ui.internal.actions.OpenPomAction; import org.eclipse.m2e.core.ui.internal.util.M2EUIUtils; import org.eclipse.m2e.core.ui.internal.views.nodes.AbstractIndexedRepositoryNode; import org.eclipse.m2e.core.ui.internal.views.nodes.IArtifactNode; import org.eclipse.m2e.core.ui.internal.views.nodes.IndexedArtifactFileNode; import org.eclipse.m2e.core.ui.internal.views.nodes.LocalRepositoryNode; import org.eclipse.m2e.core.ui.internal.views.nodes.RepositoryNode; /** * Maven repository view * * @author dyocum */ @SuppressWarnings("restriction") public class MavenRepositoryView extends ViewPart { /** * */ private static final String MENU_OPEN_GRP = "open"; /** * */ private static final String MENU_UPDATE_GRP = "update"; private static final Logger log = LoggerFactory.getLogger(MavenRepositoryView.class); private static final String ENABLE_FULL = Messages.MavenRepositoryView_enable_full; private static final String ENABLED_FULL = Messages.MavenRepositoryView_enabled_full; private static final String DISABLE_DETAILS = Messages.MavenRepositoryView_disable_details; private static final String DISABLED_DETAILS = Messages.MavenRepositoryView_details_disabled; private static final String ENABLE_MIN = Messages.MavenRepositoryView_enable_minimum; private static final String ENABLED_MIN = Messages.MavenRepositoryView_minimum_enabled; private static final String MENU_ID = ".repositoryViewMenu"; //$NON-NLS-1$ private IndexManager indexManager = MavenPlugin.getIndexManager(); private IAction collapseAllAction; private IAction reloadSettings; BaseSelectionListenerAction openPomAction; private BaseSelectionListenerAction updateAction; private BaseSelectionListenerAction rebuildAction; private DisableIndexAction disableAction; private EnableMinIndexAction enableMinAction; private EnableFullIndexAction enableFullAction; private BaseSelectionListenerAction copyUrlAction; //private BaseSelectionListenerAction materializeProjectAction; TreeViewer viewer; private RepositoryViewContentProvider contentProvider; private DrillDownAdapter drillDownAdapter; private IndexListener indexListener; public void setFocus() { viewer.getControl().setFocus(); } public void createPartControl(Composite parent) { viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); contentProvider = new RepositoryViewContentProvider(); viewer.setContentProvider(contentProvider); RepositoryViewLabelProvider labelProvider = new RepositoryViewLabelProvider(viewer.getTree().getFont()); viewer.setLabelProvider(new DecoratingStyledCellLabelProvider(labelProvider, PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator(), null)); viewer.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { } }); viewer.setInput(getViewSite()); drillDownAdapter = new DrillDownAdapter(viewer); makeActions(); hookContextMenu(); viewer.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { openPomAction.run(); } }); contributeToActionBars(); this.indexListener = new IndexListener() { public void indexAdded(IRepository repository) { refreshView(); } public void indexChanged(IRepository repository) { refreshView(); } public void indexRemoved(IRepository repository) { refreshView(); } public void indexUpdating(IRepository repository) { Display.getDefault().asyncExec(new Runnable() { public void run() { viewer.refresh(true); } }); } }; indexManager.addIndexListener(this.indexListener); } private void hookContextMenu() { MenuManager menuMgr = new MenuManager("#PopupMenu-" + MENU_ID); //$NON-NLS-1$ menuMgr.setRemoveAllWhenShown(true); menuMgr.addMenuListener(new IMenuListener() { public void menuAboutToShow(IMenuManager manager) { MavenRepositoryView.this.fillContextMenu(manager); manager.update(); } }); Menu menu = menuMgr.createContextMenu(viewer.getControl()); viewer.getControl().setMenu(menu); getSite().registerContextMenu(M2EUIPluginActivator.PLUGIN_ID + MENU_ID, menuMgr, viewer); } private void contributeToActionBars() { IActionBars bars = getViewSite().getActionBars(); fillLocalPullDown(bars.getMenuManager()); fillLocalToolBar(bars.getToolBarManager()); } private void fillLocalPullDown(IMenuManager manager) { manager.add(new Separator()); manager.add(collapseAllAction); manager.add(reloadSettings); } protected List<AbstractIndexedRepositoryNode> getSelectedRepositoryNodes(List<?> elements) { ArrayList<AbstractIndexedRepositoryNode> list = new ArrayList<AbstractIndexedRepositoryNode>(); if(elements != null) { for(int i = 0; i < elements.size(); i++ ) { Object elem = elements.get(i); if(elem instanceof AbstractIndexedRepositoryNode) { list.add((AbstractIndexedRepositoryNode) elem); } } } return list; } protected List<IArtifactNode> getArtifactNodes(List<?> elements) { if(elements == null || elements.size() == 0) { return null; } ArrayList<IArtifactNode> list = new ArrayList<IArtifactNode>(); for(int i = 0; i < elements.size(); i++ ) { Object elem = elements.get(i); if(elem instanceof IArtifactNode) { IArtifactNode node = (IArtifactNode) elem; list.add(node); } } return list; } void fillContextMenu(IMenuManager manager) { manager.add(new Separator(MENU_OPEN_GRP)); manager.add(new Separator(MENU_UPDATE_GRP)); manager.add(new Separator("import")); //$NON-NLS-1$ manager.prependToGroup(MENU_OPEN_GRP, copyUrlAction); manager.prependToGroup(MENU_OPEN_GRP, openPomAction); manager.prependToGroup(MENU_UPDATE_GRP, updateAction); manager.prependToGroup(MENU_UPDATE_GRP, rebuildAction); manager.add(disableAction); manager.add(enableMinAction); manager.add(enableFullAction); manager.add(new Separator()); manager.add(collapseAllAction); manager.add(new Separator()); drillDownAdapter.addNavigationActions(manager); manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); } private void fillLocalToolBar(IToolBarManager manager) { manager.add(new Separator()); manager.add(collapseAllAction); manager.add(reloadSettings); manager.add(new Separator()); drillDownAdapter.addNavigationActions(manager); } private void makeActions() { collapseAllAction = new Action(Messages.MavenRepositoryView_btnCollapse) { public void run() { viewer.collapseAll(); } }; collapseAllAction.setToolTipText(Messages.MavenRepositoryView_btnCollapse_tooltip); collapseAllAction.setImageDescriptor( PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ELCL_COLLAPSEALL)); reloadSettings = new Action(Messages.MavenRepositoryView_action_reload) { public void run() { String msg = Messages.MavenRepositoryView_reload_msg; boolean res = MessageDialog.openConfirm(getViewSite().getShell(), // Messages.MavenRepositoryView_reload_title, msg); if(res) { Job job = new WorkspaceJob(Messages.MavenRepositoryView_job_reloading) { public IStatus runInWorkspace(IProgressMonitor monitor) { try { MavenPlugin.getMaven().reloadSettings(); } catch(CoreException ex) { return ex.getStatus(); } return Status.OK_STATUS; } }; job.schedule(); } } }; reloadSettings.setImageDescriptor(MavenImages.REFRESH); // deleteFromLocalAction = new BaseSelectionListenerAction("Delete from Repository") { // public void run() { // List<IArtifactNode> nodes = getArtifactNodes(getStructuredSelection().toList()); // if(nodes != null){ // for(IArtifactNode node : nodes){ // String key = node.getDocumentKey(); // System.out.println("key: "+key); // ((NexusIndexManager)MavenPlugin.getIndexManager()).removeDocument("local", null, key); // } // } // } // // protected boolean updateSelection(IStructuredSelection selection) { // List<IArtifactNode> nodes = getArtifactNodes(getStructuredSelection().toList()); // return (nodes != null && nodes.size() > 0); // } // }; // deleteFromLocalAction.setToolTipText("Delete the selected GAV from the local repository"); //updateAction.setImageDescriptor(MavenImages.UPD_INDEX); updateAction = new BaseSelectionListenerAction(Messages.MavenRepositoryView_action_update) { public void run() { List<AbstractIndexedRepositoryNode> nodes = getSelectedRepositoryNodes(getStructuredSelection().toList()); for(AbstractIndexedRepositoryNode node : nodes) { if(node instanceof RepositoryNode) { ((RepositoryNode) node).getIndex().scheduleIndexUpdate(false); } } } protected boolean updateSelection(IStructuredSelection selection) { int indexCount = 0; for(AbstractIndexedRepositoryNode node : getSelectedRepositoryNodes(selection.toList())) { if(node instanceof RepositoryNode && node.isEnabledIndex()) { indexCount++ ; } } if(indexCount > 1) { setText(Messages.MavenRepositoryView_update_more); } else { setText(Messages.MavenRepositoryView_update_one); } return indexCount > 0; } }; updateAction.setToolTipText(Messages.MavenRepositoryView_btnUpdate_tooltip); updateAction.setImageDescriptor(MavenImages.UPD_INDEX); rebuildAction = new BaseSelectionListenerAction(Messages.MavenRepositoryView_action_rebuild) { public void run() { new Job(Messages.MavenRepositoryView_rebuild_indexes) { protected IStatus run(IProgressMonitor monitor) { // Remove the index listener to avoid locking the user interface indexManager.removeIndexListener(indexListener); try { List<AbstractIndexedRepositoryNode> nodes = getSelectedRepositoryNodes(getStructuredSelection().toList()); if(nodes.size() > 0) { final String title = nodes.size() == 1 ? Messages.MavenRepositoryView_rebuild_title : Messages.MavenRepositoryView_rebuild_title; final String msg = nodes.size() == 1 ? NLS.bind(Messages.MavenRepositoryView_rebuild_msg, nodes.get(0).getIndex().getRepositoryUrl()) : Messages.MavenRepositoryView_rebuild_msg2; final boolean result[] = new boolean[1]; Display.getDefault().syncExec(new Runnable() { public void run() { result[0] = MessageDialog.openConfirm(getViewSite().getShell(), title, msg); } }); if(result[0]) { SubMonitor mon = SubMonitor.convert(monitor, nodes.size()); try { for(AbstractIndexedRepositoryNode node : nodes) { NexusIndex index = node.getIndex(); if(index != null) { try { index.updateIndex(true, mon.newChild(1)); } catch(CoreException ex) { log.error(ex.getMessage(), ex); } } else { mon.worked(1); } } } finally { mon.done(); } } } return Status.OK_STATUS; } finally { indexManager.addIndexListener(indexListener); refreshView(); } } }.schedule(); } protected boolean updateSelection(IStructuredSelection selection) { int indexCount = 0; for(AbstractIndexedRepositoryNode node : getSelectedRepositoryNodes(selection.toList())) { if((node instanceof LocalRepositoryNode) || node.isEnabledIndex()) { indexCount++ ; } } if(indexCount > 1) { setText(Messages.MavenRepositoryView_rebuild_many); } else { setText(Messages.MavenRepositoryView_rebuild_one); } return indexCount > 0; } }; rebuildAction.setToolTipText(Messages.MavenRepositoryView_action_rebuild_tooltip); rebuildAction.setImageDescriptor(MavenImages.REBUILD_INDEX); disableAction = new DisableIndexAction(); disableAction.setToolTipText(Messages.MavenRepositoryView_action_disable_tooltip); disableAction.setImageDescriptor(MavenImages.REBUILD_INDEX); enableMinAction = new EnableMinIndexAction(); enableMinAction.setToolTipText(Messages.MavenRepositoryView_action_enable_tooltip); enableMinAction.setImageDescriptor(MavenImages.REBUILD_INDEX); enableFullAction = new EnableFullIndexAction(); enableFullAction.setToolTipText(Messages.MavenRepositoryView_action_enableFull_tooltip); enableFullAction.setImageDescriptor(MavenImages.REBUILD_INDEX); openPomAction = new BaseSelectionListenerAction(Messages.MavenRepositoryView_action_open) { public void run() { ISelection selection = viewer.getSelection(); Object element = ((IStructuredSelection) selection).getFirstElement(); if(element instanceof IndexedArtifactFileNode) { IndexedArtifactFile f = ((IndexedArtifactFileNode) element).getIndexedArtifactFile(); OpenPomAction.openEditor(f.group, f.artifact, f.version, null); } } protected boolean updateSelection(IStructuredSelection selection) { return selection.getFirstElement() instanceof IndexedArtifactFileNode; } }; openPomAction.setToolTipText(Messages.MavenRepositoryView_action_open_tooltip); openPomAction.setImageDescriptor(MavenImages.POM); copyUrlAction = new BaseSelectionListenerAction(Messages.MavenRepositoryView_action_copy) { public void run() { Object element = getStructuredSelection().getFirstElement(); String url = null; if(element instanceof RepositoryNode) { url = ((RepositoryNode) element).getRepositoryUrl(); } else if(element instanceof IndexedArtifactGroup) { IndexedArtifactGroup group = (IndexedArtifactGroup) element; String repositoryUrl = group.getRepository().getUrl(); if(!repositoryUrl.endsWith("/")) { //$NON-NLS-1$ repositoryUrl += "/"; //$NON-NLS-1$ } url = repositoryUrl + group.getPrefix().replace('.', '/'); } else if(element instanceof IndexedArtifact) { // } else if(element instanceof IndexedArtifactFile) { // } if(url != null) { Clipboard clipboard = new Clipboard(Display.getCurrent()); clipboard.setContents(new String[] {url}, new Transfer[] {TextTransfer.getInstance()}); clipboard.dispose(); } } protected boolean updateSelection(IStructuredSelection selection) { Object element = selection.getFirstElement(); return element instanceof RepositoryNode || element instanceof IndexedArtifactGroup; } }; copyUrlAction.setToolTipText(Messages.MavenRepositoryView_action_copy_tooltip); copyUrlAction.setImageDescriptor( PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_COPY)); // materializeProjectAction = new BaseSelectionListenerAction(Messages.MavenRepositoryView_action_materialize) { // public void run() { // Object element = getStructuredSelection().getFirstElement(); // if(element instanceof IndexedArtifactFileNode){ // MaterializeAction action = new MaterializeAction(); // StructuredSelection sel = new StructuredSelection(new Object[]{((IndexedArtifactFileNode) element).getIndexedArtifactFile()}); // action.selectionChanged(this, sel); // action.run(this); // } // } // // protected boolean updateSelection(IStructuredSelection selection) { // return selection.getFirstElement() instanceof IndexedArtifactFileNode; // } // }; // materializeProjectAction.setImageDescriptor(MavenImages.IMPORT_PROJECT); viewer.addSelectionChangedListener(openPomAction); viewer.addSelectionChangedListener(updateAction); viewer.addSelectionChangedListener(disableAction); viewer.addSelectionChangedListener(enableMinAction); viewer.addSelectionChangedListener(enableFullAction); viewer.addSelectionChangedListener(rebuildAction); viewer.addSelectionChangedListener(copyUrlAction); // viewer.addSelectionChangedListener(materializeProjectAction); } protected void setIndexDetails(AbstractIndexedRepositoryNode node, String details) { if(node != null && node.getIndex() != null) { try { node.getIndex().setIndexDetails(details); } catch(CoreException ex) { M2EUIUtils.showErrorDialog(this.getViewSite().getShell(), Messages.MavenRepositoryView_error_title, Messages.MavenRepositoryView_error_message, ex); } } } protected AbstractIndexedRepositoryNode getSelectedRepositoryNode(IStructuredSelection selection) { List<?> elements = selection.toList(); if(elements.size() != 1) { return null; } Object element = elements.get(0); return element instanceof AbstractIndexedRepositoryNode ? (AbstractIndexedRepositoryNode) element : null; } public void dispose() { // viewer.removeSelectionChangedListener(materializeProjectAction); viewer.removeSelectionChangedListener(copyUrlAction); viewer.removeSelectionChangedListener(rebuildAction); viewer.removeSelectionChangedListener(disableAction); viewer.removeSelectionChangedListener(enableMinAction); viewer.removeSelectionChangedListener(enableFullAction); viewer.removeSelectionChangedListener(updateAction); viewer.removeSelectionChangedListener(openPomAction); indexManager.removeIndexListener(this.indexListener); super.dispose(); } void refreshView() { Display.getDefault().asyncExec(new Runnable() { public void run() { Object[] expandedElems = viewer.getExpandedElements(); if(!viewer.getControl().isDisposed()) { viewer.setInput(getViewSite()); if(expandedElems != null && expandedElems.length > 0) { viewer.setExpandedElements(expandedElems); } } } }); }; /** * Base Selection Listener does not allow the style (radio button/check) to be set. This base class listens to * selections and sets the appropriate index value depending on its value AbstractIndexAction * * @author dyocum */ abstract class AbstractIndexAction extends Action implements ISelectionChangedListener { protected abstract String getDetailsValue(); protected abstract String getActionText(); public AbstractIndexAction(String text, int style) { super(text, style); } public void run() { IStructuredSelection sel = (IStructuredSelection) viewer.getSelection(); setIndexDetails(getSelectedRepositoryNode(sel), getDetailsValue()); } /* */ public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection sel = (IStructuredSelection) event.getSelection(); updateSelection(sel); } protected void updateSelection(IStructuredSelection selection) { AbstractIndexedRepositoryNode node = getSelectedRepositoryNode(selection); updateIndexDetails(node); setText(getActionText()); boolean enabled = (node != null && node instanceof RepositoryNode); this.setEnabled(enabled); } protected void updateIndexDetails(AbstractIndexedRepositoryNode node) { if(node == null || node.getIndex() == null) { return; } NexusIndex index = node.getIndex(); setChecked(getDetailsValue().equals(index.getIndexDetails())); } } class DisableIndexAction extends AbstractIndexAction { public DisableIndexAction() { super(DISABLE_DETAILS, IAction.AS_CHECK_BOX); } protected String getDetailsValue() { return NexusIndex.DETAILS_DISABLED; } protected String getActionText() { return isChecked() ? DISABLED_DETAILS : DISABLE_DETAILS; } } class EnableMinIndexAction extends AbstractIndexAction { public EnableMinIndexAction() { super(ENABLE_MIN, IAction.AS_CHECK_BOX); } protected String getDetailsValue() { return NexusIndex.DETAILS_MIN; } protected String getActionText() { return isChecked() ? ENABLED_MIN : ENABLE_MIN; } } class EnableFullIndexAction extends AbstractIndexAction { public EnableFullIndexAction() { super(ENABLE_FULL, IAction.AS_CHECK_BOX); } protected String getDetailsValue() { return NexusIndex.DETAILS_FULL; } protected String getActionText() { return isChecked() ? ENABLED_FULL : ENABLE_FULL; } } }