| /******************************************************************************* |
| * Copyright (c) 2000, 2005 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.corext.codemanipulation; |
| |
| import org.eclipse.text.edits.InsertEdit; |
| import org.eclipse.text.edits.MultiTextEdit; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.core.runtime.SubProgressMonitor; |
| import org.eclipse.core.runtime.jobs.ISchedulingRule; |
| |
| import org.eclipse.core.filebuffers.FileBuffers; |
| import org.eclipse.core.filebuffers.ITextFileBufferManager; |
| |
| import org.eclipse.core.resources.IWorkspaceRunnable; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| |
| import org.eclipse.jface.text.BadLocationException; |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.jface.text.IRegion; |
| import org.eclipse.jface.text.TextUtilities; |
| |
| 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.IMember; |
| import org.eclipse.jdt.core.IMethod; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.ITypeHierarchy; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.core.Signature; |
| |
| import org.eclipse.jdt.internal.corext.dom.TokenScanner; |
| import org.eclipse.jdt.internal.corext.util.MethodOverrideTester; |
| import org.eclipse.jdt.internal.corext.util.Strings; |
| import org.eclipse.jdt.internal.corext.util.SuperTypeHierarchyCache; |
| |
| import org.eclipse.jdt.ui.CodeGeneration; |
| |
| import org.eclipse.jdt.internal.ui.JavaUIStatus; |
| |
| /** |
| * Add javadoc stubs to members. All members must belong to the same compilation unit. |
| * If the parent type is open in an editor, be sure to pass over its working copy. |
| */ |
| public class AddJavaDocStubOperation implements IWorkspaceRunnable { |
| |
| private IMember[] fMembers; |
| |
| public AddJavaDocStubOperation(IMember[] members) { |
| super(); |
| fMembers= members; |
| } |
| |
| private String createTypeComment(IType type, String lineDelimiter) throws CoreException { |
| String[] typeParameterNames= StubUtility.getTypeParameterNames(type.getTypeParameters()); |
| return CodeGeneration.getTypeComment(type.getCompilationUnit(), type.getTypeQualifiedName('.'), typeParameterNames, lineDelimiter); |
| } |
| |
| private String createMethodComment(IMethod meth, String lineDelimiter) throws CoreException { |
| IType declaringType= meth.getDeclaringType(); |
| |
| IMethod overridden= null; |
| if (!meth.isConstructor()) { |
| ITypeHierarchy hierarchy= SuperTypeHierarchyCache.getTypeHierarchy(declaringType); |
| MethodOverrideTester tester= new MethodOverrideTester(declaringType, hierarchy); |
| overridden= tester.findOverriddenMethod(meth, true); |
| } |
| return CodeGeneration.getMethodComment(meth, overridden, lineDelimiter); |
| } |
| |
| private String createFieldComment(IField field, String lineDelimiter) throws JavaModelException, CoreException { |
| String typeName= Signature.toString(field.getTypeSignature()); |
| String fieldName= field.getElementName(); |
| return CodeGeneration.getFieldComment(field.getCompilationUnit(), typeName, fieldName, lineDelimiter); |
| } |
| |
| /** |
| * @return Returns the scheduling rule for this operation |
| */ |
| public ISchedulingRule getScheduleRule() { |
| return ResourcesPlugin.getWorkspace().getRoot(); |
| } |
| |
| /** |
| * Runs the operation. |
| * @throws OperationCanceledException Runtime error thrown when operation is cancelled. |
| */ |
| public void run(IProgressMonitor monitor) throws CoreException, OperationCanceledException { |
| if (monitor == null) { |
| monitor= new NullProgressMonitor(); |
| } |
| if (fMembers.length == 0) { |
| return; |
| } |
| try { |
| monitor.beginTask(CodeGenerationMessages.AddJavaDocStubOperation_description, fMembers.length + 2); |
| |
| addJavadocComments(monitor); |
| } finally { |
| monitor.done(); |
| } |
| } |
| |
| private void addJavadocComments(IProgressMonitor monitor) throws CoreException { |
| ICompilationUnit cu= fMembers[0].getCompilationUnit(); |
| |
| ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager(); |
| IPath path= cu.getPath(); |
| |
| manager.connect(path, new SubProgressMonitor(monitor, 1)); |
| try { |
| IDocument document= manager.getTextFileBuffer(path).getDocument(); |
| |
| String lineDelim= TextUtilities.getDefaultLineDelimiter(document); |
| MultiTextEdit edit= new MultiTextEdit(); |
| |
| for (int i= 0; i < fMembers.length; i++) { |
| IMember curr= fMembers[i]; |
| int memberStartOffset= getMemberStartOffset(curr, document); |
| |
| String comment= null; |
| switch (curr.getElementType()) { |
| case IJavaElement.TYPE: |
| comment= createTypeComment((IType) curr, lineDelim); |
| break; |
| case IJavaElement.FIELD: |
| comment= createFieldComment((IField) curr, lineDelim); |
| break; |
| case IJavaElement.METHOD: |
| comment= createMethodComment((IMethod) curr, lineDelim); |
| break; |
| } |
| if (comment == null) { |
| StringBuffer buf= new StringBuffer(); |
| buf.append("/**").append(lineDelim); //$NON-NLS-1$ |
| buf.append(" *").append(lineDelim); //$NON-NLS-1$ |
| buf.append(" */").append(lineDelim); //$NON-NLS-1$ |
| comment= buf.toString(); |
| } else { |
| if (!comment.endsWith(lineDelim)) { |
| comment= comment + lineDelim; |
| } |
| } |
| |
| final IJavaProject project= cu.getJavaProject(); |
| IRegion region= document.getLineInformationOfOffset(memberStartOffset); |
| |
| String line= document.get(region.getOffset(), region.getLength()); |
| String indentString= Strings.getIndentString(line, project); |
| |
| String indentedComment= Strings.changeIndent(comment, 0, project, indentString, lineDelim); |
| |
| edit.addChild(new InsertEdit(memberStartOffset, indentedComment)); |
| |
| monitor.worked(1); |
| } |
| edit.apply(document); // apply all edits |
| } catch (BadLocationException e) { |
| throw new CoreException(JavaUIStatus.createError(IStatus.ERROR, e)); |
| } finally { |
| manager.disconnect(path, new SubProgressMonitor(monitor, 1)); |
| } |
| } |
| |
| private int getMemberStartOffset(IMember curr, IDocument document) throws JavaModelException { |
| int offset= curr.getSourceRange().getOffset(); |
| TokenScanner scanner= new TokenScanner(document); |
| try { |
| return scanner.getNextStartOffset(offset, true); // read to the first real non comment token |
| } catch (CoreException e) { |
| // ignore |
| } |
| return offset; |
| } |
| |
| } |