Bug 306307 - HyperLink on EL expression shows duplicate entries..
diff --git a/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/META-INF/MANIFEST.MF b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/META-INF/MANIFEST.MF
index 9cb87b2..8c082cd 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/META-INF/MANIFEST.MF
+++ b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/META-INF/MANIFEST.MF
@@ -35,5 +35,6 @@
  org.eclipse.jst.jsf.facelet.ui.internal.contentassist;x-internal:=true,
  org.eclipse.jst.jsf.facelet.ui.internal.facet;x-internal:=true,
  org.eclipse.jst.jsf.facelet.ui.internal.hover;x-internal:=true,
+ org.eclipse.jst.jsf.facelet.ui.internal.htmleditor;x-internal:=true,
  org.eclipse.jst.jsf.facelet.ui.internal.validation;x-internal:=true
 Bundle-Vendor: %Bundle-Vendor.0
diff --git a/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/plugin.xml b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/plugin.xml
index 8269889..1e92218 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/plugin.xml
+++ b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/plugin.xml
@@ -24,7 +24,7 @@
 
     <extension point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectors">
        <hyperlinkDetector
-             class="org.eclipse.jst.jsf.ui.internal.jspeditor.ELHyperlinkDetector"
+             class="org.eclipse.jst.jsf.facelet.ui.internal.htmleditor.FaceletELHyperlinkDetector"
              id="org.eclipse.jst.jsf.ui.elhyperlinkdetector"
              name="%EL_Hyperlinkdetector_name"
              targetId="org.eclipse.wst.html.core.htmlsource">
