blob: 3073899bed526b0b90f044db7b385a469ef8cbb5 [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 IBM Corporation 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:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.search.ui.internal;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.epf.common.xml.AbstractSAXParser;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.edit.util.ModelStructure;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.search.ui.SearchUIPlugin;
import org.eclipse.epf.search.ui.SearchUIResources;
import org.eclipse.epf.uma.Artifact;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.ContentPackage;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.Discipline;
import org.eclipse.epf.uma.Domain;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.Practice;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessElement;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.util.UmaUtil;
import org.xml.sax.Attributes;
/**
* Performs a method search by iterating the current method library and parsing
* the content element XMI files where necessary.
*
* @author Kelvin Low
* @author Phong Nguyen Le
* @since 1.0
*/
public class MethodSearchOperation implements IMethodSearchOperation {
private static final String SCAN_LIBRARY_TEXT = SearchUIResources.scanLibraryTask_name;
private static final String SCAN_ELEMENT_TEXT = SearchUIResources.scanElementTask_name;
private boolean debug;
protected MethodSearchInput searchInput;
private ISearchResultCollector result;
private String searchString;
private boolean caseSensitive;
private boolean regExp;
private Pattern searchStringPattern;
private Pattern elementNamePattern;
private MethodElementScanner elementScanner;
private List<String> parsedFiles = new ArrayList<String>();
private IProgressMonitor progressMonitor;
// Scans the content element XMI file associated with a Method element to
// look for the search string.
private class MethodElementScanner extends AbstractSAXParser {
private MethodElement element;
/**
* Creates a new instance.
*/
public MethodElementScanner() {
super(null, false);
}
/**
* Parses the content XMI file associated with the given Method element.
*
* @param element
* a method element
*/
public void parse(MethodElement element) {
this.element = element;
String elementContentPath = getElementPath(element);
String briefDescription = element.getBriefDescription();
if (searchStringPattern.matcher(briefDescription).find()) {
result.accept(element);
}
if (elementContentPath != null
&& !parsedFiles.contains(elementContentPath)) {
super.parse(elementContentPath);
parsedFiles.add(elementContentPath);
}
}
/**
* @see AbstractSAXParser#startElement(String, String, String,
* Attributes)
*/
public void startElement(String namespaceURL, String localName,
String qname, Attributes attributes) {
for (int i = 0; i < attributes.getLength(); i++) {
String name = attributes.getQName(i);
if (!name.equals("briefDescription")) { //$NON-NLS-1$
String value = attributes.getValue(i);
if (searchStringPattern.matcher(value).find()) {
result.accept(element);
}
}
}
}
/**
* @see AbstractSAXParser#endElement(String, String, String)
*/
public void endElement(String namespaceURL, String localName,
String qname) {
String value = strBuf.toString();
if (searchStringPattern.matcher(value).find()) {
result.accept(element);
}
strBuf.setLength(0);
}
}
/**
* Creates a new instance.
*
* @param searchString
* a search string
* @param namePattern
* a name pattern
* @param result
* a search result collector
*/
public MethodSearchOperation(MethodSearchInput searchInput,
ISearchResultCollector result) {
initialize(searchInput, result);
}
public MethodSearchOperation() {
}
private void initialize(MethodSearchInput searchInput,
ISearchResultCollector result) {
this.searchInput = searchInput;
this.result = result;
caseSensitive = searchInput.getCaseSensitive();
regExp = searchInput.getRegularExpression();
elementNamePattern = MethodSearchPattern.createPattern(searchInput
.getNamePattern(), false, false);
debug = SearchUIPlugin.getDefault().isDebugging();
searchString = searchInput.getSearchString();
if (searchString == null)
searchString = ""; //$NON-NLS-1$
if (searchString.length() > 0) {
elementScanner = new MethodElementScanner();
searchStringPattern = MethodSearchPattern.createPattern(
searchString, caseSensitive, regExp);
}
if (debug) {
System.out
.println("MethodSearchOperation constructor: searchString=" //$NON-NLS-1$
+ searchString
+ ", elementNamePattern=" //$NON-NLS-1$
+ searchInput.getNamePattern()
+ ", caseSensitive=" + caseSensitive); //$NON-NLS-1$
}
}
protected Collection<MethodPlugin> getSearchableMethodPlugins() {
return LibraryUtil.getMethodPlugins(LibraryService.getInstance().getCurrentMethodLibrary());
}
/**
* Executes the search operation.
*
* @param progressMonitor
* a progress monitor
*/
public void execute(IProgressMonitor progressMonitor) {
this.progressMonitor = progressMonitor;
this.progressMonitor.beginTask(SCAN_LIBRARY_TEXT, 7500);
// Iterate the Method Plugin to look for elements that match the name
// pattern.
Collection<MethodPlugin> methodPlugins = getSearchableMethodPlugins();
for (Iterator<MethodPlugin> i = methodPlugins.iterator(); i.hasNext()
&& !progressMonitor.isCanceled();) {
MethodPlugin methodPlugin = (MethodPlugin) i.next();
matchPattern(methodPlugin);
MethodPackage methodPackage;
if (searchInput.getSearchScope().includeCoreContent()) {
methodPackage = UmaUtil.findMethodPackage(methodPlugin,
ModelStructure.DEFAULT.coreContentPath);
searchMethodPackages(methodPackage);
}
if (searchInput.getSearchScope().include(
MethodSearchScope.STANDARD_CATEGORY)) {
methodPackage = UmaUtil.findMethodPackage(methodPlugin,
ModelStructure.DEFAULT.disciplineDefinitionPath);
searchMethodPackages(methodPackage);
methodPackage = UmaUtil.findMethodPackage(methodPlugin,
ModelStructure.DEFAULT.domainPath);
searchMethodPackages(methodPackage);
methodPackage = UmaUtil.findMethodPackage(methodPlugin,
ModelStructure.DEFAULT.workProductTypePath);
searchMethodPackages(methodPackage);
methodPackage = UmaUtil.findMethodPackage(methodPlugin,
ModelStructure.DEFAULT.roleSetPath);
searchMethodPackages(methodPackage);
methodPackage = UmaUtil.findMethodPackage(methodPlugin,
ModelStructure.DEFAULT.toolPath);
searchMethodPackages(methodPackage);
}
if (searchInput.getSearchScope().include(
MethodSearchScope.CUSTOM_CATEGORY)) {
methodPackage = UmaUtil.findMethodPackage(methodPlugin,
ModelStructure.DEFAULT.customCategoryPath);
searchMethodPackages(methodPackage);
}
if (searchInput.getSearchScope().include(
MethodSearchScope.CAPABILITY_PATTERN)) {
methodPackage = UmaUtil.findMethodPackage(methodPlugin,
ModelStructure.DEFAULT.capabilityPatternPath);
searchMethodPackages(methodPackage);
}
if (searchInput.getSearchScope().include(
MethodSearchScope.DELIVERY_PROCESS)) {
methodPackage = UmaUtil.findMethodPackage(methodPlugin,
ModelStructure.DEFAULT.deliveryProcessPath);
searchMethodPackages(methodPackage);
}
}
}
/**
* Searches a Method Package.
*
* @param methodPackage
* a method package
*/
protected void searchMethodPackages(MethodPackage methodPackage) {
if (methodPackage == null
|| methodPackage.getName().equals(
ModelStructure.HIDDEN_PACKAGE_NAME)) {
return;
}
if (methodPackage instanceof ProcessComponent) {
// Add the associated CapabilityPattern or DeliveryProcess to the
// search result.
ProcessComponent processComponent = (ProcessComponent) methodPackage;
matchPattern(processComponent.getProcess());
} else if (!isInternalProcessPackage(methodPackage)) {
matchPattern(methodPackage);
}
List childPackages = methodPackage.getChildPackages();
for (Iterator i = childPackages.iterator(); i.hasNext()
&& !progressMonitor.isCanceled();) {
searchMethodPackages((MethodPackage) i.next());
}
if (methodPackage instanceof ContentPackage) {
ContentPackage contentPackage = (ContentPackage) methodPackage;
List contentElements = contentPackage.getContentElements();
for (Iterator j = contentElements.iterator(); j.hasNext()
&& !progressMonitor.isCanceled();) {
ContentElement contentElement = (ContentElement) j.next();
matchPattern(contentElement);
if (contentElement instanceof Artifact) {
searchContainedArtifacts((Artifact) contentElement);
} else if (contentElement instanceof Discipline) {
searchSubDisciplines((Discipline) contentElement);
} else if (contentElement instanceof Practice) {
searchSubPractices((Practice) contentElement);
} else if (contentElement instanceof Domain) {
searchSubDomains((Domain) contentElement);
}
}
} else if (methodPackage instanceof ProcessPackage) {
ProcessPackage processPackage = (ProcessPackage) methodPackage;
List processElements = processPackage.getProcessElements();
for (Iterator j = processElements.iterator(); j.hasNext()
&& !progressMonitor.isCanceled();) {
ProcessElement processElement = (ProcessElement) j.next();
// if (!(processElement instanceof Activity)) {
matchPattern(processElement);
// }
}
}
}
/**
* Returns <code>true</code> if the given package is an internal Process
* Package.
*
* @param methodPackage
* a method or process package
* @return <code>true</code> if the given package is an internal process
* package
*/
protected boolean isInternalProcessPackage(MethodPackage methodPackage) {
if (methodPackage instanceof ProcessPackage) {
if (UmaUtil.getProcessComponent(methodPackage) != null) {
return true;
}
}
return false;
}
/**
* Searches the contained artifacts of an artifact.
*
* @param artifact
* an artifact
*/
protected void searchContainedArtifacts(Artifact artifact) {
if (artifact != null) {
for (Iterator i = artifact.getContainedArtifacts().iterator(); i
.hasNext()
&& !progressMonitor.isCanceled();) {
Artifact containedArtifact = (Artifact) i.next();
matchPattern(containedArtifact);
searchContainedArtifacts(containedArtifact);
}
}
}
/**
* Searches the sub disciplines of a discipline.
*
* @param discipline
* a discipline
*/
protected void searchSubDisciplines(Discipline discipline) {
if (discipline != null) {
for (Iterator i = discipline.getSubdiscipline().iterator(); i
.hasNext()
&& !progressMonitor.isCanceled();) {
Discipline subDiscipline = (Discipline) i.next();
matchPattern(subDiscipline);
searchSubDisciplines(subDiscipline);
}
}
}
/**
* Searches the sub practices of a practice.
*
* @param practice
* a practice
*/
protected void searchSubPractices(Practice practice) {
if (practice != null) {
for (Iterator i = practice.getSubPractices().iterator(); i
.hasNext()
&& !progressMonitor.isCanceled();) {
Practice subPractice = (Practice) i.next();
matchPattern(subPractice);
searchSubPractices(subPractice);
}
}
}
/**
* Searches the sub domains of a domain.
*
* @param domain
* a domain
*/
protected void searchSubDomains(Domain domain) {
if (domain != null) {
for (Iterator i = domain.getSubdomains().iterator(); i.hasNext()
&& !progressMonitor.isCanceled();) {
Domain subDomain = (Domain) i.next();
matchPattern(subDomain);
searchSubDomains(subDomain);
}
}
}
/**
* Adds the given method element to the search result collection if its name
* or presentation name matches the name pattern.
*
* @param element
* a method element
*/
protected void matchPattern(MethodElement element) {
try {
if (searchInput.getSearchScope().include(element)) {
String name = element.getName();
String taskName = MessageFormat.format(SCAN_ELEMENT_TEXT,
new Object[] { name });
progressMonitor.setTaskName(taskName);
boolean foundMatch = false;
if (element instanceof DescribableElement) {
String presentationName = ((DescribableElement) element)
.getPresentationName();
foundMatch = (name != null && elementNamePattern.matcher(
name).matches())
|| (presentationName != null && elementNamePattern
.matcher(presentationName).matches());
} else {
foundMatch = (name != null && elementNamePattern.matcher(
name).matches());
}
if (foundMatch) {
if (searchString.length() == 0) {
result.accept(element);
} else {
try {
elementScanner.parse(element);
} catch (Exception e) {
e.printStackTrace();
}
}
}
progressMonitor.worked(1);
}
} catch (Exception e) {
SearchUIPlugin.getDefault().getLogger().logError(e);
}
}
/**
* Returns the path of the content XML file associated with a method
* element.
*/
protected String getElementPath(MethodElement element) {
Resource resource = null;
if (element instanceof DescribableElement) {
DescribableElement describableElement = (DescribableElement) element;
ContentDescription contentDescription = describableElement
.getPresentation();
if (contentDescription == null) {
return null;
}
resource = contentDescription.eResource();
} else {
resource = element.eResource();
}
if (resource != null) {
URI resourceURI = resource.getURI();
if (resourceURI != null) {
return resourceURI.toFileString();
}
}
return null;
}
public void execute(MethodSearchInput searchInput,
ISearchResultCollector result, IProgressMonitor monitor) {
initialize(searchInput, result);
execute(monitor);
}
}