1 11 package org.eclipse.jdt.internal.core; 12 13 import java.util.List ; 14 import java.util.Map ; 15 16 import org.eclipse.jdt.core.ICompilationUnit; 17 import org.eclipse.jdt.core.IJavaElement; 18 import org.eclipse.jdt.core.IJavaModelStatus; 19 import org.eclipse.jdt.core.IJavaModelStatusConstants; 20 import org.eclipse.jdt.core.IJavaProject; 21 import org.eclipse.jdt.core.IType; 22 import org.eclipse.jdt.core.JavaModelException; 23 import org.eclipse.jdt.core.dom.AST; 24 import org.eclipse.jdt.core.dom.ASTNode; 25 import org.eclipse.jdt.core.dom.ASTParser; 26 import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration; 27 import org.eclipse.jdt.core.dom.CompilationUnit; 28 import org.eclipse.jdt.core.dom.EnumDeclaration; 29 import org.eclipse.jdt.core.dom.SimpleName; 30 import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; 31 import org.eclipse.jdt.core.dom.TypeDeclaration; 32 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; 33 import org.eclipse.jdt.core.formatter.IndentManipulation; 34 import org.eclipse.jdt.internal.compiler.parser.ScannerHelper; 35 import org.eclipse.jface.text.IDocument; 36 import org.eclipse.jface.text.TextUtilities; 37 38 42 public abstract class CreateTypeMemberOperation extends CreateElementInCUOperation { 43 46 protected String source = null; 47 52 protected String alteredName; 53 57 protected ASTNode createdNode; 58 62 public CreateTypeMemberOperation(IJavaElement parentElement, String source, boolean force) { 63 super(parentElement); 64 this.source = source; 65 this.force = force; 66 } 67 protected StructuralPropertyDescriptor getChildPropertyDescriptor(ASTNode parent) { 68 switch (parent.getNodeType()) { 69 case ASTNode.COMPILATION_UNIT: 70 return CompilationUnit.TYPES_PROPERTY; 71 case ASTNode.ENUM_DECLARATION: 72 return EnumDeclaration.BODY_DECLARATIONS_PROPERTY; 73 case ASTNode.ANNOTATION_TYPE_DECLARATION: 74 return AnnotationTypeDeclaration.BODY_DECLARATIONS_PROPERTY; 75 default: 76 return TypeDeclaration.BODY_DECLARATIONS_PROPERTY; 77 } 78 } 79 protected ASTNode generateElementAST(ASTRewrite rewriter, IDocument document, ICompilationUnit cu) throws JavaModelException { 80 if (this.createdNode == null) { 81 this.source = removeIndentAndNewLines(this.source, document, cu); 82 ASTParser parser = ASTParser.newParser(AST.JLS3); 83 parser.setSource(this.source.toCharArray()); 84 parser.setProject(getCompilationUnit().getJavaProject()); 85 parser.setKind(ASTParser.K_CLASS_BODY_DECLARATIONS); 86 ASTNode node = parser.createAST(this.progressMonitor); 87 String createdNodeSource; 88 if (node.getNodeType() != ASTNode.TYPE_DECLARATION) { 89 createdNodeSource = generateSyntaxIncorrectAST(); 90 if (this.createdNode == null) 91 throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS)); 92 } else { 93 TypeDeclaration typeDeclaration = (TypeDeclaration) node; 94 this.createdNode = (ASTNode) typeDeclaration.bodyDeclarations().iterator().next(); 95 createdNodeSource = this.source; 96 } 97 if (this.alteredName != null) { 98 SimpleName newName = this.createdNode.getAST().newSimpleName(this.alteredName); 99 SimpleName oldName = rename(this.createdNode, newName); 100 int nameStart = oldName.getStartPosition(); 101 int nameEnd = nameStart + oldName.getLength(); 102 StringBuffer newSource = new StringBuffer (); 103 if (this.source.equals(createdNodeSource)) { 104 newSource.append(createdNodeSource.substring(0, nameStart)); 105 newSource.append(this.alteredName); 106 newSource.append(createdNodeSource.substring(nameEnd)); 107 } else { 108 int createdNodeStart = this.createdNode.getStartPosition(); 110 int createdNodeEnd = createdNodeStart + this.createdNode.getLength(); 111 newSource.append(createdNodeSource.substring(createdNodeStart, nameStart)); 112 newSource.append(this.alteredName); 113 newSource.append(createdNodeSource.substring(nameEnd, createdNodeEnd)); 114 115 } 116 this.source = newSource.toString(); 117 } 118 } 119 if (rewriter == null) return this.createdNode; 120 return rewriter.createStringPlaceholder(this.source, this.createdNode.getNodeType()); 122 } 123 private String removeIndentAndNewLines(String code, IDocument document, ICompilationUnit cu) { 124 IJavaProject project = cu.getJavaProject(); 125 Map options = project.getOptions(true); 126 int tabWidth = IndentManipulation.getTabWidth(options); 127 int indentWidth = IndentManipulation.getIndentWidth(options); 128 int indent = IndentManipulation.measureIndentUnits(code, tabWidth, indentWidth); 129 int firstNonWhiteSpace = -1; 130 int length = code.length(); 131 while (firstNonWhiteSpace < length-1) 132 if (!ScannerHelper.isWhitespace(code.charAt(++firstNonWhiteSpace))) 133 break; 134 int lastNonWhiteSpace = length; 135 while (lastNonWhiteSpace > 0) 136 if (!ScannerHelper.isWhitespace(code.charAt(--lastNonWhiteSpace))) 137 break; 138 String lineDelimiter = TextUtilities.getDefaultLineDelimiter(document); 139 return IndentManipulation.changeIndent(code.substring(firstNonWhiteSpace, lastNonWhiteSpace+1), indent, tabWidth, indentWidth, "", lineDelimiter); } 141 145 protected abstract SimpleName rename(ASTNode node, SimpleName newName); 146 151 protected String generateSyntaxIncorrectAST() { 152 StringBuffer buff = new StringBuffer (); 154 IType type = getType(); 155 String lineSeparator = org.eclipse.jdt.internal.core.util.Util.getLineSeparator(this.source, type == null ? null : type.getJavaProject()); 156 buff.append(lineSeparator + " public class A {" + lineSeparator); buff.append(this.source); 158 buff.append(lineSeparator).append('}'); 159 ASTParser parser = ASTParser.newParser(AST.JLS3); 160 parser.setSource(buff.toString().toCharArray()); 161 CompilationUnit compilationUnit = (CompilationUnit) parser.createAST(null); 162 TypeDeclaration typeDeclaration = (TypeDeclaration) compilationUnit.types().iterator().next(); 163 List bodyDeclarations = typeDeclaration.bodyDeclarations(); 164 if (bodyDeclarations.size() != 0) 165 this.createdNode = (ASTNode) bodyDeclarations.iterator().next(); 166 return buff.toString(); 167 } 168 171 protected IType getType() { 172 return (IType)getParentElement(); 173 } 174 179 protected void setAlteredName(String newName) { 180 this.alteredName = newName; 181 } 182 190 public IJavaModelStatus verify() { 191 IJavaModelStatus status = super.verify(); 192 if (!status.isOK()) { 193 return status; 194 } 195 if (this.source == null) { 196 return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS); 197 } 198 if (!force) { 199 try { 201 ICompilationUnit cu = getCompilationUnit(); 202 generateElementAST(null, getDocument(cu), cu); 203 } catch (JavaModelException jme) { 204 return jme.getJavaModelStatus(); 205 } 206 return verifyNameCollision(); 207 } 208 209 return JavaModelStatus.VERIFIED_OK; 210 } 211 214 protected IJavaModelStatus verifyNameCollision() { 215 return JavaModelStatus.VERIFIED_OK; 216 } 217 } 218 | Popular Tags |