1 11 package org.eclipse.jdt.internal.ui.compare; 12 13 import java.util.ArrayList ; 14 import java.util.HashMap ; 15 import java.util.Iterator ; 16 import java.util.List ; 17 import java.util.Map ; 18 19 import org.eclipse.core.runtime.CoreException; 20 import org.eclipse.core.runtime.IProgressMonitor; 21 import org.eclipse.core.runtime.IStatus; 22 23 import org.eclipse.core.resources.IResource; 24 25 import org.eclipse.swt.widgets.Shell; 26 27 import org.eclipse.jface.text.Document; 28 import org.eclipse.jface.text.IDocument; 29 import org.eclipse.jface.text.IDocumentPartitioner; 30 31 import org.eclipse.ui.services.IDisposable; 32 33 import org.eclipse.compare.CompareUI; 34 import org.eclipse.compare.IEditableContent; 35 import org.eclipse.compare.IEditableContentExtension; 36 import org.eclipse.compare.IResourceProvider; 37 import org.eclipse.compare.ISharedDocumentAdapter; 38 import org.eclipse.compare.IStreamContentAccessor; 39 import org.eclipse.compare.structuremergeviewer.DiffNode; 40 import org.eclipse.compare.structuremergeviewer.Differencer; 41 import org.eclipse.compare.structuremergeviewer.DocumentRangeNode; 42 import org.eclipse.compare.structuremergeviewer.ICompareInput; 43 import org.eclipse.compare.structuremergeviewer.IDiffContainer; 44 import org.eclipse.compare.structuremergeviewer.IDiffElement; 45 import org.eclipse.compare.structuremergeviewer.IStructureComparator; 46 import org.eclipse.compare.structuremergeviewer.StructureCreator; 47 import org.eclipse.compare.structuremergeviewer.StructureRootNode; 48 49 import org.eclipse.jdt.core.ICompilationUnit; 50 import org.eclipse.jdt.core.IJavaElement; 51 import org.eclipse.jdt.core.IJavaProject; 52 import org.eclipse.jdt.core.JavaCore; 53 import org.eclipse.jdt.core.ToolFactory; 54 import org.eclipse.jdt.core.compiler.IScanner; 55 import org.eclipse.jdt.core.compiler.ITerminalSymbols; 56 import org.eclipse.jdt.core.compiler.InvalidInputException; 57 import org.eclipse.jdt.core.dom.AST; 58 import org.eclipse.jdt.core.dom.ASTParser; 59 import org.eclipse.jdt.core.dom.CompilationUnit; 60 61 import org.eclipse.jdt.ui.text.IJavaPartitions; 62 63 import org.eclipse.jdt.internal.ui.JavaPlugin; 64 65 66 public class JavaStructureCreator extends StructureCreator { 67 68 private Map fDefaultCompilerOptions; 69 70 74 private final class RootJavaNode extends JavaNode implements IDisposable { 75 76 private final Object fInput; 77 private final boolean fEditable; 78 private final ISharedDocumentAdapter fAdapter; 79 80 private RootJavaNode(IDocument document, boolean editable, Object input, ISharedDocumentAdapter adapter) { 81 super(document); 82 this.fEditable = editable; 83 fInput= input; 84 fAdapter= adapter; 85 } 86 87 90 public boolean isEditable() { 91 return fEditable; 92 } 93 94 97 protected void nodeChanged(DocumentRangeNode node) { 98 save(this, fInput); 99 } 100 101 104 public void dispose() { 105 if (fAdapter != null) { 106 fAdapter.disconnect(fInput); 107 } 108 } 109 110 113 public Object getAdapter(Class adapter) { 114 if (adapter == ISharedDocumentAdapter.class) { 115 return fAdapter; 116 } 117 return super.getAdapter(adapter); 118 } 119 120 121 124 public boolean isReadOnly() { 125 if (fInput instanceof IEditableContentExtension) { 126 IEditableContentExtension ext = (IEditableContentExtension) fInput; 127 return ext.isReadOnly(); 128 } 129 return super.isReadOnly(); 130 } 131 132 135 public IStatus validateEdit(Shell shell) { 136 if (fInput instanceof IEditableContentExtension) { 137 IEditableContentExtension ext = (IEditableContentExtension) fInput; 138 return ext.validateEdit(shell); 139 } 140 return super.validateEdit(shell); 141 } 142 } 143 144 148 static class RewriteInfo { 149 150 boolean fIsOut= false; 151 152 JavaNode fAncestor= null; 153 JavaNode fLeft= null; 154 JavaNode fRight= null; 155 156 ArrayList fChildren= new ArrayList (); 157 158 void add(IDiffElement diff) { 159 fChildren.add(diff); 160 } 161 162 void setDiff(ICompareInput diff) { 163 if (fIsOut) 164 return; 165 166 fIsOut= true; 167 168 JavaNode a= (JavaNode) diff.getAncestor(); 169 JavaNode y= (JavaNode) diff.getLeft(); 170 JavaNode m= (JavaNode) diff.getRight(); 171 172 if (a != null) { 173 if (fAncestor != null) 174 return; 175 fAncestor= a; 176 } 177 if (y != null) { 178 if (fLeft != null) 179 return; 180 fLeft= y; 181 } 182 if (m != null) { 183 if (fRight != null) 184 return; 185 fRight= m; 186 } 187 188 fIsOut= false; 189 } 190 191 194 boolean matches() { 195 return !fIsOut && fAncestor != null && fLeft != null && fRight != null; 196 } 197 } 198 199 public JavaStructureCreator() { 200 } 201 202 void setDefaultCompilerOptions(Map compilerSettings) { 203 fDefaultCompilerOptions= compilerSettings; 204 } 205 206 209 public String getName() { 210 return CompareMessages.JavaStructureViewer_title; 211 } 212 213 218 public IStructureComparator getStructure(final Object input) { 219 String contents= null; 220 char[] buffer= null; 221 IDocument doc= CompareUI.getDocument(input); 222 if (doc == null) { 223 if (input instanceof IStreamContentAccessor) { 224 IStreamContentAccessor sca= (IStreamContentAccessor) input; 225 try { 226 contents= JavaCompareUtilities.readString(sca); 227 } catch (CoreException ex) { 228 return null; 230 } 231 } 232 233 if (contents != null) { 234 int n= contents.length(); 235 buffer= new char[n]; 236 contents.getChars(0, n, buffer, 0); 237 238 doc= new Document(contents); 239 setupDocument(doc); 240 } 241 } 242 243 return createStructureComparator(input, buffer, doc, null, null); 244 } 245 246 249 protected IStructureComparator createStructureComparator(Object element, 250 IDocument document, ISharedDocumentAdapter sharedDocumentAdapter, 251 IProgressMonitor monitor) throws CoreException { 252 return createStructureComparator(element, null, document, sharedDocumentAdapter, monitor); 253 } 254 255 private IStructureComparator createStructureComparator(final Object input, char[] buffer, IDocument doc, ISharedDocumentAdapter adapter, IProgressMonitor monitor) { 256 String contents; 257 Map compilerOptions= null; 258 259 if (input instanceof IResourceProvider) { 260 IResource resource= ((IResourceProvider) input).getResource(); 261 if (resource != null) { 262 IJavaElement element= JavaCore.create(resource); 263 if (element != null) { 264 IJavaProject javaProject= element.getJavaProject(); 265 if (javaProject != null) 266 compilerOptions= javaProject.getOptions(true); 267 } 268 } 269 } 270 if (compilerOptions == null) 271 compilerOptions= fDefaultCompilerOptions; 272 273 if (doc != null) { 274 boolean isEditable= false; 275 if (input instanceof IEditableContent) 276 isEditable= ((IEditableContent) input).isEditable(); 277 278 JavaNode root= new RootJavaNode(doc, isEditable, input, adapter); 280 281 if (buffer == null) { 282 contents= doc.get(); 283 int n= contents.length(); 284 buffer= new char[n]; 285 contents.getChars(0, n, buffer, 0); 286 } 287 288 ASTParser parser= ASTParser.newParser(AST.JLS3); 289 if (compilerOptions != null) 290 parser.setCompilerOptions(compilerOptions); 291 parser.setSource(buffer); 292 parser.setFocalPosition(0); 293 CompilationUnit cu= (CompilationUnit) parser.createAST(monitor); 294 cu.accept(new JavaParseTreeBuilder(root, buffer, true)); 295 296 return root; 297 } 298 return null; 299 } 300 301 310 public String getContents(Object node, boolean ignoreWhiteSpace) { 311 312 if (! (node instanceof IStreamContentAccessor)) 313 return null; 314 315 IStreamContentAccessor sca= (IStreamContentAccessor) node; 316 String content= null; 317 try { 318 content= JavaCompareUtilities.readString(sca); 319 } catch (CoreException ex) { 320 JavaPlugin.log(ex); 321 return null; 322 } 323 324 if (ignoreWhiteSpace) { 326 StringBuffer buf= new StringBuffer (); 328 char[] b= content.toCharArray(); 329 330 IScanner scanner= ToolFactory.createScanner(true, true, false, false); scanner.setSource(b); 334 try { 335 int token; 336 while ((token= scanner.getNextToken()) != ITerminalSymbols.TokenNameEOF) { 337 switch (token) { 338 case ITerminalSymbols.TokenNameWHITESPACE: 339 int l= buf.length(); 340 if (l > 0 && buf.charAt(l-1) != ' ') 341 buf.append(' '); 342 break; 343 default: 344 buf.append(scanner.getCurrentTokenSource()); 345 buf.append(' '); 346 break; 347 } 348 } 349 content= buf.toString(); } catch (InvalidInputException ex) { 351 } 353 } 354 return content; 355 } 356 357 361 public boolean canRewriteTree() { 362 return true; 363 } 364 365 371 public void rewriteTree(Differencer differencer, IDiffContainer root) { 372 373 HashMap map= new HashMap (10); 374 375 Object [] children= root.getChildren(); 376 for (int i= 0; i < children.length; i++) { 377 DiffNode diff= (DiffNode) children[i]; 378 JavaNode jn= (JavaNode) diff.getId(); 379 380 if (jn == null) 381 continue; 382 int type= jn.getTypeCode(); 383 384 if (type == JavaNode.METHOD || type == JavaNode.CONSTRUCTOR) { 386 387 String name= jn.extractMethodName(); 389 RewriteInfo nameInfo= (RewriteInfo) map.get(name); 390 if (nameInfo == null) { 391 nameInfo= new RewriteInfo(); 392 map.put(name, nameInfo); 393 } 394 nameInfo.add(diff); 395 396 String argList= jn.extractArgumentList(); 399 RewriteInfo argInfo= null; 400 if (argList != null && !argList.equals("()")) { argInfo= (RewriteInfo) map.get(argList); 402 if (argInfo == null) { 403 argInfo= new RewriteInfo(); 404 map.put(argList, argInfo); 405 } 406 argInfo.add(diff); 407 } 408 409 switch (diff.getKind() & Differencer.CHANGE_TYPE_MASK) { 410 case Differencer.ADDITION: 411 case Differencer.DELETION: 412 if (type != JavaNode.CONSTRUCTOR) 416 nameInfo.setDiff(diff); 417 418 if (argInfo != null) 419 argInfo.setDiff(diff); 420 break; 421 default: 422 break; 423 } 424 } 425 426 rewriteTree(differencer, diff); 428 } 429 430 Iterator it= map.keySet().iterator(); 433 while (it.hasNext()) { 434 String name= (String ) it.next(); 435 RewriteInfo i= (RewriteInfo) map.get(name); 436 if (i.matches()) { 438 DiffNode d= (DiffNode) differencer.findDifferences(true, null, root, i.fAncestor, i.fLeft, i.fRight); 441 if (d != null) { d.setDontExpand(true); 443 Iterator it2= i.fChildren.iterator(); 444 while (it2.hasNext()) { 445 IDiffElement rd= (IDiffElement) it2.next(); 446 root.removeToRoot(rd); 447 d.add(rd); 448 } 449 } 450 } 451 } 452 } 453 454 461 static boolean hasEdition(IJavaElement je) { 462 return JavaElementHistoryPageSource.hasEdition(je); 463 } 464 465 468 protected IDocumentPartitioner getDocumentPartitioner() { 469 return JavaCompareUtilities.createJavaPartitioner(); 470 } 471 472 475 protected String getDocumentPartitioning() { 476 return IJavaPartitions.JAVA_PARTITIONING; 477 } 478 479 482 protected String [] getPath(Object element, Object input) { 483 if (element instanceof IJavaElement) { 484 IJavaElement je = (IJavaElement) element; 485 List args= new ArrayList (); 488 while (je != null) { 489 String name= JavaCompareUtilities.getJavaElementID(je); 492 if (name == null) 493 return null; 494 args.add(name); 495 if (je instanceof ICompilationUnit) 496 break; 497 je= je.getParent(); 498 } 499 500 int n= args.size(); 502 String [] path= new String [n]; 503 for (int i= 0; i < n; i++) 504 path[i]= (String ) args.get(n-1-i); 505 506 return path; 507 } 508 return null; 509 } 510 } 511 | Popular Tags |