| /******************************************************************************* |
| * 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()); |
| } |
| } |