/******************************************************************************* * Copyright (c) 2007, 2009 Wind River Systems, Inc. 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: * Anton Leherbauer (Wind River Systems) - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.corext.template.c; import com.ibm.icu.text.DateFormat; import com.ibm.icu.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; 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.ContextTypeRegistry; 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.cdt.internal.corext.util.Messages; /** * 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) { StringBuffer expr= new StringBuffer("${"); //$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<String>(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()); } }