001: /*******************************************************************************
002: * Copyright (c) 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.ui.fix;
011:
012: import java.util.Map;
013:
014: import org.eclipse.core.runtime.CoreException;
015:
016: import org.eclipse.jface.text.BadLocationException;
017: import org.eclipse.jface.text.templates.Template;
018: import org.eclipse.jface.text.templates.TemplateBuffer;
019: import org.eclipse.jface.text.templates.TemplateException;
020:
021: import org.eclipse.jdt.core.ICompilationUnit;
022: import org.eclipse.jdt.core.compiler.IProblem;
023: import org.eclipse.jdt.core.dom.CompilationUnit;
024:
025: import org.eclipse.jdt.internal.corext.fix.CleanUpConstants;
026: import org.eclipse.jdt.internal.corext.fix.IFix;
027: import org.eclipse.jdt.internal.corext.fix.UnimplementedCodeFix;
028: import org.eclipse.jdt.internal.corext.template.java.CodeTemplateContext;
029: import org.eclipse.jdt.internal.corext.template.java.CodeTemplateContextType;
030:
031: import org.eclipse.jdt.ui.PreferenceConstants;
032: import org.eclipse.jdt.ui.text.java.IProblemLocation;
033:
034: import org.eclipse.jdt.internal.ui.JavaPlugin;
035:
036: public class UnimplementedCodeCleanUp extends AbstractMultiFix {
037:
038: public static final String MAKE_TYPE_ABSTRACT = "cleanup.make_type_abstract_if_missing_method"; //$NON-NLS-1$
039:
040: public UnimplementedCodeCleanUp() {
041: super ();
042: }
043:
044: public UnimplementedCodeCleanUp(Map settings) {
045: super (settings);
046: }
047:
048: /**
049: * {@inheritDoc}
050: */
051: public String[] getDescriptions() {
052: if (isEnabled(CleanUpConstants.ADD_MISSING_METHODES))
053: return new String[] { MultiFixMessages.UnimplementedCodeCleanUp_AddUnimplementedMethods_description };
054:
055: if (isEnabled(MAKE_TYPE_ABSTRACT))
056: return new String[] { MultiFixMessages.UnimplementedCodeCleanUp_MakeAbstract_description };
057:
058: return null;
059: }
060:
061: /**
062: * {@inheritDoc}
063: */
064: public String getPreview() {
065: StringBuffer buf = new StringBuffer();
066:
067: if (isEnabled(MAKE_TYPE_ABSTRACT)) {
068: buf
069: .append("public abstract class Face implements IFace {\n"); //$NON-NLS-1$
070: } else {
071: buf.append("public class Face implements IFace {\n"); //$NON-NLS-1$
072: }
073: if (isEnabled(CleanUpConstants.ADD_MISSING_METHODES)) {
074: boolean createComments = Boolean.valueOf(
075: PreferenceConstants.getPreference(
076: PreferenceConstants.CODEGEN_ADD_COMMENTS,
077: null)).booleanValue();
078: if (createComments)
079: buf
080: .append(indent(getOverridingMethodComment(),
081: " ")); //$NON-NLS-1$
082:
083: buf.append(" @Override\n"); //$NON-NLS-1$
084: buf.append(" public void method() {\n"); //$NON-NLS-1$
085: buf.append(indent(getMethodBody(), " ")); //$NON-NLS-1$
086: buf.append(" }\n"); //$NON-NLS-1$
087: }
088: buf.append("}\n"); //$NON-NLS-1$
089:
090: return buf.toString();
091: }
092:
093: /**
094: * {@inheritDoc}
095: */
096: public CleanUpRequirements getRequirements() {
097: if (!isEnabled(CleanUpConstants.ADD_MISSING_METHODES)
098: && !isEnabled(MAKE_TYPE_ABSTRACT))
099: return super .getRequirements();
100:
101: return new CleanUpRequirements(true, false, null);
102: }
103:
104: /**
105: * {@inheritDoc}
106: */
107: protected IFix createFix(CompilationUnit unit) throws CoreException {
108: IProblemLocation[] problemLocations = convertProblems(unit
109: .getProblems());
110: problemLocations = filter(problemLocations, new int[] {
111: IProblem.AbstractMethodMustBeImplemented,
112: IProblem.EnumAbstractMethodMustBeImplemented });
113:
114: return UnimplementedCodeFix.createCleanUp(unit,
115: isEnabled(CleanUpConstants.ADD_MISSING_METHODES),
116: isEnabled(MAKE_TYPE_ABSTRACT), problemLocations);
117: }
118:
119: /**
120: * {@inheritDoc}
121: */
122: protected IFix createFix(CompilationUnit unit,
123: IProblemLocation[] problems) throws CoreException {
124: IProblemLocation[] problemLocations = filter(problems,
125: new int[] { IProblem.AbstractMethodMustBeImplemented,
126: IProblem.EnumAbstractMethodMustBeImplemented });
127: return UnimplementedCodeFix.createCleanUp(unit,
128: isEnabled(CleanUpConstants.ADD_MISSING_METHODES),
129: isEnabled(MAKE_TYPE_ABSTRACT), problemLocations);
130: }
131:
132: /**
133: * {@inheritDoc}
134: */
135: public boolean canFix(ICompilationUnit compilationUnit,
136: IProblemLocation problem) {
137: int id = problem.getProblemId();
138: if (id == IProblem.AbstractMethodMustBeImplemented
139: || id == IProblem.EnumAbstractMethodMustBeImplemented)
140: return isEnabled(CleanUpConstants.ADD_MISSING_METHODES)
141: || isEnabled(MAKE_TYPE_ABSTRACT);
142:
143: return false;
144: }
145:
146: /**
147: * {@inheritDoc}
148: */
149: public int computeNumberOfFixes(CompilationUnit compilationUnit) {
150: if (!isEnabled(CleanUpConstants.ADD_MISSING_METHODES)
151: && !isEnabled(MAKE_TYPE_ABSTRACT))
152: return 0;
153:
154: IProblemLocation[] locations = filter(
155: convertProblems(compilationUnit.getProblems()),
156: new int[] { IProblem.AbstractMethodMustBeImplemented,
157: IProblem.EnumAbstractMethodMustBeImplemented });
158: return locations.length;
159: }
160:
161: private String getOverridingMethodComment() {
162: String templateName = CodeTemplateContextType.OVERRIDECOMMENT_ID;
163:
164: Template template = getCodeTemplate(templateName);
165: if (template == null)
166: return ""; //$NON-NLS-1$
167:
168: CodeTemplateContext context = new CodeTemplateContext(template
169: .getContextTypeId(), null, "\n"); //$NON-NLS-1$
170:
171: context.setVariable(CodeTemplateContextType.FILENAME,
172: "Face.java"); //$NON-NLS-1$
173: context
174: .setVariable(CodeTemplateContextType.PACKAGENAME,
175: "test"); //$NON-NLS-1$
176: context.setVariable(CodeTemplateContextType.PROJECTNAME,
177: "TestProject"); //$NON-NLS-1$
178: context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE,
179: "Face"); //$NON-NLS-1$
180: context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD,
181: "method"); //$NON-NLS-1$
182: context
183: .setVariable(CodeTemplateContextType.RETURN_TYPE,
184: "void"); //$NON-NLS-1$
185: context.setVariable(
186: CodeTemplateContextType.SEE_TO_OVERRIDDEN_TAG,
187: "test.IFace#foo()"); //$NON-NLS-1$
188:
189: return evaluateTemplate(template, context);
190: }
191:
192: private String getMethodBody() {
193: String templateName = CodeTemplateContextType.METHODSTUB_ID;
194: Template template = getCodeTemplate(templateName);
195: if (template == null)
196: return ""; //$NON-NLS-1$
197:
198: CodeTemplateContext context = new CodeTemplateContext(template
199: .getContextTypeId(), null, "\n"); //$NON-NLS-1$
200: context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD,
201: "method"); //$NON-NLS-1$
202: context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE,
203: "Face"); //$NON-NLS-1$
204: context.setVariable(CodeTemplateContextType.BODY_STATEMENT, ""); //$NON-NLS-1$
205: return evaluateTemplate(template, context);
206: }
207:
208: private static Template getCodeTemplate(String id) {
209: return JavaPlugin.getDefault().getCodeTemplateStore()
210: .findTemplateById(id);
211: }
212:
213: private String evaluateTemplate(Template template,
214: CodeTemplateContext context) {
215: TemplateBuffer buffer;
216: try {
217: buffer = context.evaluate(template);
218: } catch (BadLocationException e) {
219: JavaPlugin.log(e);
220: return ""; //$NON-NLS-1$
221: } catch (TemplateException e) {
222: JavaPlugin.log(e);
223: return ""; //$NON-NLS-1$
224: }
225: if (buffer == null)
226: return ""; //$NON-NLS-1$
227:
228: return buffer.getString();
229: }
230:
231: private String indent(String code, String indent) {
232: if (code.length() == 0)
233: return code;
234:
235: StringBuffer buf = new StringBuffer();
236: buf.append(indent);
237: char[] codeArray = code.toCharArray();
238: for (int i = 0; i < codeArray.length; i++) {
239: buf.append(codeArray[i]);
240: if (codeArray[i] == '\n')
241: buf.append(indent);
242: }
243: buf.append("\n"); //$NON-NLS-1$
244:
245: return buf.toString();
246: }
247:
248: }
|