1 11 package org.eclipse.jdt.internal.ui.javaeditor; 12 13 14 import java.util.ArrayList ; 15 import java.util.Iterator ; 16 import java.util.List ; 17 18 import org.eclipse.core.runtime.CoreException; 19 import org.eclipse.core.runtime.IProgressMonitor; 20 21 import org.eclipse.core.filebuffers.FileBuffers; 22 import org.eclipse.core.filebuffers.LocationKind; 23 24 import org.eclipse.core.resources.IResource; 25 26 import org.eclipse.jface.text.IDocument; 27 import org.eclipse.jface.text.ISynchronizable; 28 import org.eclipse.jface.text.source.IAnnotationModel; 29 30 import org.eclipse.ui.IEditorInput; 31 import org.eclipse.ui.IFileEditorInput; 32 33 import org.eclipse.ui.editors.text.FileDocumentProvider; 34 35 import org.eclipse.jdt.core.ElementChangedEvent; 36 import org.eclipse.jdt.core.IClassFile; 37 import org.eclipse.jdt.core.IElementChangedListener; 38 import org.eclipse.jdt.core.IJavaElement; 39 import org.eclipse.jdt.core.IJavaElementDelta; 40 import org.eclipse.jdt.core.IJavaProject; 41 import org.eclipse.jdt.core.IPackageFragmentRoot; 42 import org.eclipse.jdt.core.JavaCore; 43 import org.eclipse.jdt.core.JavaModelException; 44 45 import org.eclipse.jdt.ui.text.IJavaPartitions; 46 import org.eclipse.jdt.ui.text.JavaTextTools; 47 48 import org.eclipse.jdt.internal.ui.IResourceLocator; 49 import org.eclipse.jdt.internal.ui.JavaPlugin; 50 51 52 55 public class ClassFileDocumentProvider extends FileDocumentProvider { 56 57 60 public interface InputChangeListener { 61 void inputChanged(IClassFileEditorInput input); 62 } 63 64 67 protected class ClassFileSynchronizer implements IElementChangedListener { 68 69 protected IClassFileEditorInput fInput; 70 protected IPackageFragmentRoot fPackageFragmentRoot; 71 72 75 public ClassFileSynchronizer(IClassFileEditorInput input) { 76 77 fInput= input; 78 79 IJavaElement parent= fInput.getClassFile().getParent(); 80 while (parent != null && !(parent instanceof IPackageFragmentRoot)) { 81 parent= parent.getParent(); 82 } 83 fPackageFragmentRoot= (IPackageFragmentRoot) parent; 84 } 85 86 89 public void install() { 90 JavaCore.addElementChangedListener(this); 91 } 92 93 96 public void uninstall() { 97 JavaCore.removeElementChangedListener(this); 98 } 99 100 103 public void elementChanged(ElementChangedEvent e) { 104 check(fPackageFragmentRoot, e.getDelta()); 105 } 106 107 111 protected boolean check(IPackageFragmentRoot input, IJavaElementDelta delta) { 112 IJavaElement element= delta.getElement(); 113 114 if ((delta.getKind() & IJavaElementDelta.REMOVED) != 0 || (delta.getFlags() & IJavaElementDelta.F_CLOSED) != 0) { 115 if (element.equals(input.getJavaProject()) || element.equals(input)) { 117 handleDeleted(fInput); 118 return true; 119 } 120 } 121 122 if (((delta.getFlags() & IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED) != 0) && input.equals(element)) { 123 handleDeleted(fInput); 124 return true; 125 } 126 127 if (((delta.getFlags() & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) != 0) && input.equals(element)) { 128 handleDeleted(fInput); 129 return true; 130 } 131 132 IJavaElementDelta[] subdeltas= delta.getAffectedChildren(); 133 for (int i= 0; i < subdeltas.length; i++) { 134 if (check(input, subdeltas[i])) 135 return true; 136 } 137 138 if ((delta.getFlags() & IJavaElementDelta.F_SOURCEDETACHED) != 0 || 139 (delta.getFlags() & IJavaElementDelta.F_SOURCEATTACHED) != 0) 140 { 141 IClassFile file= fInput != null ? fInput.getClassFile() : null; 142 IJavaProject project= input != null ? input.getJavaProject() : null; 143 144 boolean isOnClasspath= false; 145 if (file != null && project != null) 146 isOnClasspath= project.isOnClasspath(file); 147 148 if (isOnClasspath) { 149 fireInputChanged(fInput); 150 return false; 151 } else { 152 handleDeleted(fInput); 153 return true; 154 } 155 } 156 157 return false; 158 } 159 } 160 161 164 protected class _FileSynchronizer extends FileSynchronizer { 165 public _FileSynchronizer(IFileEditorInput fileEditorInput) { 166 super(fileEditorInput); 167 } 168 } 169 170 173 protected class ClassFileInfo extends FileInfo { 174 175 ClassFileSynchronizer fClassFileSynchronizer= null; 176 177 ClassFileInfo(IDocument document, IAnnotationModel model, _FileSynchronizer fileSynchronizer) { 178 super(document, model, fileSynchronizer); 179 } 180 181 ClassFileInfo(IDocument document, IAnnotationModel model, ClassFileSynchronizer classFileSynchronizer) { 182 super(document, model, null); 183 fClassFileSynchronizer= classFileSynchronizer; 184 } 185 } 186 187 188 private List fInputListeners= new ArrayList (); 189 190 193 public ClassFileDocumentProvider() { 194 super(); 195 } 196 197 200 protected boolean setDocumentContent(IDocument document, IEditorInput editorInput, String encoding) throws CoreException { 201 if (editorInput instanceof IClassFileEditorInput) { 202 IClassFile classFile= ((IClassFileEditorInput) editorInput).getClassFile(); 203 String source= classFile.getSource(); 204 if (source == null) 205 source= ""; document.set(source); 207 return true; 208 } 209 return super.setDocumentContent(document, editorInput, encoding); 210 } 211 212 219 protected IAnnotationModel createClassFileAnnotationModel(IClassFileEditorInput classFileEditorInput) throws CoreException { 220 IResource resource= null; 221 IClassFile classFile= classFileEditorInput.getClassFile(); 222 223 IResourceLocator locator= (IResourceLocator) classFile.getAdapter(IResourceLocator.class); 224 if (locator != null) 225 resource= locator.getContainingResource(classFile); 226 227 if (resource != null) { 228 ClassFileMarkerAnnotationModel model= new ClassFileMarkerAnnotationModel(resource); 229 model.setClassFile(classFile); 230 return model; 231 } 232 233 return null; 234 } 235 236 240 protected IDocument createEmptyDocument() { 241 IDocument document= FileBuffers.getTextFileBufferManager().createEmptyDocument(null, LocationKind.IFILE); 242 if (document instanceof ISynchronizable) 243 ((ISynchronizable)document).setLockObject(new Object ()); 244 return document; 245 } 246 247 250 protected IDocument createDocument(Object element) throws CoreException { 251 IDocument document= super.createDocument(element); 252 if (document != null) { 253 JavaTextTools tools= JavaPlugin.getDefault().getJavaTextTools(); 254 tools.setupJavaDocumentPartitioner(document, IJavaPartitions.JAVA_PARTITIONING); 255 } 256 return document; 257 } 258 259 262 protected ElementInfo createElementInfo(Object element) throws CoreException { 263 264 if (element instanceof IClassFileEditorInput) { 265 266 IClassFileEditorInput input = (IClassFileEditorInput) element; 267 ExternalClassFileEditorInput external= null; 268 if (input instanceof ExternalClassFileEditorInput) 269 external= (ExternalClassFileEditorInput) input; 270 271 if (external != null) { 272 try { 273 refreshFile(external.getFile()); 274 } catch (CoreException x) { 275 handleCoreException(x, JavaEditorMessages.ClassFileDocumentProvider_error_createElementInfo); 276 } 277 } 278 279 IDocument d= createDocument(input); 280 IAnnotationModel m= createClassFileAnnotationModel(input); 281 282 if (external != null) { 283 ClassFileInfo info= new ClassFileInfo(d, m, (_FileSynchronizer) null); 284 info.fModificationStamp= computeModificationStamp(external.getFile()); 285 info.fEncoding= getPersistedEncoding(element); 286 return info; 287 } else if (input instanceof InternalClassFileEditorInput) { 288 ClassFileSynchronizer s= new ClassFileSynchronizer(input); 289 s.install(); 290 ClassFileInfo info= new ClassFileInfo(d, m, s); 291 info.fEncoding= getPersistedEncoding(element); 292 return info; 293 } 294 } 295 296 return null; 297 } 298 299 302 protected void disposeElementInfo(Object element, ElementInfo info) { 303 ClassFileInfo classFileInfo= (ClassFileInfo) info; 304 if (classFileInfo.fClassFileSynchronizer != null) { 305 classFileInfo.fClassFileSynchronizer.uninstall(); 306 classFileInfo.fClassFileSynchronizer= null; 307 } 308 309 super.disposeElementInfo(element, info); 310 } 311 312 315 protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document) throws CoreException { 316 } 317 318 319 323 public boolean isSynchronized(Object element) { 324 Object elementInfo= getElementInfo(element); 325 if (elementInfo instanceof ClassFileInfo) { 326 IClassFileEditorInput input= (IClassFileEditorInput)element; 327 IResource resource; 328 try { 329 resource= input.getClassFile().getUnderlyingResource(); 330 } catch (JavaModelException e) { 331 return true; 332 } 333 return resource == null || resource.isSynchronized(IResource.DEPTH_ZERO); 334 } 335 return false; 336 } 337 338 342 protected void handleDeleted(IClassFileEditorInput input) { 343 fireElementDeleted(input); 344 } 345 346 349 protected void fireInputChanged(IClassFileEditorInput input) { 350 List list= new ArrayList (fInputListeners); 351 for (Iterator i = list.iterator(); i.hasNext();) 352 ((InputChangeListener) i.next()).inputChanged(input); 353 } 354 355 358 public void addInputChangeListener(InputChangeListener listener) { 359 fInputListeners.add(listener); 360 } 361 362 365 public void removeInputChangeListener(InputChangeListener listener) { 366 fInputListeners.remove(listener); 367 } 368 369 } 370 | Popular Tags |