/*******************************************************************************
* Copyright (c) 2007-2012 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is 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:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.cdi.seam.text.ext.hyperlink;
import java.text.MessageFormat;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.ui.PartInitException;
import org.jboss.tools.cdi.core.CDICoreNature;
import org.jboss.tools.cdi.core.CDICorePlugin;
import org.jboss.tools.cdi.seam.config.core.CDISeamConfigExtension;
import org.jboss.tools.cdi.seam.config.core.definition.SeamBeansDefinition;
import org.jboss.tools.cdi.seam.config.core.definition.SeamFieldDefinition;
import org.jboss.tools.cdi.seam.config.core.definition.SeamMemberDefinition;
import org.jboss.tools.cdi.seam.config.core.definition.SeamMethodDefinition;
import org.jboss.tools.cdi.seam.config.core.util.Util;
import org.jboss.tools.cdi.seam.text.ext.CDISeamExtMessages;
import org.jboss.tools.common.text.ext.hyperlink.AbstractHyperlink;
import org.jboss.tools.common.text.ext.util.StructuredModelWrapper;
import org.jboss.tools.common.text.ext.util.Utils;
import org.jboss.tools.jst.web.ui.internal.text.ext.hyperlink.jsp.JSPRootHyperlinkPartitioner;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* @author Jeremy
*/
public class SeamConfigTagNameHyperlink extends AbstractHyperlink {
/**
* @see com.ibm.sse.editor.AbstractHyperlink#doHyperlink(org.eclipse.jface.text.IRegion)
*/
protected void doHyperlink(IRegion region) {
IFile documentFile = getFile();
if(documentFile == null) return;
IProject project = documentFile.getProject();
CDICoreNature cdi = CDICorePlugin.getCDI(project, true);
if(cdi == null) return;
String tagName = getTagName(region);
if(tagName == null) return;
int at = tagName.indexOf('@');
String attrName = null;
if(at >= 0) {
attrName = tagName.substring(at + 1);
tagName = tagName.substring(0, at);
}
String uri = getURI(region);
IJavaElement element = null;
IType type = Util.resolveType(tagName, uri, cdi);
if(type != null) {
element = type;
if(attrName != null) {
try {
if(type.isAnnotation()) {
IMethod m = type.getMethod(attrName, new String[0]);
if(m != null && m.exists()) element = m;
} else {
IField f = type.getField(attrName);
if(f != null && f.exists()) {
element = f;
}
}
} catch (CoreException e) {
}
}
} else {
SeamMemberDefinition def = find(cdi, region, documentFile);
if(def instanceof SeamFieldDefinition) {
element = ((SeamFieldDefinition)def).getField();
} else if(def instanceof SeamMethodDefinition) {
element = ((SeamMethodDefinition)def).getMethod();
}
}
if(element != null) {
try {
JavaUI.openInEditor(element);
} catch (JavaModelException e) {
} catch (PartInitException e) {
}
}
}
SeamMemberDefinition find(CDICoreNature cdi, IRegion region, IFile documentFile) {
CDISeamConfigExtension ext = CDISeamConfigExtension.getExtension(cdi);
if(ext == null) return null;
SeamBeansDefinition def = ext.getContext().getDefinition(documentFile.getFullPath());
if(def == null) return null;
return def.findExactly(region.getOffset());
}
private IType resolve(IJavaProject jp, String tagName, String uri) {
return null;
}
private String getURI(IRegion region) {
return getURI(region, getDocument());
}
public static String getURI(IRegion region, IDocument document) {
StructuredModelWrapper smw = new StructuredModelWrapper();
smw.init(document);
try {
Document xmlDocument = smw.getDocument();
if (xmlDocument == null) return null;
Node n = Utils.findNodeForOffset(xmlDocument, region.getOffset());
if(n instanceof Attr) {
n = ((Attr)n).getOwnerElement();
}
if (!(n instanceof Element)) return null;
return getURI(n, document, region.getOffset());
} finally {
smw.dispose();
}
}
public static String getURI(Node node, IDocument document, int offset) {
String nodeName = node.getNodeName();
if (nodeName.indexOf(':') == -1) return null;
String nodePrefix = nodeName.substring(0, nodeName.indexOf(":")); //$NON-NLS-1$
if (nodePrefix == null || nodePrefix.length() == 0) return null;
Map trackers = JSPRootHyperlinkPartitioner.getTrackersMap(document, offset);
return (String)(trackers == null ? null : trackers.get(nodePrefix));
}
private String getTagName(IRegion region) {
StructuredModelWrapper smw = new StructuredModelWrapper();
smw.init(getDocument());
try {
Document xmlDocument = smw.getDocument();
if (xmlDocument == null) return null;
Node node = Utils.findNodeForOffset(xmlDocument, region.getOffset());
Attr attr = null;
Element elem = null;
if (node instanceof Element) {
elem = (Element)node;
} else if(node instanceof Attr) {
attr = (Attr)node;
elem = attr.getOwnerElement();
}
if(elem == null) return null;
String tagName = elem.getNodeName();
if (tagName.indexOf(':') == -1) return null;
tagName = tagName.substring(tagName.indexOf(':') + 1);
if(attr != null) {
tagName += "@" + attr.getName();
}
return tagName;
} finally {
smw.dispose();
}
}
/*
* (non-Javadoc)
*
* @see IHyperlink#getHyperlinkText()
*/
public String getHyperlinkText() {
String tagName = getTagName(getHyperlinkRegion());
if (tagName == null)
return CDISeamExtMessages.CDI_SEAM_CONFIG_OPEN_TAG;
return MessageFormat.format(CDISeamExtMessages.CDI_SEAM_CONFIG_OPEN_TAG, tagName);
}
}