/** * */ package org.objectstyle.wolips.wodclipse.core.refactoring; import org.eclipse.core.runtime.CoreException; 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.IJavaProject; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.NamingConventions; import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.core.formatter.CodeFormatter; import org.eclipse.jdt.internal.core.CreateFieldOperation; import org.eclipse.jdt.internal.core.CreateImportOperation; import org.eclipse.jdt.internal.core.CreateMethodOperation; import org.eclipse.jdt.internal.core.JavaModelOperation; import org.eclipse.jdt.internal.corext.codemanipulation.GetterSetterUtil; import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil; import org.eclipse.jdt.internal.corext.util.JavaModelUtil; import org.eclipse.jdt.ui.JavaUI; import org.eclipse.jface.text.IRewriteTarget; import org.eclipse.ui.IEditorPart; import org.objectstyle.wolips.bindings.utils.BindingReflectionUtils; public class AddKeyOperation extends JavaModelOperation { public static void addKey(AddKeyInfo info) throws CoreException { IEditorPart editorPart = JavaUI.openInEditor(info.getComponentType().getCompilationUnit()); if (editorPart != null) { IRewriteTarget target = (IRewriteTarget) editorPart.getAdapter(IRewriteTarget.class); if (target != null) { target.beginCompoundChange(); } try { new AddKeyOperation(info).run(null); } finally { if (target != null) { target.endCompoundChange(); } } } } public static void replaceField(AddKeyInfo info, String originalName) throws CoreException { IEditorPart editorPart = JavaUI.openInEditor(info.getComponentType().getCompilationUnit()); if (editorPart != null) { IRewriteTarget target = (IRewriteTarget) editorPart.getAdapter(IRewriteTarget.class); if (target != null) { target.beginCompoundChange(); } try { String newName = info.getName(); info.setName(originalName); String originalFieldName = info.getFieldName(); info.setName(newName); // This is less than ideal, but will do for now. At least this way the field order // should remain the same. IField originalField = info.getComponentType().getField(originalFieldName); if (info.isCreateField() && originalField.exists()) { AddKeyOperation op = new AddKeyOperation(info); op._sibling = originalField; op._force = true; op.run(null); originalField.delete(false, null); } } finally { if (target != null) { target.endCompoundChange(); } } } } private boolean _force = false; private AddKeyInfo _info; private IJavaElement _sibling; public AddKeyOperation(AddKeyInfo info) { super(new IJavaElement[] { info.getComponentType() }); _info = info; } private void createAccessor(String simpleTypeName, String fieldName) throws JavaModelException { boolean isBoolean = BindingReflectionUtils.isBoolean(_info.getJavaTypeName()); IType componentType = getComponentType(); String accessorMethodName; if (_info.isPrependGetToAccessorMethod()) { accessorMethodName = NamingConventions.suggestGetterName(componentType.getJavaProject(), fieldName, Flags.AccPublic, isBoolean, null); } else { accessorMethodName = _info.getName(); } String source = null; if (_info.isCreateField()) { try { source = GetterSetterUtil.getGetterStub(componentType.getField(fieldName), accessorMethodName, true, Flags.AccPublic); } catch (CoreException e) { throw new JavaModelException(e); } } else { source = "public " + simpleTypeName + " " + accessorMethodName + "() {\n" + " // TODO\n" + "return null;\n" + "}"; } if (source != null) { String lineDelim = "\n";// TextUtilities.getDefaultLineDelimiter(document); source = CodeFormatterUtil.format(CodeFormatter.K_CLASS_BODY_DECLARATIONS, source, 1, null, componentType.getJavaProject()); new CreateMethodOperation(componentType, source, false).runOperation(progressMonitor); } } private void createField(String simpleTypeName, String fieldName) throws JavaModelException { IType componentType = getComponentType(); String accessModifier = "private "; if (!(_info.isCreateAccessorMethod() || _info.isCreateMutatorMethod())) { accessModifier = "public "; } String keyField = accessModifier + simpleTypeName + " " + fieldName + ";"; CreateFieldOperation op = new CreateFieldOperation(componentType, keyField, _force); if (_sibling != null) { op.createAfter(_sibling); } op.runOperation(progressMonitor); } private void createImports(String keyType, String keyParameterType) throws JavaModelException { if (BindingReflectionUtils.isImportRequired(keyType)) { new CreateImportOperation(keyType, getCompilationUnit(), Flags.AccDefault).runOperation(progressMonitor); } if (BindingReflectionUtils.isImportRequired(keyParameterType)) { new CreateImportOperation(keyParameterType, getCompilationUnit(), Flags.AccDefault).runOperation(progressMonitor); } } private void createMutator(String simpleTypeName, String fieldName) throws JavaModelException { boolean isBoolean = BindingReflectionUtils.isBoolean(_info.getJavaTypeName()); IType componentType = getComponentType(); String mutatorMethodName = NamingConventions.suggestSetterName(getJavaProject(), fieldName, Flags.AccPublic, isBoolean, null); String source = null; if (_info.isCreateField()) { try { source = GetterSetterUtil.getSetterStub(componentType.getField(fieldName), mutatorMethodName, true, Flags.AccPublic); } catch (CoreException e) { throw new JavaModelException(e); } } else { source = "public void " + mutatorMethodName + "(" + simpleTypeName + " " + _info.getName() + ") {\n" + " // TODO\n" + "}"; } if (source != null) { String lineDelim = "\n";// TextUtilities.getDefaultLineDelimiter(document); source = CodeFormatterUtil.format(CodeFormatter.K_CLASS_BODY_DECLARATIONS, source, 1, null, getJavaProject()); new CreateMethodOperation(componentType, source, false).runOperation(progressMonitor); } } @Override protected void executeOperation() throws JavaModelException { String keyType = _info.getJavaTypeName(); String keyParameterType = _info.getJavaParameterTypeName(); String simpleTypeName = simpleTypeName(keyType, keyParameterType); String fieldName = _info.getFieldName(); createImports(keyType, keyParameterType); if (_info.isCreateField()) { createField(simpleTypeName, fieldName); } if (_info.isCreateAccessorMethod()) { createAccessor(simpleTypeName, fieldName); } if (_info.isCreateMutatorMethod()) { createMutator(simpleTypeName, fieldName); } } private ICompilationUnit getCompilationUnit() { return _info.getComponentType().getCompilationUnit(); } private IType getComponentType() { return _info.getComponentType(); } private IJavaProject getJavaProject() { return _info.getComponentType().getJavaProject(); } private String simpleTypeName(String keyType, String keyParameterType) { boolean useGenerics = JavaModelUtil.is50OrHigher(getJavaProject()); String simpleTypeName; if (keyParameterType != null && useGenerics) { simpleTypeName = Signature.getSimpleName(keyType) + "<" + Signature.getSimpleName(keyParameterType) + ">"; } else { simpleTypeName = Signature.getSimpleName(keyType); } return simpleTypeName; } }