/**
* This file Copyright (c) 2005-2008 Aptana, Inc. This program is
* dual-licensed under both the Aptana Public License and the GNU General
* Public license. You may elect to use one or the other of these licenses.
*
* This program is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. Redistribution, except as permitted by whichever of
* the GPL or APL you select, is prohibited.
*
* 1. For the GPL license (GPL), you can redistribute and/or modify this
* program under the terms of the GNU General Public License,
* Version 3, as published by the Free Software Foundation. You should
* have received a copy of the GNU General Public License, Version 3 along
* with this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Aptana provides a special exception to allow redistribution of this file
* with certain other free and open source software ("FOSS") code and certain additional terms
* pursuant to Section 7 of the GPL. You may view the exception and these
* terms on the web at http://www.aptana.com/legal/gpl/.
*
* 2. For the Aptana Public License (APL), this program and the
* accompanying materials are made available under the terms of the APL
* v1.0 which accompanies this distribution, and is available at
* http://www.aptana.com/legal/apl/.
*
* You may view the GPL, Aptana's exception and additional terms, and the
* APL in the file titled license.html at the root of the corresponding
* plugin containing this source file.
*
* Any modifications to this file must keep this entire header intact.
*/
package com.aptana.ide.editors.unified;
import java.util.ArrayList;
import org.eclipse.jface.text.DefaultTextDoubleClickStrategy;
import org.eclipse.jface.text.IAutoEditStrategy;
import org.eclipse.jface.text.ITextDoubleClickStrategy;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import com.aptana.ide.core.StringUtils;
import com.aptana.ide.editors.formatting.IUnifiedBracketInserter;
import com.aptana.ide.editors.unified.contentassist.UnifiedTemplateCompletionProcessor;
import com.aptana.ide.editors.unified.hover.LexemeTextHover;
/**
* BaseContributor
*/
public abstract class BaseContributor implements IUnifiedEditorContributor
{
/*
* Fields
*/
private String language;
/**
* parent
*/
protected IUnifiedEditorContributor parent;
private String[] contentTypes;
private EditorFileContext fileService;
private String[] indentPrefixes = new String[] { "\t", " " }; //$NON-NLS-1$ //$NON-NLS-2$
private SourceViewerConfiguration parentConfiguration;
private ITextDoubleClickStrategy doubleClickStrategy;
private ITextTripleClickStrategy tripleClickStrategy;
/**
* Creates a new base contributor with a language type. This constructor was added jointly with a default
* implementation of the getLocalContentType method thats returns the language parameter for this constructur making
* it no longer abstract.
*
* @param language
* - mime type
*/
protected BaseContributor(String language)
{
this.language = language;
}
/*
* Methods
*/
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#dispose()
*/
public void dispose()
{
if (parent != null)
{
parent.dispose();
parent = null;
}
fileService = null;
parentConfiguration = null;
doubleClickStrategy = null;
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#isAutoActivateContentAssist()
*/
public boolean isAutoActivateContentAssist()
{
return false;
}
/**
* Returns the language specified in the BaseContributor(String language) constructor.
*
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#getLocalContentType()
*/
public String getLocalContentType()
{
return language;
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#getIndentPrefixes(org.eclipse.jface.text.source.ISourceViewer,
* java.lang.String)
*/
public String[] getIndentPrefixes(ISourceViewer sourceViewer, String contentType)
{
if (contentType == null || contentType.equals(StringUtils.EMPTY)
|| contentType.equals(this.getLocalContentType()))
{
return getLocalIndentPrefixes();
}
IUnifiedEditorContributor[] ccs = getChildContributors();
if (ccs != null)
{
for (int i = 0; i < ccs.length; i++)
{
if (ccs[i].getLocalContentType().equals(contentType) && ccs[i] instanceof BaseContributor)
{
((BaseContributor) ccs[i]).getLocalIndentPrefixes();
break;
}
}
}
// this is the default, so don't care about contentType
return indentPrefixes;
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#getIndentString(org.eclipse.jface.text.source.ISourceViewer,
* java.lang.String)
*/
public String getIndentString(ISourceViewer sourceViewer, String contentType)
{
String[] indents = getIndentPrefixes(sourceViewer, contentType);
boolean hasIndents = (indents == null) || (indents.length == 0);
String indentString = hasIndents ? "\t" : indents[0]; //$NON-NLS-1$
return indentString;
}
/**
* getLocalIndentPrefixes
*
* @return String[]
*/
protected String[] getLocalIndentPrefixes()
{
return this.indentPrefixes;
}
/**
* setLocalIndentPrefixes
*
* @param prefixes
*/
protected void setLocalIndentPrefixes(String[] prefixes)
{
this.indentPrefixes = prefixes;
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#setIndentPrefixes(java.lang.String[],
* org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
*/
public void setIndentPrefixes(String[] prefixes, ISourceViewer sourceViewer, String contentType)
{
IUnifiedEditorContributor[] ccs = getChildContributors();
if (ccs != null)
{
for (int i = 0; i < ccs.length; i++)
{
if (ccs[i].getLocalContentType().equals(contentType) && ccs[i] instanceof BaseContributor)
{
((BaseContributor) ccs[i]).setLocalIndentPrefixes(prefixes);
sourceViewer.setIndentPrefixes(prefixes, contentType);
break;
}
}
}
}
/**
* Sets index prefixes for all lanugages, overriding any current settings
*
* @param prefixes
* @param sourceViewer
*/
public void setAllIndentPrefixes(String[] prefixes, ISourceViewer sourceViewer)
{
this.indentPrefixes = prefixes;
IUnifiedEditorContributor[] ccs = getChildContributors();
if (ccs != null)
{
for (int i = 0; i < ccs.length; i++)
{
if (ccs[i] instanceof BaseContributor)
{
((BaseContributor) ccs[i]).setLocalIndentPrefixes(prefixes);
sourceViewer.setIndentPrefixes(prefixes, ccs[i].getLocalContentType());
}
}
}
sourceViewer.setIndentPrefixes(prefixes, this.getLocalContentType());
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#getChildContributors()
*/
public IUnifiedEditorContributor[] getChildContributors()
{
return null; // default is no child contributors
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#findChildContributor(java.lang.String)
*/
public IUnifiedEditorContributor findChildContributor(String contentType)
{
if (contentType.equals(getLocalContentType()))
{
return this;
}
else
{
IUnifiedEditorContributor[] contributors = getChildContributors();
if (contributors != null)
{
for (int i = 0; i < contributors.length; i++)
{
IUnifiedEditorContributor child = contributors[i].findChildContributor(contentType);
if (child != null)
{
return child;
}
}
}
return null;
}
}
/**
* configLocalPresentationReconciler
*
* @param reconciler
*/
public void configLocalPresentationReconciler(PresentationReconciler reconciler)
{
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#getLocalAutoEditStrategies(org.eclipse.jface.text.source.ISourceViewer,
* java.lang.String)
*/
public IAutoEditStrategy[] getLocalAutoEditStrategies(ISourceViewer sourceViewer, String contentType)
{
return null;
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#getLocalContentAssistProcessor(org.eclipse.jface.text.source.ISourceViewer,
* java.lang.String)
*/
public IContentAssistProcessor getLocalContentAssistProcessor(ISourceViewer sourceViewer, String contentType)
{
return null;
}
/*
* Final Methods
*/
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#configPresentationReconciler(org.eclipse.jface.text.presentation.PresentationReconciler)
*/
public final void configPresentationReconciler(PresentationReconciler reconciler)
{
// configLocalPresentationReconciler(reconciler);
//
// IUnifiedEditorContributor[] ccs = getChildContributors();
// if(ccs != null)
// {
// for (int i = 0; i < ccs.length; i++)
// {
// ccs[i].configPresentationReconciler(reconciler);
// }
// }
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#getContentTypes()
*/
public final String[] getContentTypes()
{
// this can be computed only once at first call, and cached
if (contentTypes == null)
{
ArrayList al = new ArrayList();
// find all contentTypes below this level
String localCTS = getLocalContentType();
int len = 0;
if (localCTS != null)
{
al.add(new String[] { localCTS });
len = 1;
}
IUnifiedEditorContributor[] ccs = getChildContributors();
if (ccs != null)
{
for (int i = 0; i < ccs.length; i++)
{
String[] ct = ccs[i].getContentTypes();
if (ct != null)
{
al.add(ct);
len += ct.length;
}
}
}
// now consolidate them into an array
contentTypes = new String[len];
int index = 0;
for (int i = 0; i < al.size(); i++)
{
String[] types = (String[]) al.get(i);
for (int j = 0; j < types.length; j++)
{
contentTypes[index] = types[j];
index++;
}
}
}
return contentTypes;
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#getContentAssistProcessor(org.eclipse.jface.text.source.ISourceViewer,
* java.lang.String)
*/
public final IContentAssistProcessor getContentAssistProcessor(ISourceViewer sourceViewer, String contentType)
{
// this will only return one IContentAssistProcessor, so the first match wins,
// but don't cache because result is based on content type
IContentAssistProcessor localCA = getLocalContentAssistProcessor(sourceViewer, contentType);
if (localCA != null)
{
return new MergingContentProcessor(localCA, new UnifiedTemplateCompletionProcessor(contentType));
}
IUnifiedEditorContributor[] ccs = getChildContributors();
if (ccs != null)
{
for (int i = 0; i < ccs.length; i++)
{
IContentAssistProcessor ca = ccs[i].getContentAssistProcessor(sourceViewer, contentType);
if (ca != null)
{
return ca;
}
}
}
return null;
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#getBracketInserter(org.eclipse.jface.text.source.ISourceViewer,
* java.lang.String)
*/
public final IUnifiedBracketInserter getBracketInserter(ISourceViewer sourceViewer, String contentType)
{
// this will only return one IContentAssistProcessor, so the first match wins,
// but don't cache because result is based on content type
IUnifiedBracketInserter localCA = getLocalBracketInserter(sourceViewer, contentType);
if (localCA != null)
{
return localCA;
}
IUnifiedEditorContributor[] ccs = getChildContributors();
if (ccs != null)
{
for (int i = 0; i < ccs.length; i++)
{
IUnifiedBracketInserter ca = ccs[i].getBracketInserter(sourceViewer, contentType);
if (ca != null)
{
return ca;
}
}
}
return null;
}
/**
* isValidIdentifier
*
* @param c
* @param keyCode
* @return boolean
*/
public boolean isValidIdentifier(char c, int keyCode)
{
return false;
}
/**
* isValidActivationCharacter
*
* @param c
* @param keyCode
* @return boolean
*/
public boolean isValidActivationCharacter(char c, int keyCode)
{
return false;
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#getTextHover(org.eclipse.jface.text.source.ISourceViewer,
* java.lang.String)
*/
public final ITextHover getTextHover(ISourceViewer sourceViewer, String contentType)
{
// this will only return one ITextHover, so the first match wins,
// but don't cache because result is based on content type
ITextHover localHover = getLocalTextHover(sourceViewer, contentType);
if (localHover != null)
{
return localHover;
}
IUnifiedEditorContributor[] ccs = getChildContributors();
if (ccs != null)
{
for (int i = 0; i < ccs.length; i++)
{
ITextHover hover = ccs[i].getTextHover(sourceViewer, contentType);
if (hover != null)
{
return hover;
}
}
}
return null;
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#getAutoEditStrategies(org.eclipse.jface.text.source.ISourceViewer,
* java.lang.String)
*/
public final IAutoEditStrategy[] getAutoEditStrategies(ISourceViewer sourceViewer, String contentType)
{
// this result is based on contentType, so isn't cached
ArrayList al = new ArrayList();
// find all autoEditStrategies below this level
IAutoEditStrategy[] localAES = getLocalAutoEditStrategies(sourceViewer, contentType);
int len = 0;
if (localAES != null)
{
al.add(localAES);
len = localAES.length;
}
IUnifiedEditorContributor[] ccs = getChildContributors();
if (ccs != null && ccs.length > 0)
{
for (int i = 0; i < ccs.length; i++)
{
IAutoEditStrategy[] ct = ccs[i].getAutoEditStrategies(sourceViewer, contentType);
if (ct != null && ct.length > 0)
{
al.add(ct);
len += ct.length;
}
}
}
// now consolidate them into an array
IAutoEditStrategy[] autoEditStrategies = new IAutoEditStrategy[len];
int index = 0;
for (int i = 0; i < al.size(); i++)
{
IAutoEditStrategy[] aes = (IAutoEditStrategy[]) al.get(i);
for (int j = 0; j < aes.length; j++)
{
autoEditStrategies[index] = aes[j];
index++;
}
}
return autoEditStrategies;
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#getFileContext()
*/
public final EditorFileContext getFileContext()
{
if (fileService == null && parent != null)
{
return parent.getFileContext();
}
else
{
return fileService;
}
}
/**
* Sets the current language service
*
* @param fileContext
*/
public void setFileContext(EditorFileContext fileContext)
{
this.fileService = fileContext;
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#setParent(com.aptana.ide.editors.unified.IUnifiedEditorContributor)
*/
public final void setParent(IUnifiedEditorContributor parent)
{
this.parent = parent;
}
/**
* Returns an instance of the TextHover class for the specified content type
*
* @param sourceViewer
* The current ISourceViewer
* @param contentType
* The current content type (generally a mine type such as text/html)
* @return A new TextHover class, or null if not relevant.
*/
public ITextHover getLocalTextHover(ISourceViewer sourceViewer, String contentType)
{
if (contentType.equals(getLocalContentType()))
{
return new LexemeTextHover(getFileContext());
}
return null;
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#getParentConfiguration()
*/
public SourceViewerConfiguration getParentConfiguration()
{
if (parentConfiguration != null)
{
return parentConfiguration;
}
else if (parent != null)
{
return parent.getParentConfiguration();
}
else
{
return null;
}
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#setParentConfiguration(org.eclipse.jface.text.source.SourceViewerConfiguration)
*/
public void setParentConfiguration(SourceViewerConfiguration parentConfiguration)
{
this.parentConfiguration = parentConfiguration;
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#getDoubleClickStrategy(ISourceViewer, String)
*/
public ITextDoubleClickStrategy getDoubleClickStrategy(ISourceViewer sourceViewer, String contentType)
{
IUnifiedEditorContributor[] ccs = getChildContributors();
if (ccs != null && ccs.length > 0)
{
for (int i = 0; i < ccs.length; i++)
{
ITextDoubleClickStrategy dcs = ccs[i].getDoubleClickStrategy(sourceViewer, contentType);
if (dcs != null)
{
return dcs;
}
}
}
if (doubleClickStrategy == null)
{
doubleClickStrategy = new DefaultTextDoubleClickStrategy();
}
return doubleClickStrategy;
}
/**
* Gets triple click strategy.
*
* @param sourceViewer
* - source viewer.
* @param contentType
* - content type.
* @return triple click strategy
*/
public ITextTripleClickStrategy getTripleClickStrategy(ISourceViewer sourceViewer, String contentType)
{
IUnifiedEditorContributor[] ccs = getChildContributors();
if (ccs != null && ccs.length > 0)
{
for (int i = 0; i < ccs.length; i++)
{
ITextTripleClickStrategy dcs = ccs[i].getTripleClickStrategy(sourceViewer, contentType);
if (dcs != null)
{
return dcs;
}
}
}
if (tripleClickStrategy == null)
{
tripleClickStrategy = new UnifiedTripleClickStrategy();
}
return tripleClickStrategy;
}
/**
* @see com.aptana.ide.editors.unified.IUnifiedEditorContributor#getLocalBracketInserter(ISourceViewer, String)
*/
public IUnifiedBracketInserter getLocalBracketInserter(ISourceViewer sourceViewer, String contentType)
{
return null;
}
}