blob: 31dae8541618e90049653505b8dff4e142ef61a7 [file] [log] [blame]
/*******************************************************************************
* 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.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;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContextFactory;
import org.eclipse.jst.jsf.context.symbol.IBeanInstanceSymbol;
import org.eclipse.jst.jsf.context.symbol.IBeanMethodSymbol;
import org.eclipse.jst.jsf.context.symbol.IBeanPropertySymbol;
import org.eclipse.jst.jsf.context.symbol.ISymbol;
import org.eclipse.jst.jsf.core.internal.contentassist.el.SymbolInfo;
/**
* This HyperlinkDetector creates hyperlinks for symbols in JSF EL expressions
* inside jsp and facelet files.
*/
public abstract class AbstractELHyperlinkDetector extends AbstractHyperlinkDetector {
/**
* 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.
* @param context
* @param region
* @return the hyperlinks
*/
protected IHyperlink[] detectHyperlinks(
final IStructuredDocumentContext context, final IRegion region) {
final Region elRegion = JSPSourceUtil.findELRegion(context);
if (elRegion != null) {
final SymbolInfo symbolInfo = JSPSourceUtil.determineSymbolInfo(
context, elRegion, region.getOffset());
if (symbolInfo != null) {
IHyperlink link = null;
final Region linkRegion = new Region(symbolInfo
.getRelativeRegion().getOffset()
+ elRegion.getOffset(), symbolInfo.getRelativeRegion()
.getLength());
final ISymbol symbol = symbolInfo.getSymbol();
if (symbol instanceof IBeanInstanceSymbol) {
link = createBeanInstanceLink(linkRegion,
(IBeanInstanceSymbol) symbol);
} else if (symbol instanceof IBeanPropertySymbol) {
link = createBeanPropertyLink(linkRegion,
(IBeanPropertySymbol) symbol);
} else if (symbol instanceof IBeanMethodSymbol) {
link = createMethodLink(linkRegion,
(IBeanMethodSymbol) symbol);
}
if (link != null) {
return new IHyperlink[] { link };
}
}
}
return null;
}
private IHyperlink createBeanInstanceLink(
final Region region, final IBeanInstanceSymbol symbol) {
if (symbol.isTypeResolved()) {
final IType type = symbol.getJavaTypeDescriptor().getType();
return new JavaElementHyperlink(region, type);
}
return null;
}
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) {
// 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;
}
}