Skip to main content
summaryrefslogtreecommitdiffstats
blob: 31dae8541618e90049653505b8dff4e142ef61a7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*******************************************************************************
 * 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;
	}

}

Back to the top