| //------------------------------------------------------------------------------ |
| // 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 && !searchString.equals("*")) { //$NON-NLS-1$ |
| 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 || searchString.equals("*")) { //$NON-NLS-1$ |
| 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); |
| } |
| |
| } |