blob: 89284fe0de123eca43fef125729b56f9c904fb75 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014 Hussein Mhanna
*
* 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:
* Hussein Mhanna - initial API and implementation
******************************************************************************/
package org.eclipse.rmf.reqif10.search.ui;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.emf.edit.ui.util.EditUIUtil;
import org.eclipse.jface.dialogs.DialogPage;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.rmf.reqif10.pror.editor.IReqifEditor;
import org.eclipse.rmf.reqif10.pror.editor.presentation.Reqif10Editor;
import org.eclipse.rmf.reqif10.search.criteria.Criteria;
import org.eclipse.rmf.reqif10.search.edit.util.ReqIFEditSearcher;
import org.eclipse.rmf.reqif10.search.ui.masterdetails.CriteriasMasterDetailsBlock;
import org.eclipse.search.ui.IReplacePage;
import org.eclipse.search.ui.ISearchPage;
import org.eclipse.search.ui.ISearchPageContainer;
import org.eclipse.search.ui.ISearchQuery;
import org.eclipse.search.ui.NewSearchUI;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.ManagedForm;
public class ReqIFSearchPage extends DialogPage implements ISearchPage,
IReplacePage {
private static final String REQIF_EXTENSION = "reqif";
private ISearchPageContainer container;
private CriteriasMasterDetailsBlock masterDetailsBlock;
public ReqIFSearchPage() {
}
@Override
public void createControl(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL,
true, true));
composite.setLayout(new FillLayout());
IManagedForm managedForm = new ManagedForm(composite);
masterDetailsBlock = new CriteriasMasterDetailsBlock();
masterDetailsBlock.createContent(managedForm);
container.setPerformActionEnabled(true);
setControl(parent);
}
private List<IResource> getResources() {
IResource[] resources = new IResource[0];
switch (container.getSelectedScope()) {
case ISearchPageContainer.SELECTION_SCOPE:
Object[] objects = ((IStructuredSelection) (container
.getSelection())).toArray();
Set<IResource> resList = new HashSet<IResource>(objects.length);
for (Object object : objects) {
if (object instanceof IResource) {
resList.add((IResource) object);
} else if (object instanceof EObject) {
EObject eObject = (EObject) object;
Resource eResource = eObject.eResource();
if (eResource != null) {
URI eUri = eResource.getURI();
if (eUri.isPlatformResource()) {
String platformString = eUri.toPlatformString(true);
IResource resource = ResourcesPlugin.getWorkspace()
.getRoot().findMember(platformString);
resList.add(resource);
}
}
}
}
resources = resList.toArray(new IResource[0]);
break;
case ISearchPageContainer.WORKSPACE_SCOPE:
resources = ResourcesPlugin.getWorkspace().getRoot().getProjects();
break;
case ISearchPageContainer.WORKING_SET_SCOPE:
resources = convertToResources(container.getSelectedWorkingSets());
break;
}
return getReqIFResources(resources);
}
private List<IResource> getReqIFResources(IResource[] resources) {
List<IResource> reqIFResources = new ArrayList<IResource>();
for (IResource resource : resources) {
if (resource instanceof IFile
&& resource.getFileExtension() != null
&& resource.getFileExtension().equals(REQIF_EXTENSION)) {
reqIFResources.add(resource);
} else if (resource instanceof IContainer) {
try {
reqIFResources
.addAll(getReqIFResources(((IContainer) resource)
.members()));
} catch (CoreException e) {
e.printStackTrace();
}
}
}
return reqIFResources;
}
private static IResource[] convertToResources(IWorkingSet[] workingSets) {
List<IResource> res = new ArrayList<IResource>();
for (int i = 0; i < workingSets.length; i++) {
IWorkingSet workingSet = workingSets[i];
if (workingSet.isAggregateWorkingSet() && workingSet.isEmpty()) {
return new IResource[] { ResourcesPlugin.getWorkspace()
.getRoot() };
}
IAdaptable[] elements = workingSet.getElements();
for (int k = 0; k < elements.length; k++) {
IResource curr = (IResource) elements[k]
.getAdapter(IResource.class);
if (curr != null) {
res.add(curr);
}
}
}
return (IResource[]) res.toArray(new IResource[res.size()]);
}
final void updateOKStatus() {
container.setPerformActionEnabled(true);
}
public Map<URI, EditingDomain> getEditorsURIMap() {
final Map<URI, EditingDomain> uriMap = new HashMap<URI, EditingDomain>();
PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
@Override
public void run() {
IEditorReference[] editorReferences = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow().getActivePage()
.getEditorReferences();
for (IEditorReference editorReference : editorReferences) {
IEditorPart editorPart = editorReference.getEditor(false);
if (editorPart instanceof IReqifEditor) {
try {
uriMap.put(EditUIUtil.getURI(editorReference
.getEditorInput()),
((IEditingDomainProvider) editorPart)
.getEditingDomain());
} catch (PartInitException e) {
e.printStackTrace();
}
}
}
}
});
return uriMap;
}
public List<Resource> getEMFResources(Map<URI, EditingDomain> uriMap) {
ResourceSet resourceSet = new ResourceSetImpl();
List<IResource> resources = getResources();
List<Resource> emfResources = new ArrayList<Resource>();
for (IResource resource : resources) {
URI uri = URI.createPlatformResourceURI(resource.getFullPath()
.toOSString(), true);
EditingDomain editingDomain = uriMap.get(uri);
if (editingDomain != null) {
emfResources.addAll(editingDomain.getResourceSet()
.getResources());
} else {
Resource emfResource = resourceSet.getResource(uri, true);
if (emfResource != null) {
emfResources.add(emfResource);
}
}
}
return emfResources;
}
@Override
public boolean performReplace() {
IRunnableWithProgress runnable = new IRunnableWithProgress() {
@Override
public void run(final IProgressMonitor monitor)
throws InvocationTargetException, InterruptedException {
monitor.beginTask("Start Searching ...",
IProgressMonitor.UNKNOWN);
final Map<URI, EditingDomain> uriMap = getEditorsURIMap();
final List<Resource> resources = getEMFResources(uriMap);
ExtendedReqIFEdit reqIFEditSearcher = new ExtendedReqIFEdit(
uriMap);
reqIFEditSearcher.search(monitor, resources,
masterDetailsBlock.getCriterias(), true);
}
};
try {
new ProgressMonitorDialog(getShell()).run(true, true, runnable);
} catch (InvocationTargetException e) {
ReqIFSearchUIPlugin.getPlugin().log(e);
} catch (InterruptedException e) {
ReqIFSearchUIPlugin.getPlugin().log(e);
}
return true;
}
@SuppressWarnings("restriction")
@Override
public boolean performAction() {
ISearchQuery query = newQuery();
// Note : In the javadoc its explaned that we need to only call
// NewSearchUI.runQueryInForeground but due to a bug this doesn't work
// so I had to do the code below.
org.eclipse.search2.internal.ui.SearchView searchView = null;
try {
searchView = (org.eclipse.search2.internal.ui.SearchView) PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getActivePage()
.showView(NewSearchUI.SEARCH_VIEW_ID);
} catch (final PartInitException e) {
ReqIFSearchUIPlugin.INSTANCE.log(e);
}
NewSearchUI.runQueryInForeground(new ProgressMonitorDialog(getShell()),
query);
if (searchView != null) {
searchView.showSearchResult(query.getSearchResult());
}
return true;
}
private ISearchQuery newQuery() {
return new ReqIFSearchQuery(this,
masterDetailsBlock.getCriterias());
}
@Override
public void setContainer(ISearchPageContainer container) {
this.container = container;
}
protected class ExtendedReqIFEdit extends ReqIFEditSearcher {
private final Map<URI, EditingDomain> uriMap;
public ExtendedReqIFEdit(Map<URI, EditingDomain> uriMap) {
this.uriMap = uriMap;
}
@Override
protected Collection<EObject> search(IProgressMonitor monitor,
Resource resource, Collection<Criteria> criterias,
boolean replace) {
final Map<Object, Object> saveOptions = new HashMap<Object, Object>();
saveOptions.put(Resource.OPTION_SAVE_ONLY_IF_CHANGED,
Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER);
Collection<EObject> result = super.search(monitor, resource,
criterias, replace);
if (false == uriMap.containsKey(resource.getURI())) {
try {
resource.save(saveOptions);
} catch (IOException e) {
ReqIFSearchUIPlugin.getPlugin().log(e);
}
}
return result;
}
public void executeCommand(final EditingDomain editingDomain,
final Command command) {
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
ExtendedReqIFEdit.super.executeCommand(editingDomain,
command);
}
});
}
}
}