blob: 7afe5a8f4660e81e230b727e791cdc1d7484bcd4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 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 API and implementation
*******************************************************************************/
package org.eclipse.wst.xsd.ui.internal.editor.search;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.wst.common.core.search.SearchEngine;
import org.eclipse.wst.common.core.search.SearchMatch;
import org.eclipse.wst.common.core.search.SearchParticipant;
import org.eclipse.wst.common.core.search.SearchPlugin;
import org.eclipse.wst.common.core.search.SearchRequestor;
import org.eclipse.wst.common.core.search.pattern.QualifiedName;
import org.eclipse.wst.common.core.search.pattern.SearchPattern;
import org.eclipse.wst.common.core.search.scope.SearchScope;
import org.eclipse.wst.common.ui.internal.search.dialogs.IComponentList;
import org.eclipse.wst.common.ui.internal.search.dialogs.IComponentSearchListProvider;
import org.eclipse.wst.xml.core.internal.search.XMLComponentDeclarationPattern;
import org.eclipse.wst.xsd.ui.internal.search.IXSDSearchConstants;
import org.eclipse.xsd.XSDAttributeDeclaration;
import org.eclipse.xsd.XSDElementDeclaration;
import org.eclipse.xsd.XSDImport;
import org.eclipse.xsd.XSDInclude;
import org.eclipse.xsd.XSDRedefine;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSchemaContent;
import org.eclipse.xsd.XSDSchemaDirective;
import org.eclipse.xsd.XSDSimpleTypeDefinition;
import org.eclipse.xsd.XSDTypeDefinition;
public abstract class XSDSearchListProvider implements IComponentSearchListProvider
{
protected XSDSchema[] schemas;
protected IFile currentFile;
// TODO (cs) remove these and use proper search scopes!
//
public static final int ENCLOSING_PROJECT_SCOPE = 0;
public static final int ENTIRE_WORKSPACE_SCOPE = 1;
public XSDSearchListProvider(IFile currentFile, XSDSchema[] schemas)
{
this.schemas = schemas;
this.currentFile = currentFile;
try
{
IProject[] refs = currentFile.getProject().getReferencedProjects();
for (int i=0; i < refs.length; i++)
{
System.out.println("dep " + refs[i].getName());
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
class ComponentCollectingXSDVisitor
{
protected List visitedSchemas = new ArrayList();
IComponentList list;
QualifiedName searchKind;
ComponentCollectingXSDVisitor(IComponentList list, QualifiedName searchKind)
{
this.list = list;
this.searchKind = searchKind;
}
public void visitSchema(XSDSchema schema, boolean visitImportedSchema)
{
visitedSchemas.add(schema);
for (Iterator contents = schema.getContents().iterator(); contents.hasNext();)
{
XSDSchemaContent content = (XSDSchemaContent) contents.next();
if (content instanceof XSDSchemaDirective)
{
XSDSchemaDirective schemaDirective = (XSDSchemaDirective) content;
XSDSchema extSchema = schemaDirective.getResolvedSchema();
if (extSchema != null && !visitedSchemas.contains(extSchema))
{
if (schemaDirective instanceof XSDImport && visitImportedSchema)
{
visitSchema(extSchema, false);
}
else if (schemaDirective instanceof XSDInclude || schemaDirective instanceof XSDRedefine)
{
visitSchema(extSchema, false);
}
}
}
else if (content instanceof XSDElementDeclaration && searchKind == IXSDSearchConstants.ELEMENT_META_NAME)
{
list.add(content);
}
else if (content instanceof XSDAttributeDeclaration && searchKind == IXSDSearchConstants.ATTRIBUTE_META_NAME)
{
list.add(content);
}
else if (content instanceof XSDSimpleTypeDefinition && searchKind == IXSDSearchConstants.SIMPLE_TYPE_META_NAME)
{
// in this case we only want to show simple types
list.add(content);
}
else if (content instanceof XSDTypeDefinition && searchKind == IXSDSearchConstants.TYPE_META_NAME)
{
// in this case we want to show all types
list.add(content);
}
}
}
public List getVisitedSchemas()
{
return visitedSchemas;
}
}
class InternalSearchRequestor extends SearchRequestor
{
IComponentList componentList;
HashMap files;
InternalSearchRequestor(IComponentList componentList, HashMap files)
{
this.componentList = componentList;
this.files = files;
}
public void acceptSearchMatch(SearchMatch match) throws CoreException
{
// we filter out the matches from the current file since we assume the
// info derived from our schema models is more update to date
// (in the event that we haven't saved our latest modifications)
//
if (files.get(match.getFile()) == null)
{
// TODO... this ugly qualified name stashing will go away soon
//
QualifiedName qualifiedName = null;
Object o = match.map.get("name");
if (o != null && o instanceof QualifiedName)
{
qualifiedName = (QualifiedName)o;
}
if (qualifiedName != null && qualifiedName.getLocalName() != null)
{
componentList.add(match);
}
}
}
}
protected void findMatches(SearchEngine searchEngine, SearchRequestor requestor, SearchScope scope, QualifiedName metaName)
{
try
{
XMLComponentDeclarationPattern pattern = new XMLComponentDeclarationPattern(new QualifiedName("*", "*"), metaName, SearchPattern.R_PATTERN_MATCH);
// TODO (cs) revist this... we shouldn't be needing to hard-code partipant id's
// All we're really doing here is trying to avoid finding matches in
// wsdl's since we don't ever want to import/include a wsdl from a schema!
// Maybe we should just scope out any file types that aren't xsd's using a
// custom SearchScope?
//
SearchParticipant particpant = SearchPlugin.getDefault().getSearchParticipant("org.eclipse.wst.xsd.search.XSDSearchParticipant");
Assert.isNotNull(particpant);
SearchParticipant[] participants = {particpant};
searchEngine.search(pattern, requestor, participants, scope, null, new NullProgressMonitor());
}
catch (CoreException e)
{
e.printStackTrace();
}
}
protected HashMap createFileMap(List visitedSchemas)
{
HashMap fileMap = new HashMap();
for (Iterator i = visitedSchemas.iterator(); i.hasNext(); )
{
XSDSchema theSchema = (XSDSchema)i.next();
String location = theSchema.getSchemaLocation();
IFile file = computeFile(location);
if (file != null)
{
fileMap.put(file, Boolean.TRUE);
}
}
return fileMap;
}
private IFile computeFile(String baseLocation)
{
IFile file = null;
if (baseLocation != null)
{
String fileScheme = "file:"; //$NON-NLS-1$
String platformResourceScheme = "platform:/resource";
if (baseLocation.startsWith(fileScheme))
{
baseLocation = baseLocation.substring(fileScheme.length());
baseLocation = removeLeading(baseLocation, "/");
IPath path = new Path(baseLocation);
file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
}
else if (baseLocation.startsWith(platformResourceScheme))
{
baseLocation = baseLocation.substring(platformResourceScheme.length());
baseLocation = removeLeading(baseLocation, "/");
IPath path = new Path(baseLocation);
file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
}
}
return file;
}
private String removeLeading(String path, String pattern)
{
while (path.startsWith(pattern))
{
path = path.substring(pattern.length());
}
return path;
}
}