diff --git a/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/src/org/eclipse/jst/jsf/facelet/ui/internal/htmleditor/FaceletELHyperlinkDetector.java b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/src/org/eclipse/jst/jsf/facelet/ui/internal/htmleditor/FaceletELHyperlinkDetector.java
new file mode 100644
index 0000000..703eeee
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.facelet.ui/src/org/eclipse/jst/jsf/facelet/ui/internal/htmleditor/FaceletELHyperlinkDetector.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Oracle 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:
+ *     Oracle Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.jsf.facelet.ui.internal.htmleditor;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory;
+import org.eclipse.jst.jsf.context.resolver.structureddocument.IWorkspaceContextResolver;
+import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
+import org.eclipse.jst.jsf.ui.internal.jspeditor.AbstractELHyperlinkDetector;
+
+/**
+ * This HyperlinkDetector creates hyperlinks for symbols in JSF EL expressions
+ * inside facelet files.
+ */
+public class FaceletELHyperlinkDetector extends AbstractELHyperlinkDetector {
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.jst.jsf.ui.internal.jspeditor.AbstractELHyperlinkDetector#isEnabled(org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext)
+	 */
+	@Override
+	protected boolean isEnabled(IStructuredDocumentContext context) {
+		boolean enabled = false;
+		if (context != null) {
+			IWorkspaceContextResolver resolver =
+				IStructuredDocumentContextResolverFactory.INSTANCE.getWorkspaceContextResolver(context);
+			if (resolver != null) {
+				IResource resource = resolver.getResource();
+				if (resource instanceof IFile) {
+					IFile file = (IFile)resource;
+					String filename = file.getFullPath().toString();
+					enabled =
+						hasContentType(filename, "jsf.facelet") || //$NON-NLS-1$
+						hasContentType(filename, "jsf.facelet.composite"); //$NON-NLS-1$
+				}
+			}
+		}
+		return enabled;
+	}
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.ui/plugin.properties b/jsf/plugins/org.eclipse.jst.jsf.ui/plugin.properties
index 3775520..f31e526 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.ui/plugin.properties
+++ b/jsf/plugins/org.eclipse.jst.jsf.ui/plugin.properties
@@ -10,7 +10,7 @@
 ###############################################################################
 plugin.name=JavaServer Faces Tools - UI
 plugin.provider=Eclipse.org
-EL_Hyperlinkdetector_name=JSF EL Symbol
+EL_Hyperlinkdetector_name=JSP EL Hyperlink Detector
 
 jsf.library.reference=JSF Library References
 jsf.library.wizard.name=JSF Library
diff --git a/jsf/plugins/org.eclipse.jst.jsf.ui/plugin.xml b/jsf/plugins/org.eclipse.jst.jsf.ui/plugin.xml
index 6105f36..a8699cb 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.ui/plugin.xml
+++ b/jsf/plugins/org.eclipse.jst.jsf.ui/plugin.xml
@@ -100,7 +100,7 @@
     <extension
           point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectors">
        <hyperlinkDetector
-             class="org.eclipse.jst.jsf.ui.internal.jspeditor.ELHyperlinkDetector"
+             class="org.eclipse.jst.jsf.ui.internal.jspeditor.JSPELHyperlinkDetector"
              id="org.eclipse.jst.jsf.ui.elhyperlinkdetector"
              name="%EL_Hyperlinkdetector_name"
              targetId="org.eclipse.jst.jsp.core.jspsource">
diff --git a/jsf/plugins/org.eclipse.jst.jsf.ui/src/org/eclipse/jst/jsf/ui/internal/jspeditor/ELHyperlinkDetector.java b/jsf/plugins/org.eclipse.jst.jsf.ui/src/org/eclipse/jst/jsf/ui/internal/jspeditor/AbstractELHyperlinkDetector.java
similarity index 62%
rename from jsf/plugins/org.eclipse.jst.jsf.ui/src/org/eclipse/jst/jsf/ui/internal/jspeditor/ELHyperlinkDetector.java
rename to jsf/plugins/org.eclipse.jst.jsf.ui/src/org/eclipse/jst/jsf/ui/internal/jspeditor/AbstractELHyperlinkDetector.java
index 8201802..31dae85 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.ui/src/org/eclipse/jst/jsf/ui/internal/jspeditor/ELHyperlinkDetector.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.ui/src/org/eclipse/jst/jsf/ui/internal/jspeditor/AbstractELHyperlinkDetector.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2001, 2008 Oracle Corporation and others.
+ * Copyright (c) 2010 Oracle 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
@@ -10,6 +10,8 @@
  *******************************************************************************/
 package org.eclipse.jst.jsf.ui.internal.jspeditor;
 
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.content.IContentType;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.ITextViewer;
@@ -26,16 +28,32 @@
 
 /**
  * This HyperlinkDetector creates hyperlinks for symbols in JSF EL expressions
- * inside jsp files.
+ * inside jsp and facelet files.
  */
-public class ELHyperlinkDetector extends AbstractHyperlinkDetector {
+public abstract class AbstractELHyperlinkDetector extends AbstractHyperlinkDetector {
 
-    public final IHyperlink[] detectHyperlinks(final ITextViewer textViewer,
-            final IRegion region, final boolean canShowMultipleHyperlinks) {
-        final IStructuredDocumentContext context = IStructuredDocumentContextFactory.INSTANCE
-        .getContext(textViewer, region.getOffset());
+	/**
+	 * Tests if this detector should return any hyperlinks for this context.
+	 * @param context IStructuredDocumentContext instance to test enablement for.
+	 * @return true if this detector should return any hyperlinks for this context, else false.
+	 */
+	protected abstract boolean isEnabled(final IStructuredDocumentContext context);
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.jface.text.hyperlink.IHyperlinkDetector#detectHyperlinks(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion, boolean)
+	 */
+	public final IHyperlink[] detectHyperlinks(
+			final ITextViewer textViewer,
+			final IRegion region,
+			final boolean canShowMultipleHyperlinks) {
+        final IStructuredDocumentContext context =
+        	IStructuredDocumentContextFactory.INSTANCE.getContext(textViewer, region.getOffset());
+        if (!isEnabled(context)) {
+        	return null;
+        }
         return detectHyperlinks(context, region);
-    }
+	}
 
     /**
      * Broken out for testing.
@@ -74,8 +92,8 @@
         return null;
     }
 
-    private IHyperlink createBeanInstanceLink(final Region region,
-            final IBeanInstanceSymbol symbol) {
+    private IHyperlink createBeanInstanceLink(
+    		final Region region, final IBeanInstanceSymbol symbol) {
         if (symbol.isTypeResolved()) {
             final IType type = symbol.getJavaTypeDescriptor().getType();
             return new JavaElementHyperlink(region, type);
@@ -83,18 +101,37 @@
         return null;
     }
 
-    private IHyperlink createBeanPropertyLink(final Region region,
-            final IBeanPropertySymbol symbol) {
+    private IHyperlink createBeanPropertyLink(
+    		final Region region, final IBeanPropertySymbol symbol) {
         // defer calculation of access method until user click on link (takes
         // too long otherwise):
         return new BeanSuffixHyperlink(region, symbol);
     }
 
-    private IHyperlink createMethodLink(final Region region,
-            final IBeanMethodSymbol symbol) {
+    private IHyperlink createMethodLink(
+    		final Region region, final IBeanMethodSymbol symbol) {
         // defer calculation of access method until user click on link (takes
         // too long otherwise):
         return new BeanSuffixHyperlink(region, symbol);
     }
 
+    /**
+     * Tests if the specified file has the specified content type.
+     * @param filename Name of file to test.
+     * @param contentTypeId ID of content type to test.
+     * @return true if the specified file has the specified content type, else false.
+     */
+	protected boolean hasContentType(String filename, String contentTypeId) {
+		boolean hasContentType = false;
+		final IContentType[] contentTypes =
+			Platform.getContentTypeManager().findContentTypesFor(filename);
+		for (final IContentType contentType: contentTypes) {
+			if (contentTypeId.equals(contentType.getId())) {
+				hasContentType = true;
+				break;
+			}
+		}
+		return hasContentType;
+	}
+
 }
diff --git a/jsf/plugins/org.eclipse.jst.jsf.ui/src/org/eclipse/jst/jsf/ui/internal/jspeditor/JSPELHyperlinkDetector.java b/jsf/plugins/org.eclipse.jst.jsf.ui/src/org/eclipse/jst/jsf/ui/internal/jspeditor/JSPELHyperlinkDetector.java
new file mode 100644
index 0000000..79faa8f
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.ui/src/org/eclipse/jst/jsf/ui/internal/jspeditor/JSPELHyperlinkDetector.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Oracle 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:
+ *     Oracle Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.jsf.ui.internal.jspeditor;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory;
+import org.eclipse.jst.jsf.context.resolver.structureddocument.IWorkspaceContextResolver;
+import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
+
+/**
+ * This HyperlinkDetector creates hyperlinks for symbols in JSF EL expressions
+ * inside jsp files.
+ */
+public class JSPELHyperlinkDetector extends AbstractELHyperlinkDetector {
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.jst.jsf.ui.internal.jspeditor.AbstractELHyperlinkDetector#isEnabled(org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext)
+	 */
+	@Override
+	protected boolean isEnabled(IStructuredDocumentContext context) {
+		boolean enabled = false;
+		if (context != null) {
+			IWorkspaceContextResolver resolver =
+				IStructuredDocumentContextResolverFactory.INSTANCE.getWorkspaceContextResolver(context);
+			if (resolver != null) {
+				IResource resource = resolver.getResource();
+				if (resource instanceof IFile) {
+					IFile file = (IFile)resource;
+					String filename = file.getFullPath().toString();
+					enabled = hasContentType(filename, "org.eclipse.jst.jsp.core.jspsource"); //$NON-NLS-1$
+				}
+			}
+		}
+		return enabled;
+	}
+
+}