/** * Copyright (C) 2005 - 2012 Eric Van Dewoestine * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.eclim.plugin.jdt.command.delegate; import java.util.ArrayList; import java.util.HashMap; import org.eclim.Services; import org.eclim.annotation.Command; import org.eclim.command.CommandLine; import org.eclim.command.Options; import org.eclim.plugin.core.util.TemplateUtils; import org.eclim.plugin.jdt.PluginResources; import org.eclim.plugin.jdt.command.impl.ImplCommand; import org.eclim.plugin.jdt.util.JavaUtils; import org.eclim.plugin.jdt.util.MethodUtils; import org.eclim.plugin.jdt.util.TypeInfo; import org.eclim.plugin.jdt.util.TypeUtils; import org.eclim.util.file.Position; import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IField; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ITypeParameter; import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.core.formatter.CodeFormatter; /** * Command to handle creation of delegate methods. * * @author Eric Van Dewoestine */ @Command( name = "java_delegate", options = "REQUIRED p project ARG," + "REQUIRED f file ARG," + "REQUIRED o offset ARG," + "REQUIRED e encoding ARG," + "OPTIONAL t type ARG," + "OPTIONAL s superType ARG," + "OPTIONAL m methods ARG" ) public class DelegateCommand extends ImplCommand { private static final String TEMPLATE = "method.gst"; private IField field; private TypeInfo delegateTypeInfo; /** * {@inheritDoc} */ public Object execute(CommandLine commandLine) throws Exception { String project = commandLine.getValue(Options.PROJECT_OPTION); String file = commandLine.getValue(Options.FILE_OPTION); ICompilationUnit src = JavaUtils.getCompilationUnit(project, file); IJavaElement element = src.getElementAt(getOffset(commandLine)); if(element.getElementType() != IJavaElement.FIELD){ return Services.getMessage("not.a.field"); } field = (IField)element; String signature = field.getTypeSignature(); IType delegateType = TypeUtils.findUnqualifiedType( src, Signature.getSignatureSimpleName(signature)); if(delegateType == null){ return Services.getMessage("type.not.found", src.getJavaProject().getElementName(), Signature.getSignatureSimpleName(signature)) + " " + Services.getMessage("check.import"); } ITypeParameter[] params = delegateType.getTypeParameters(); String[] typeParams = new String[params.length]; for (int ii = 0; ii < params.length; ii++){ typeParams[ii] = params[ii].getElementName(); } String[] args = Signature.getTypeArguments(signature); String[] typeArgs = new String[args.length]; for (int ii = 0; ii < args.length; ii++){ typeArgs[ii] = Signature.getSignatureSimpleName(args[ii]); } delegateTypeInfo = new TypeInfo(delegateType, typeParams, typeArgs); return super.execute(commandLine); } /** * {@inheritDoc} */ @Override protected TypeInfo[] getSuperTypes(CommandLine commandLine, IType type) throws Exception { IType delegateType = delegateTypeInfo.getType(); ArrayList<TypeInfo> types = new ArrayList<TypeInfo>(); types.add(delegateTypeInfo); TypeUtils.getInterfaces(delegateType, types, false, delegateTypeInfo); TypeUtils.getSuperClasses(delegateType, types, false, delegateTypeInfo); return types.toArray(new TypeInfo[types.size()]); } /** * {@inheritDoc} */ @Override protected boolean isValidMethod(IMethod method) throws Exception { int flags = method.getFlags(); return (!method.isConstructor() && (Flags.isPublic(flags) || method.getDeclaringType().isInterface())); } /** * {@inheritDoc} */ @Override protected boolean isValidType(IType type) throws Exception { return true; } /** * {@inheritDoc} */ @Override protected Position insertMethod( CommandLine commandLine, ICompilationUnit src, IType type, TypeInfo superTypeInfo, IMethod method, IJavaElement sibling) throws Exception { HashMap<String, Object> values = new HashMap<String, Object>(); JavaUtils.loadPreferencesForTemplate( type.getJavaProject().getProject(), getPreferences(), values); IType superType = superTypeInfo.getType(); if(superType.isInterface()){ values.put("modifier", "public"); }else{ values.put("modifier", Flags.isPublic(method.getFlags()) ? "public" : "protected"); } values.put("name", method.getElementName()); String returnType = Signature.getSignatureSimpleName( method.getReturnType()); values.put("returnType", TypeUtils.replaceTypeParams(returnType, superTypeInfo)); values.put("params", MethodUtils.getMethodParameters(method, superTypeInfo, true)); String thrown = MethodUtils.getMethodThrows(method); values.put("throwsType", thrown != null ? thrown : null); values.put("overrides", Boolean.FALSE); StringBuffer methodBody = new StringBuffer(); if(!returnType.equals("void")){ methodBody.append("return "); } methodBody.append(field.getElementName()) .append('.').append(method.getElementName()).append('('); String[] paramNames = method.getParameterNames(); for(int ii = 0; ii < paramNames.length; ii++){ if(ii != 0){ methodBody.append(", "); } methodBody.append(paramNames[ii]); } methodBody.append(");"); values.put("methodBody", methodBody.toString()); String typeName = JavaUtils.getCompilationUnitRelativeTypeName(src, superType); values.put("superType", typeName); values.put("implementof", Boolean.TRUE); values.put("delegate", Boolean.TRUE); values.put("methodSignature", MethodUtils.getMinimalMethodSignature(method, superTypeInfo)); PluginResources resources = (PluginResources) Services.getPluginResources(PluginResources.NAME); String result = TemplateUtils.evaluate(resources, TEMPLATE, values); Position position = TypeUtils.getPosition(type, type.createMethod(result, sibling, false, null)); JavaUtils.format( src, CodeFormatter.K_COMPILATION_UNIT, position.getOffset(), position.getLength()); return position; } }