Put back hyperlink classes
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/editor/BaseHyperlinkDetector.java b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/editor/BaseHyperlinkDetector.java new file mode 100644 index 0000000..ca26c9a --- /dev/null +++ b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/editor/BaseHyperlinkDetector.java
@@ -0,0 +1,265 @@ +/******************************************************************************* + * Copyright (c) 2004, 2006 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 + * Jens Lukowski/Innoopract - initial renaming/restructuring + *******************************************************************************/ + +package org.eclipse.wst.xsd.editor; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.hyperlink.IHyperlink; +import org.eclipse.jface.text.hyperlink.IHyperlinkDetector; +import org.eclipse.wst.sse.core.StructuredModelManager; +import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; +import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion; +import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion; +import org.eclipse.wst.sse.core.utils.StringUtils; +import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr; +import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; + +/** + * Base class for hyperlinks detectors. Provides a framework and common code for + * hyperlink detectors. TODO: Can we pull this class further up the inheritance + * hierarchy? + */ +public abstract class BaseHyperlinkDetector implements IHyperlinkDetector +{ + /* + * (non-Javadoc) + */ + public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) + { + if (region == null || textViewer == null) + { + return null; + } + + List hyperlinks = new ArrayList(0); + IDocument document = textViewer.getDocument(); + int offset = region.getOffset(); + + IDOMNode node = getCurrentNode(document, offset); + + // This call allows us to determine whether an attribute is linkable, + // without incurring the cost of asking for the target component. + + if (!isLinkable(node)) + { + return null; + } + + IRegion hyperlinkRegion = getHyperlinkRegion(node); + + // createHyperlink is a template method. Derived classes, should override. + + IHyperlink hyperlink = createHyperlink(document, node, hyperlinkRegion); + + if (hyperlink != null) + { + hyperlinks.add(hyperlink); + } + + if (hyperlinks.size() == 0) + { + return null; + } + + return (IHyperlink[]) hyperlinks.toArray(new IHyperlink[0]); + } + + /** + * Determines whether a node is "linkable" that is, the component it refers to + * can be the target of a "go to definition" navigation. + * + * @param node the node to test, must not be null; + * @return true if the node is linkable, false otherwise. + */ + private boolean isLinkable(IDOMNode node) + { + if (node == null) + { + return false; + } + + short nodeType = node.getNodeType(); + + boolean isLinkable = false; + + if (nodeType == Node.ATTRIBUTE_NODE) + { + IDOMAttr attr = (IDOMAttr) node; + String name = attr.getName(); + + // isLinkableAttribute is a template method. Derived classes should + // override. + + isLinkable = isLinkableAttribute(name); + } + + return isLinkable; + } + + /** + * Determines whether an attribute is "linkable" that is, the component it + * points to can be the target of a "go to definition" navigation. Derived + * classes should override. + * + * @param name the attribute name. Must not be null. + * @return true if the attribute is linkable, false otherwise. + */ + protected abstract boolean isLinkableAttribute(String name); + + /** + * Creates a hyperlink based on the selected node. Derived classes should + * override. + * + * @param document the source document. + * @param node the node under the cursor. + * @param region the text region to use to create the hyperlink. + * @return a new IHyperlink for the node or null if one cannot be created. + */ + protected abstract IHyperlink createHyperlink(IDocument document, IDOMNode node, IRegion region); + + /** + * Locates the attribute node under the cursor. + * + * @param offset the cursor offset. + * @param parent the parent node + * @return an IDOMNode representing the attribute if one is found at the + * offset or null otherwise. + */ + protected IDOMNode getAttributeNode(int offset, IDOMNode parent) + { + IDOMAttr attrNode = null; + NamedNodeMap map = parent.getAttributes(); + + for (int index = 0; index < map.getLength(); index++) + { + attrNode = (IDOMAttr) map.item(index); + boolean located = attrNode.contains(offset); + if (located) + { + if (attrNode.hasNameOnly()) + { + attrNode = null; + } + break; + } + } + + if (attrNode == null) + { + return parent; + } + return attrNode; + } + + /** + * Returns the node the cursor is currently on in the document or null if no + * node is selected + * + * @param offset the current cursor offset. + * @return IDOMNode either element, doctype, text, attribute or null + */ + private IDOMNode getCurrentNode(IDocument document, int offset) + { + IndexedRegion inode = null; + IStructuredModel sModel = null; + + try + { + sModel = StructuredModelManager.getModelManager().getExistingModelForRead(document); + inode = sModel.getIndexedRegion(offset); + if (inode == null) + inode = sModel.getIndexedRegion(offset - 1); + } + finally + { + if (sModel != null) + sModel.releaseFromRead(); + } + + if (inode instanceof IDOMNode) + { + IDOMNode node = (IDOMNode) inode; + + if (node.hasAttributes()) + { + node = getAttributeNode(offset, node); + } + return node; + } + + return null; + } + + /** + * Get the text region corresponding to an IDOMNode. + * + * @param node the node for which we want the text region. Must not be null. + * @return an IRegion for the node, or null if the node is not recognized. + */ + protected IRegion getHyperlinkRegion(IDOMNode node) + { + if (node == null) + { + return null; + } + + IRegion hyperRegion = null; + short nodeType = node.getNodeType(); + + switch (nodeType) + { + case Node.ELEMENT_NODE : + { + hyperRegion = new Region(node.getStartOffset(), node.getEndOffset() - node.getStartOffset()); + } + break; + case Node.ATTRIBUTE_NODE : + { + IDOMAttr att = (IDOMAttr) node; + + int regOffset = att.getValueRegionStartOffset(); + + // ISSUE: We are using a deprecated method here. Is there + // a better way to get what we need? + + ITextRegion valueRegion = att.getValueRegion(); + if (valueRegion != null) + { + int regLength = valueRegion.getTextLength(); + String attValue = att.getValueRegionText(); + + // Do not include quotes in attribute value region. + if (StringUtils.isQuoted(attValue)) + { + regOffset = ++regOffset; + regLength = regLength - 2; + } + hyperRegion = new Region(regOffset, regLength); + } + } + break; + default : + // Do nothing. + break; + } + + return hyperRegion; + } +}
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/editor/Logger.java b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/editor/Logger.java new file mode 100644 index 0000000..a53578c --- /dev/null +++ b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/editor/Logger.java
@@ -0,0 +1,157 @@ +/******************************************************************************* + * Copyright (c) 2001, 2006 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 + * Jens Lukowski/Innoopract - initial renaming/restructuring + * + *******************************************************************************/ +package org.eclipse.wst.xsd.editor; + +import java.util.StringTokenizer; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.osgi.framework.Bundle; + +/** + * Small convenience class to log messages to plugin's log file and also, if + * desired, the console. This class should only be used by classes in this + * plugin. Other plugins should make their own copy, with appropriate ID. + */ +public class Logger { + private static final String PLUGIN_ID = "org.eclipse.wst.xsd.ui"; //$NON-NLS-1$ + + public static final int ERROR = IStatus.ERROR; // 4 + public static final int ERROR_DEBUG = 200 + ERROR; + public static final int INFO = IStatus.INFO; // 1 + public static final int INFO_DEBUG = 200 + INFO; + + public static final int OK = IStatus.OK; // 0 + + public static final int OK_DEBUG = 200 + OK; + + private static final String TRACEFILTER_LOCATION = "/debug/tracefilter"; //$NON-NLS-1$ + public static final int WARNING = IStatus.WARNING; // 2 + public static final int WARNING_DEBUG = 200 + WARNING; + + /** + * Adds message to log. + * + * @param level + * severity level of the message (OK, INFO, WARNING, ERROR, + * OK_DEBUG, INFO_DEBUG, WARNING_DEBUG, ERROR_DEBUG) + * @param message + * text to add to the log + * @param exception + * exception thrown + */ + protected static void _log(int level, String message, Throwable exception) { + if (level == OK_DEBUG || level == INFO_DEBUG || level == WARNING_DEBUG || level == ERROR_DEBUG) { + if (!isDebugging()) + return; + } + + int severity = IStatus.OK; + switch (level) { + case INFO_DEBUG : + case INFO : + severity = IStatus.INFO; + break; + case WARNING_DEBUG : + case WARNING : + severity = IStatus.WARNING; + break; + case ERROR_DEBUG : + case ERROR : + severity = IStatus.ERROR; + } + message = (message != null) ? message : "null"; //$NON-NLS-1$ + Status statusObj = new Status(severity, PLUGIN_ID, severity, message, exception); + Bundle bundle = Platform.getBundle(PLUGIN_ID); + if (bundle != null) + Platform.getLog(bundle).log(statusObj); + } + + /** + * Prints message to log if category matches /debug/tracefilter option. + * + * @param message + * text to print + * @param category + * category of the message, to be compared with + * /debug/tracefilter + */ + protected static void _trace(String category, String message, Throwable exception) { + if (isTracing(category)) { + message = (message != null) ? message : "null"; //$NON-NLS-1$ + Status statusObj = new Status(IStatus.OK, PLUGIN_ID, IStatus.OK, message, exception); + Bundle bundle = Platform.getBundle(PLUGIN_ID); + if (bundle != null) + Platform.getLog(bundle).log(statusObj); + } + } + + /** + * @return true if the platform is debugging + */ + public static boolean isDebugging() { + return Platform.inDebugMode(); + } + + /** + * Determines if currently tracing a category + * + * @param category + * @return true if tracing category, false otherwise + */ + public static boolean isTracing(String category) { + if (!isDebugging()) + return false; + + String traceFilter = Platform.getDebugOption(PLUGIN_ID + TRACEFILTER_LOCATION); + if (traceFilter != null) { + StringTokenizer tokenizer = new StringTokenizer(traceFilter, ","); //$NON-NLS-1$ + while (tokenizer.hasMoreTokens()) { + String cat = tokenizer.nextToken().trim(); + if (category.equals(cat)) { + return true; + } + } + } + return false; + } + + public static void log(int level, String message) { + _log(level, message, null); + } + + public static void log(int level, String message, Throwable exception) { + _log(level, message, exception); + } + + public static void logException(String message, Throwable exception) { + _log(ERROR, message, exception); + } + + public static void logException(Throwable exception) { + _log(ERROR, exception.getMessage(), exception); + } + + public static void trace(String category, String message) { + _trace(category, message, null); + } + + public static void traceException(String category, String message, Throwable exception) { + _trace(category, message, exception); + } + + public static void traceException(String category, Throwable exception) { + _trace(category, exception.getMessage(), exception); + } +}
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/editor/XSDHyperlink.java b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/editor/XSDHyperlink.java new file mode 100644 index 0000000..bd8ee37 --- /dev/null +++ b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/editor/XSDHyperlink.java
@@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2004, 2006 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 + * Jens Lukowski/Innoopract - initial renaming/restructuring + *******************************************************************************/ + +package org.eclipse.wst.xsd.editor; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.hyperlink.IHyperlink; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.ide.IDE; +import org.eclipse.wst.common.uriresolver.internal.util.URIHelper; +import org.eclipse.xsd.XSDConcreteComponent; +import org.eclipse.xsd.XSDSchema; + +/** + * XSDHyperlink knows how to open links from XSD files. + * + * @see XSDHyperlinkDetector + */ +public class XSDHyperlink implements IHyperlink +{ + private IRegion fRegion; + private XSDConcreteComponent fComponent; + + public XSDHyperlink(IRegion region, XSDConcreteComponent component) + { + fRegion = region; + fComponent = component; + } + + public IRegion getHyperlinkRegion() + { + return fRegion; + } + + public String getTypeLabel() + { + return null; + } + + public String getHyperlinkText() + { + return null; + } + + public void open() + { + XSDSchema schema = fComponent.getSchema(); + + if (schema == null) + { + return; + } + + String schemaLocation = schema.getSchemaLocation(); + schemaLocation = URIHelper.removePlatformResourceProtocol(schemaLocation); + IPath schemaPath = new Path(schemaLocation); + IFile schemaFile = ResourcesPlugin.getWorkspace().getRoot().getFile(schemaPath); + + boolean fileExists = schemaFile != null && schemaFile.exists(); + + if (!fileExists) + { + return; + } + IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (workbenchWindow != null) + { + IWorkbenchPage workbenchPage = workbenchWindow.getActivePage(); + IEditorPart editorPart = workbenchPage.getActiveEditor(); + + workbenchPage.getNavigationHistory().markLocation(editorPart); + + try + { + editorPart = IDE.openEditor(workbenchPage, schemaFile, true); + if (editorPart instanceof InternalXSDMultiPageEditor) + { + ((InternalXSDMultiPageEditor) editorPart).openOnGlobalReference(fComponent); + } + } + catch (PartInitException pie) + { + Logger.log(Logger.WARNING_DEBUG, pie.getMessage(), pie); + } + } + } +}
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/editor/XSDHyperlinkDetector.java b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/editor/XSDHyperlinkDetector.java new file mode 100644 index 0000000..7bdfa15 --- /dev/null +++ b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/editor/XSDHyperlinkDetector.java
@@ -0,0 +1,301 @@ +/******************************************************************************* + * Copyright (c) 2004, 2006 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 + * Jens Lukowski/Innoopract - initial renaming/restructuring + *******************************************************************************/ + +package org.eclipse.wst.xsd.editor; + +import java.util.List; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.hyperlink.IHyperlink; +import org.eclipse.wst.sse.core.StructuredModelManager; +import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; +import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument; +import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel; +import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; +import org.eclipse.wst.xsd.ui.internal.text.XSDModelAdapter; +import org.eclipse.xsd.XSDAttributeDeclaration; +import org.eclipse.xsd.XSDAttributeGroupDefinition; +import org.eclipse.xsd.XSDConcreteComponent; +import org.eclipse.xsd.XSDElementDeclaration; +import org.eclipse.xsd.XSDIdentityConstraintDefinition; +import org.eclipse.xsd.XSDModelGroupDefinition; +import org.eclipse.xsd.XSDSchema; +import org.eclipse.xsd.XSDSchemaDirective; +import org.eclipse.xsd.XSDSimpleTypeDefinition; +import org.eclipse.xsd.XSDTypeDefinition; +import org.eclipse.xsd.XSDVariety; +import org.eclipse.xsd.util.XSDConstants; +import org.w3c.dom.Attr; +import org.w3c.dom.Node; + +/** + * Detects hyperlinks for XSD files. Used by the XSD text editor to provide a + * "Go to declaration" functionality similar with the one provided by the Java + * editor. + */ +public class XSDHyperlinkDetector extends BaseHyperlinkDetector +{ + /** + * Determines whether an attribute is "linkable" that is, the component it + * points to can be the target of a "go to definition" navigation. Derived + * classes should override. + * + * @param name the attribute name. Must not be null. + * @return true if the attribute is linkable, false otherwise. + */ + protected boolean isLinkableAttribute(String name) + { + boolean isLinkable = name.equals(XSDConstants.TYPE_ATTRIBUTE) || + name.equals(XSDConstants.REFER_ATTRIBUTE) || + name.equals(XSDConstants.REF_ATTRIBUTE) || + name.equals(XSDConstants.BASE_ATTRIBUTE) || + name.equals(XSDConstants.SCHEMALOCATION_ATTRIBUTE) || + name.equals(XSDConstants.SUBSTITUTIONGROUP_ATTRIBUTE) || + name.equals(XSDConstants.ITEMTYPE_ATTRIBUTE) || + name.equals(XSDConstants.MEMBERTYPES_ATTRIBUTE) + ; + + return isLinkable; + } + + /** + * Creates a hyperlink based on the selected node. Derived classes should + * override. + * + * @param document the source document. + * @param node the node under the cursor. + * @param region the text region to use to create the hyperlink. + * @return a new IHyperlink for the node or null if one cannot be created. + */ + protected IHyperlink createHyperlink(IDocument document, IDOMNode node, IRegion region) + { + XSDSchema xsdSchema = getXSDSchema(document); + + if (xsdSchema == null) + { + return null; + } + + XSDConcreteComponent targetComponent = getTargetXSDComponent(xsdSchema, node); + + if (targetComponent != null) + { + IRegion nodeRegion = getHyperlinkRegion(node); + + return new XSDHyperlink(nodeRegion, targetComponent); + } + + return null; + } + + /** + * Finds the XSD component for the given node. + * + * @param xsdSchema cannot be null + * @param node cannot be null + * @return XSDConcreteComponent + */ + private XSDConcreteComponent getTargetXSDComponent(XSDSchema xsdSchema, IDOMNode node) + { + XSDConcreteComponent component = null; + + XSDConcreteComponent xsdComp = xsdSchema.getCorrespondingComponent((Node) node); + if (xsdComp instanceof XSDElementDeclaration) + { + XSDElementDeclaration elementDecl = (XSDElementDeclaration) xsdComp; + if (elementDecl.isElementDeclarationReference()) + { + component = elementDecl.getResolvedElementDeclaration(); + } + else + { + XSDConcreteComponent typeDef = null; + if (elementDecl.getAnonymousTypeDefinition() == null) + { + typeDef = elementDecl.getTypeDefinition(); + } + + XSDConcreteComponent subGroupAffiliation = elementDecl.getSubstitutionGroupAffiliation(); + + if (typeDef != null && subGroupAffiliation != null) + { + // we have 2 things we can navigate to, if the + // cursor is anywhere on the substitution + // attribute + // then jump to that, otherwise just go to the + // typeDef. + if (node instanceof Attr && ((Attr) node).getLocalName().equals(XSDConstants.SUBSTITUTIONGROUP_ATTRIBUTE)) + { + component = subGroupAffiliation; + } + else + { + // try to reveal the type now. On success, + // then we return true. + // if we fail, set the substitution group + // as + // the object to reveal as a backup plan. + // ISSUE: how to set backup? + // if (revealObject(typeDef)) { + component = typeDef; + // } + // else { + // objectToReveal = subGroupAffiliation; + // } + } + } + else + { + // one or more of these is null. If the + // typeDef is + // non-null, use it. Otherwise + // try and use the substitution group + component = typeDef != null ? typeDef : subGroupAffiliation; + } + } + } + else if (xsdComp instanceof XSDModelGroupDefinition) + { + XSDModelGroupDefinition elementDecl = (XSDModelGroupDefinition) xsdComp; + if (elementDecl.isModelGroupDefinitionReference()) + { + component = elementDecl.getResolvedModelGroupDefinition(); + } + } + else if (xsdComp instanceof XSDAttributeDeclaration) + { + XSDAttributeDeclaration attrDecl = (XSDAttributeDeclaration) xsdComp; + if (attrDecl.isAttributeDeclarationReference()) + { + component = attrDecl.getResolvedAttributeDeclaration(); + } + else if (attrDecl.getAnonymousTypeDefinition() == null) + { + component = attrDecl.getTypeDefinition(); + } + } + else if (xsdComp instanceof XSDAttributeGroupDefinition) + { + XSDAttributeGroupDefinition attrGroupDef = (XSDAttributeGroupDefinition) xsdComp; + if (attrGroupDef.isAttributeGroupDefinitionReference()) + { + component = attrGroupDef.getResolvedAttributeGroupDefinition(); + } + } + else if (xsdComp instanceof XSDIdentityConstraintDefinition) + { + XSDIdentityConstraintDefinition idConstraintDef = (XSDIdentityConstraintDefinition) xsdComp; + if (idConstraintDef.getReferencedKey() != null) + { + component = idConstraintDef.getReferencedKey(); + } + } + else if (xsdComp instanceof XSDSimpleTypeDefinition) + { + XSDSimpleTypeDefinition typeDef = (XSDSimpleTypeDefinition) xsdComp; + + // Simple types can be one of restriction, list or union. + + XSDVariety variety = typeDef.getVariety(); + int varietyType = variety.getValue(); + + switch (varietyType) + { + case XSDVariety.ATOMIC : + { + component = typeDef.getBaseTypeDefinition(); + } + break; + case XSDVariety.LIST : + { + component = typeDef.getItemTypeDefinition(); + } + break; + case XSDVariety.UNION : + { + List memberTypes = typeDef.getMemberTypeDefinitions(); + if (memberTypes != null && memberTypes.size() > 0) + { + // ISSUE: What if there are more than one type? + // This could be a case for multiple hyperlinks at the same + // location. + component = (XSDConcreteComponent) memberTypes.get(0); + } + } + break; + } + } + else if (xsdComp instanceof XSDTypeDefinition) + { + XSDTypeDefinition typeDef = (XSDTypeDefinition) xsdComp; + component = typeDef.getBaseType(); + } + else if (xsdComp instanceof XSDSchemaDirective) + { + XSDSchemaDirective directive = (XSDSchemaDirective) xsdComp; + component = directive.getResolvedSchema(); + } + + // Avoid types located in the schema for schema (the built in XSD types) + // as we don't want to navigate to their definition. + + if (component != null) + { + XSDSchema schema = component.getSchema(); + + if (schema.equals(schema.getSchemaForSchema())) { + component = null; + } + } + + return component; + } + + /** + * Gets the xsd schema from document + * + * @param document + * @return XSDSchema or null of one does not exist yet for document + */ + private XSDSchema getXSDSchema(IDocument document) + { + XSDSchema schema = null; + IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForRead(document); + if (model != null) + { + try + { + if (model instanceof IDOMModel) + { + IDOMDocument domDoc = ((IDOMModel) model).getDocument(); + if (domDoc != null) + { + XSDModelAdapter modelAdapter = (XSDModelAdapter) domDoc.getExistingAdapter(XSDModelAdapter.class); + /* + * ISSUE: Didn't want to go through initializing schema if it does + * not already exist, so just attempted to get existing adapter. If + * doesn't exist, just don't bother working. + */ + if (modelAdapter != null) + schema = modelAdapter.getSchema(); + } + } + } + finally + { + model.releaseFromRead(); + } + } + return schema; + } +}