blob: 600ba89db3b45bfbc286268527fc46f45813493b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2016 Wind River Systems, Inc. and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Anton Leherbauer (Wind River Systems) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.corext.template.c;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.internal.corext.util.Messages;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeManager;
import org.eclipse.core.variables.IStringVariableManager;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.jface.text.templates.GlobalTemplateVariables;
import org.eclipse.jface.text.templates.SimpleTemplateVariableResolver;
import org.eclipse.jface.text.templates.TemplateContext;
import org.eclipse.jface.text.templates.TemplateContextType;
import org.eclipse.jface.text.templates.TemplateException;
import org.eclipse.jface.text.templates.TemplateVariable;
import org.eclipse.jface.text.templates.TemplateVariableResolver;
import org.eclipse.jface.text.templates.TemplateVariableType;
import org.eclipse.text.templates.ContextTypeRegistry;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.SimpleDateFormat;
/**
* A generic template context type for file resources based on content-type.
*
* @since 5.0
*/
public class FileTemplateContextType extends TemplateContextType {
public static final String CONTEXTTYPE_SUFFIX = ".contenttype_context"; //$NON-NLS-1$
public static final String CONTENTTYPE_TEXT = "org.eclipse.core.runtime.text"; //$NON-NLS-1$
public static final String TEXTFILE_CONTEXTTYPE = CONTENTTYPE_TEXT + CONTEXTTYPE_SUFFIX;
/* resolver types */
public static final String FILENAME = "file_name"; //$NON-NLS-1$
public static final String FILEBASE = "file_base"; //$NON-NLS-1$
public static final String FILELOCATION = "file_loc"; //$NON-NLS-1$
public static final String FILEPATH = "file_path"; //$NON-NLS-1$
public static final String PROJECTNAME = "project_name"; //$NON-NLS-1$
/**
* Resolver that resolves to the variable defined in the context.
*/
static class FileTemplateVariableResolver extends SimpleTemplateVariableResolver {
public FileTemplateVariableResolver(String type, String description) {
super(type, description);
}
@Override
protected String resolve(TemplateContext context) {
String value = context.getVariable(getType());
return value != null ? value : ""; //$NON-NLS-1$
}
}
/**
* This date variable evaluates to the current date in a specific format.
*/
static class DateVariableResolver extends SimpleTemplateVariableResolver {
private String fFormat;
public DateVariableResolver() {
super("date", TemplateMessages.FileTemplateContextType_variable_description_date); //$NON-NLS-1$
}
/*
* @see org.eclipse.jface.text.templates.TemplateVariableResolver#resolve(org.eclipse.jface.text.templates.TemplateVariable, org.eclipse.jface.text.templates.TemplateContext)
*/
@Override
public void resolve(TemplateVariable variable, TemplateContext context) {
fFormat = null;
TemplateVariableType type = variable.getVariableType();
List<?> params = type.getParams();
if (params.size() == 1) {
fFormat = params.get(0).toString();
}
super.resolve(variable, context);
}
/*
* @see org.eclipse.jface.text.templates.SimpleTemplateVariableResolver#resolve(org.eclipse.jface.text.templates.TemplateContext)
*/
@Override
protected String resolve(TemplateContext context) {
DateFormat f;
if (fFormat == null) {
f = DateFormat.getDateInstance();
} else {
f = new SimpleDateFormat(fFormat);
}
return f.format(new java.util.Date());
}
}
/**
* Resolver that resolves to the value of a core variable.
*/
static class CoreVariableResolver extends SimpleTemplateVariableResolver {
private String fVariableName;
private String[] fArguments;
public CoreVariableResolver(String type) {
super(type, TemplateMessages.FileTemplateContextType__variable_description_eclipse);
}
/*
* @see org.eclipse.jface.text.templates.TemplateVariableResolver#resolve(org.eclipse.jface.text.templates.TemplateVariable, org.eclipse.jface.text.templates.TemplateContext)
*/
@Override
public void resolve(TemplateVariable variable, TemplateContext context) {
fVariableName = variable.getName();
TemplateVariableType type = variable.getVariableType();
List<?> params = type.getParams();
fArguments = params.toArray(new String[params.size()]);
super.resolve(variable, context);
}
/*
* @see org.eclipse.jface.text.templates.SimpleTemplateVariableResolver#resolve(org.eclipse.jface.text.templates.TemplateContext)
*/
@Override
protected String resolve(TemplateContext context) {
StringBuilder expr = new StringBuilder("${"); //$NON-NLS-1$
expr.append(fVariableName);
for (int i = 0; i < fArguments.length; i++) {
expr.append(':').append(fArguments[i]);
}
expr.append('}');
IStringVariableManager mgr = VariablesPlugin.getDefault().getStringVariableManager();
try {
return mgr.performStringSubstitution(expr.toString(), false);
} catch (CoreException exc) {
return expr.toString();
}
}
}
public FileTemplateContextType(String contextTypeId) {
this(contextTypeId, contextTypeId);
}
public FileTemplateContextType(String contextTypeId, String contextName) {
super(contextTypeId, contextName);
// global
addResolver(new GlobalTemplateVariables.Dollar());
addResolver(new DateVariableResolver());
addResolver(new GlobalTemplateVariables.Year());
addResolver(new GlobalTemplateVariables.Time());
addResolver(new GlobalTemplateVariables.User());
// addResolver(new CoreVariableResolver("eclipse")); //$NON-NLS-1$
addResourceVariables();
}
protected void addResourceVariables() {
addResolver(new FileTemplateVariableResolver(FILENAME,
TemplateMessages.FileTemplateContextType_variable_description_filename));
addResolver(new FileTemplateVariableResolver(FILEBASE,
TemplateMessages.FileTemplateContextType_variable_description_filebase));
addResolver(new FileTemplateVariableResolver(FILELOCATION,
TemplateMessages.FileTemplateContextType_variable_description_fileloc));
addResolver(new FileTemplateVariableResolver(FILEPATH,
TemplateMessages.FileTemplateContextType_variable_description_filepath));
addResolver(new FileTemplateVariableResolver(PROJECTNAME,
TemplateMessages.FileTemplateContextType_variable_description_projectname));
}
@Override
protected TemplateVariableResolver getResolver(String type) {
// compatibility with editor template variables
if ("file".equals(type)) { //$NON-NLS-1$
type = FILENAME;
} else if ("project".equals(type) || "enclosing_project".equals(type)) { //$NON-NLS-1$ //$NON-NLS-2$
type = PROJECTNAME;
}
return super.getResolver(type);
}
@Override
protected void validateVariables(TemplateVariable[] variables) throws TemplateException {
ArrayList<String> required = new ArrayList<>(5);
for (int i = 0; i < variables.length; i++) {
String type = variables[i].getType();
if (getResolver(type) == null) {
throw new TemplateException(
Messages.format(TemplateMessages.FileTemplateContextType_validate_unknownvariable, type));
}
required.remove(type);
}
if (!required.isEmpty()) {
String missing = required.get(0);
throw new TemplateException(
Messages.format(TemplateMessages.FileTemplateContextType_validate_missingvariable, missing));
}
super.validateVariables(variables);
}
/*
* @see org.eclipse.jface.text.templates.TemplateContextType#resolve(org.eclipse.jface.text.templates.TemplateVariable, org.eclipse.jface.text.templates.TemplateContext)
*/
@Override
public void resolve(TemplateVariable variable, TemplateContext context) {
String type = variable.getType();
TemplateVariableResolver resolver = getResolver(type);
if (resolver == null) {
resolver = new FileTemplateVariableResolver(type, ""); //$NON-NLS-1$
}
resolver.resolve(variable, context);
}
public static void registerContextTypes(ContextTypeRegistry registry) {
IContentTypeManager contentTypeMgr = Platform.getContentTypeManager();
IContentType[] contentTypes = contentTypeMgr.getAllContentTypes();
for (int i = 0; i < contentTypes.length; i++) {
IContentType contentType = contentTypes[i];
if (isTextContentType(contentType)
&& contentType.getFileSpecs(IContentType.FILE_EXTENSION_SPEC).length > 0) {
final String contextTypeId = contextTypeIdForContentType(contentType);
if (registry.getContextType(contextTypeId) == null) {
registry.addContextType(new FileTemplateContextType(contextTypeId, contentType.getName()));
}
}
}
}
public static String contextTypeIdForContentType(IContentType contentType) {
return contentType.getId() + CONTEXTTYPE_SUFFIX;
}
public static boolean isFileTemplateContextType(String contextTypeId) {
return contextTypeId.endsWith(CONTEXTTYPE_SUFFIX);
}
public static boolean isContextTypeForContentType(String contextTypeId, String contentTypeId) {
return contextTypeId.endsWith(CONTEXTTYPE_SUFFIX) && contextTypeId.startsWith(contentTypeId);
}
public static String contentTypeIdForContextType(String contextTypeId) {
return contextTypeId.substring(0, contextTypeId.length() - CONTEXTTYPE_SUFFIX.length());
}
private static boolean isTextContentType(IContentType contentType) {
if (contentType == null) {
return false;
}
String id = contentType.getId();
if (id.equals(CONTENTTYPE_TEXT)) {
return true;
}
if (id.indexOf(".pde.") != -1 || id.indexOf(".jdt.") != -1) { //$NON-NLS-1$ //$NON-NLS-2$
return false;
}
return isTextContentType(contentType.getBaseType());
}
}