001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.ui.editor.text;
011:
012: import java.net.URL;
013:
014: import org.eclipse.jface.text.BadLocationException;
015: import org.eclipse.jface.text.IRegion;
016: import org.eclipse.jface.text.ITextViewer;
017: import org.eclipse.pde.core.plugin.IPluginAttribute;
018: import org.eclipse.pde.core.plugin.IPluginElement;
019: import org.eclipse.pde.core.plugin.IPluginExtension;
020: import org.eclipse.pde.core.plugin.IPluginExtensionPoint;
021: import org.eclipse.pde.core.plugin.IPluginObject;
022: import org.eclipse.pde.internal.core.PDECore;
023: import org.eclipse.pde.internal.core.ischema.ISchema;
024: import org.eclipse.pde.internal.core.ischema.ISchemaAttribute;
025: import org.eclipse.pde.internal.core.ischema.ISchemaElement;
026: import org.eclipse.pde.internal.core.ischema.ISchemaObject;
027: import org.eclipse.pde.internal.core.schema.SchemaAnnotationHandler;
028: import org.eclipse.pde.internal.core.text.IDocumentAttributeNode;
029: import org.eclipse.pde.internal.core.text.IDocumentElementNode;
030: import org.eclipse.pde.internal.core.text.IDocumentRange;
031: import org.eclipse.pde.internal.core.text.IDocumentTextNode;
032: import org.eclipse.pde.internal.core.util.SchemaUtil;
033: import org.eclipse.pde.internal.core.util.XMLComponentRegistry;
034: import org.eclipse.pde.internal.ui.editor.PDESourcePage;
035:
036: public class PluginXMLTextHover extends PDETextHover {
037:
038: private PDESourcePage fSourcePage;
039:
040: public PluginXMLTextHover(PDESourcePage sourcePage) {
041: fSourcePage = sourcePage;
042: }
043:
044: public String getHoverInfo(ITextViewer textViewer,
045: IRegion hoverRegion) {
046: int offset = hoverRegion.getOffset();
047: IDocumentRange range = fSourcePage
048: .getRangeElement(offset, true);
049: if (range instanceof IDocumentTextNode)
050: return checkTranslatedValue((IDocumentTextNode) range);
051: if (!(range instanceof IPluginObject))
052: return null;
053:
054: ISchema schema = getExtensionSchema((IPluginObject) range);
055: if (schema != null) {
056: ISchemaObject sObj = getSchemaObject(schema,
057: (IPluginObject) range);
058: if (sObj == null) {
059: return null;
060: } else if (range instanceof IPluginAttribute
061: && sObj instanceof ISchemaElement) {
062: IDocumentAttributeNode da = (IDocumentAttributeNode) range;
063: if (da.getNameOffset() <= offset
064: && offset <= da.getNameOffset()
065: + da.getNameLength() - 1)
066: // inside name
067: return getAttributeText((IPluginAttribute) range,
068: (ISchemaElement) sObj);
069: else if (da.getValueOffset() <= offset
070: && offset <= da.getValueOffset()
071: + da.getValueLength() - 1)
072: // inside value
073: return getAttributeValueText(
074: (IPluginAttribute) range,
075: (ISchemaElement) sObj);
076: } else if (range instanceof IPluginElement) {
077: IDocumentElementNode dn = (IDocumentElementNode) range;
078: int dnOff = dn.getOffset();
079: int dnLen = dn.getLength();
080: String dnName = dn.getXMLTagName();
081: if (dnOff + 1 <= offset
082: && offset <= dnOff + dnName.length())
083: // inside opening tag
084: return getElementText((ISchemaElement) sObj);
085: try {
086: String nt = textViewer.getDocument().get(dnOff,
087: dnLen);
088: if (nt.endsWith("</" + dnName + '>')) { //$NON-NLS-1$
089: offset = offset - dnOff;
090: if (nt.length() - dnName.length() - 1 <= offset
091: && offset <= nt.length() - 2)
092: // inside closing tag
093: return getElementText((ISchemaElement) sObj);
094: }
095: } catch (BadLocationException e) {
096: }
097: }
098: } else if (range instanceof IDocumentAttributeNode
099: && ((IDocumentAttributeNode) range)
100: .getEnclosingElement() instanceof IPluginExtensionPoint)
101: return getExtensionPointHoverInfo((IPluginObject) range,
102: offset);
103:
104: return null;
105: }
106:
107: private String getExtensionPointHoverInfo(IPluginObject object,
108: int offset) {
109: IDocumentAttributeNode da = (IDocumentAttributeNode) object;
110: if (da.getValueOffset() <= offset
111: && offset <= da.getValueOffset() + da.getValueLength()
112: - 1) {
113: String value = da.getAttributeValue();
114: if (da.getAttributeName().equals(IPluginObject.P_NAME)
115: && value.startsWith("%")) //$NON-NLS-1$
116: return object.getResourceString(value);
117: }
118: return null;
119:
120: }
121:
122: private ISchema getExtensionSchema(IPluginObject object) {
123: IPluginObject extension = object;
124: if (object instanceof IDocumentAttributeNode)
125: extension = (IPluginObject) ((IDocumentAttributeNode) object)
126: .getEnclosingElement();
127: while (extension != null
128: && !(extension instanceof IPluginExtension))
129: extension = extension.getParent();
130:
131: if (extension == null)
132: // started off outside of an extension element
133: return null;
134:
135: String point = ((IPluginExtension) extension).getPoint();
136: return PDECore.getDefault().getSchemaRegistry()
137: .getSchema(point);
138: }
139:
140: private ISchemaObject getSchemaObject(ISchema schema,
141: IPluginObject object) {
142: if (object instanceof IPluginElement)
143: return schema.findElement(((IPluginElement) object)
144: .getName());
145: if (object instanceof IPluginExtension)
146: return schema.findElement("extension"); //$NON-NLS-1$
147: if (object instanceof IDocumentAttributeNode)
148: return schema.findElement(((IDocumentAttributeNode) object)
149: .getEnclosingElement().getXMLTagName());
150: return null;
151: }
152:
153: private String getAttributeText(IPluginAttribute attrib,
154: ISchemaElement sEle) {
155: ISchemaAttribute sAtt = sEle.getAttribute(attrib.getName());
156: if (sAtt == null)
157: return null;
158: return sAtt.getDescription();
159: }
160:
161: private String getAttributeValueText(IPluginAttribute attrib,
162: ISchemaElement sEle) {
163: if (sEle.getName().equals("extension") && //$NON-NLS-1$
164: attrib.getName().equals(IPluginExtension.P_POINT))
165: return getSchemaDescription(attrib, sEle);
166: ISchemaAttribute sAtt = sEle.getAttribute(attrib.getName());
167: if (sAtt == null)
168: return null;
169:
170: String value = attrib.getValue();
171: if (sAtt.isTranslatable() && value.startsWith("%")) //$NON-NLS-1$
172: return attrib.getResourceString(value);
173: return null;
174: }
175:
176: private String getSchemaDescription(IPluginAttribute attr,
177: ISchemaElement sEle) {
178: String description = XMLComponentRegistry.Instance()
179: .getDescription(attr.getValue(),
180: XMLComponentRegistry.F_SCHEMA_COMPONENT);
181:
182: if (description == null) {
183: URL url = sEle.getSchema().getURL();
184: SchemaAnnotationHandler handler = new SchemaAnnotationHandler();
185: SchemaUtil.parseURL(url, handler);
186: description = handler.getDescription();
187: XMLComponentRegistry.Instance().putDescription(
188: attr.getValue(), description,
189: XMLComponentRegistry.F_SCHEMA_COMPONENT);
190: }
191: return description;
192: }
193:
194: private String getElementText(ISchemaElement sEle) {
195: if (sEle == null) {
196: return null;
197: }
198: return sEle.getDescription();
199: }
200:
201: private String checkTranslatedValue(IDocumentTextNode node) {
202: String value = node.getText();
203: if (value.startsWith("%")) //$NON-NLS-1$
204: return ((IPluginObject) node.getEnclosingElement())
205: .getResourceString(value);
206:
207: return null;
208: }
209: }
|