Community
Participate
Working Groups
I've been trying to use existing action and new task wizards with specialized reporting functionality but apparently the current implementation of NewTaskAction is internal and it also have certain limitations in around supported selection types. So I'd like to suggest some improvements for TasksUiUtil.getSelectedRepository(): - support additional selection types, such as IAdaptable to TaskRepository and/or AbstractTask (to allow 3rd party plugins to adapt their objects to those) - when selection is empty, can also check if current editor is a Task Editor and use its repository (not really related to my integration, but I think it would be convenient, though Task Editor may have to participate with platfor selection service). I can submit patch for the adaptables if that would help to get this functionality in Mylyn faster.
Not exactly related to the TasksUiUtil.getSelectedRepository(), but new task wizards (including clone and create new task from selection) should also preselect repositories, and projects/products based on the data from TaskSelection. I can work on a patch for desired functionality if that would help.
That is tracked on bug 165910.
Eugene: could you please outline what you would like the contract of the method to be, and any changes in signature? Writing a comment with the Javadoc in it is probably the best way to do that.
Mik, contract stays the same and no change in the signatures, so I don't think it is really an API. Here is the "pseudo java code" that should illustrate what is being suggested. Let me know if you require additional details. /** * Returns TaskRepository retrieved from the current selection. * * The following elements stored in selection can be used to retrieve associated repository: * * <ul> * <li>TaskRepository * <li>AbstractRepositoryQuery * <li>AbstractTask * <li>IResource * <li>IAdaptable or adapter factory available from Platform.getAdapterManager().getAdapter() * <ul> * <li>IResource * <li>TaskRepository * <li>AbstractTask * <li>TaskSelection * </ul> * <li>Task repository associated with the currently active TaskEditor retrieved using * PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor() * </ul> * * @param viewer a viewer used to retrieve selection from, if null then * workbench window's selection service is used * * @return TaskRepository instance retrieved from the current selection */ public static TaskRepository getSelectedRepository(StructuredViewer viewer) { IStructuredSelection selection = null; if (viewer != null) { selection = (IStructuredSelection) viewer.getSelection(); } if (selection == null || selection.isEmpty()) { IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); ISelection windowSelection = window.getSelectionService().getSelection(); if (windowSelection instanceof IStructuredSelection) { selection = (IStructuredSelection) windowSelection; } } if (selection == null) { return null; } Object element = selection.getFirstElement(); if (element instanceof TaskRepository) { return (TaskRepository) selection.getFirstElement(); } else if (element instanceof AbstractRepositoryQuery) { AbstractRepositoryQuery query = (AbstractRepositoryQuery) element; return TasksUiPlugin.getRepositoryManager().getRepository(query.getRepositoryKind(), query.getRepositoryUrl()); } else if (element instanceof AbstractTask) { AbstractTask task = (AbstractTask) element; return TasksUiPlugin.getRepositoryManager().getRepository(task.getConnectorKind(), task.getRepositoryUrl()); } else if (element instanceof IResource) { IResource resource = (IResource) element; return TasksUiPlugin.getDefault().getRepositoryForResource(resource, true); } else { IResource resource = (IResource) getAdapter(element, IResource.class); if (resource != null) { return TasksUiPlugin.getDefault().getRepositoryForResource(resource, true); } AbstractTask task = (AbstractTask) getAdapter(element, AbstractTask.class); if (task != null) { return TasksUiPlugin.getRepositoryManager().getRepository(task.getConnectorKind(), task.getRepositoryUrl()); } TaskRepository repository = (TaskRepository) getAdapter(element, TaskRepository.class); if (repository != null) { return repository; } TaskSelection taskSelection = (TaskSelection) getAdapter(element, TaskSelection.class); if (taskSelection != null) { RepositoryTaskData taskData = taskSelection.getTaskData(); if (taskData != null) { return TasksUiPlugin.getRepositoryManager().getRepository(taskData.getRepositoryKind(), taskData.getRepositoryUrl()); } } } IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if(window!=null) { IWorkbenchPage activePage = window.getActivePage(); if(activePage!=null) { IEditorPart activeEditor = activePage.getActiveEditor(); if(activeEditor instanceof TaskEditor) { AbstractTask task = ((TaskEditor) activeEditor).getTaskEditorInput().getTask(); if(task!=null) { return TasksUiPlugin.getRepositoryManager().getRepository(task.getConnectorKind(), task.getRepositoryUrl()); } } } } // TODO mapping between LogEntry.pliginId and repositories // TODO handle other selection types return null; } private static Object getAdapter(Object adaptable, Class<?> adapterType) { if(adaptable instanceof IAdaptable) { Object adapter = ((IAdaptable) adaptable).getAdapter(adapterType); if(adapter!=null) { return adapter; } } return Platform.getAdapterManager().getAdapter(adaptable, adapterType); }
Created attachment 86427 [details] mylyn/context/zip
Steffen: please review.
Created attachment 87736 [details] pseudo code as patch Patch looks good. Eugene, could you provide a test case for the added adapters and querying of the active task editor?
(In reply to comment #7) > Patch looks good. Eugene, could you provide a test case for the added adapters > and querying of the active task editor? Umm. There is no adapters in Mylyn code, but perhaps test plugin could add something and then pass dummy StructuredViewer, but I have no idea where to start with testing active task editor. An example would help.
Please add a test for the case where the viewer selection is empty and the workbench selection is empty. That causes a NPE with the current patch.
(In reply to comment #9) > Please add a test for the case where the viewer selection is empty and the > workbench selection is empty. That causes a NPE with the current patch. Steffen, please read comment #8
Created attachment 88195 [details] updated patch and failing test case
Created attachment 88196 [details] mylyn/context/zip
Steffen, it would be more helpful to actually get my question from comment #8 answered. Reassigning to me without answering questions don't really help resolving issues. Besides, last time I checked, it is not your responsibility [1], so please stop assigning issues to me, especially without asking first. Thank you in advance. [1] http://wiki.eclipse.org/Mylyn#Mentors
I get an NPE when I try to create a task and a new JIRA task editor is currently active. It looks like TaskEditor.getTaskEditorInput() returns null in that case: java.lang.NullPointerException at org.eclipse.mylyn.tasks.ui.TasksUiUtil.getSelectedRepository(TasksUiUtil.java:578) at org.eclipse.mylyn.internal.tasks.ui.wizards.SelectRepositoryPage.createTableViewer(SelectRepositoryPage.java:161) at org.eclipse.mylyn.internal.tasks.ui.wizards.SelectRepositoryPage.createControl(SelectRepositoryPage.java:113) at org.eclipse.jface.wizard.Wizard.createPageControls(Wizard.java:170) at org.eclipse.jface.wizard.WizardDialog.createPageControls(WizardDialog.java:669) at org.eclipse.jface.wizard.WizardDialog.createContents(WizardDialog.java:543) at org.eclipse.jface.window.Window.create(Window.java:431) at org.eclipse.jface.dialogs.Dialog.create(Dialog.java:1088) at org.eclipse.mylyn.tasks.ui.TasksUiUtil.openNewTaskEditor(TasksUiUtil.java:692) at org.eclipse.mylyn.tasks.ui.TasksUiUtil.openNewTaskEditor(TasksUiUtil.java:683) at org.eclipse.mylyn.internal.tasks.ui.actions.NewTaskAction.run(NewTaskAction.java:46) at org.eclipse.mylyn.internal.tasks.ui.actions.NewTaskAction.run(NewTaskAction.java:53) at org.eclipse.ui.internal.PluginAction.runWithEvent(PluginAction.java:251) at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:582) at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:499) at org.eclipse.jface.action.ActionContributionItem$6.handleEvent(ActionContributionItem.java:451) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1145) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3335) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2982) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2392) at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2356) at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2222) at org.eclipse.ui.internal.Workbench$4.run(Workbench.java:474) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:288) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:469) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149) at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:106) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:193) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:106) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:76) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:362) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:175) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:564) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:504) at org.eclipse.equinox.launcher.Main.run(Main.java:1251) at org.eclipse.equinox.launcher.Main.main(Main.java:1227)
(In reply to comment #14) > I get an NPE when I try to create a task and a new JIRA task editor is > currently active. It looks like TaskEditor.getTaskEditorInput() returns null in > that case... Should we continue testing this manually or tests suggested on comment Comment #7 are doable? There is actually some variety of possible selections, i.e. when some web browser editor is active, etc...
Steffen: if this shouldn't be tagged as [api] maybe we should tag it as [framework]? I would like us to have a quick way of distinguishing framework/api requests from end-user requests.
So far most of the bugs tagged as [api] either requested new API or changes to existing API whereas this bug proposes new functionality without breaking API. I am okay with a [framework] tag for distinguishing internal implementation changes from "user visible" changes.
Technically, if method behavior is changed, even without changing its signature it is still an api change as it may break other applications. Though form the practical point of view, in this case risk of breaking anything is very unlike, but benefits are significant.
Created attachment 91484 [details] updated patch
Mylyn has been restructured, and our issue tracking has moved to GitHub [1]. We are closing ~14K Bugzilla issues to give the new team a fresh start. If you feel that this issue is still relevant, please create a new one on GitHub. [1] https://github.com/orgs/eclipse-mylyn