1 11 package org.eclipse.team.internal.ccvs.core.util; 12 13 import java.util.HashSet ; 14 import java.util.Set ; 15 16 import org.eclipse.core.resources.IContainer; 17 import org.eclipse.core.resources.IFile; 18 import org.eclipse.core.resources.IResource; 19 import org.eclipse.core.resources.IResourceChangeEvent; 20 import org.eclipse.core.resources.IResourceChangeListener; 21 import org.eclipse.core.resources.IResourceDelta; 22 import org.eclipse.core.resources.IResourceDeltaVisitor; 23 import org.eclipse.core.runtime.CoreException; 24 import org.eclipse.core.runtime.Path; 25 import org.eclipse.team.internal.ccvs.core.*; 26 import org.eclipse.team.internal.ccvs.core.CVSException; 27 import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin; 28 import org.eclipse.team.internal.ccvs.core.ICVSFile; 29 import org.eclipse.team.internal.ccvs.core.Policy; 30 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; 31 import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer; 32 import org.eclipse.team.internal.ccvs.core.syncinfo.DeferredResourceChangeHandler; 33 34 56 public class SyncFileChangeListener implements IResourceChangeListener { 57 58 protected int INTERESTING_CHANGES = IResourceDelta.CONTENT | 60 IResourceDelta.MOVED_FROM | 61 IResourceDelta.MOVED_TO | 62 IResourceDelta.OPEN | 63 IResourceDelta.REPLACED | 64 IResourceDelta.TYPE; 65 66 protected boolean isProjectOpening = false; 67 68 protected static DeferredResourceChangeHandler deferredHandler = new DeferredResourceChangeHandler(); 69 70 75 public static DeferredResourceChangeHandler getDeferredHandler() { 76 return deferredHandler; 77 } 78 79 87 public void resourceChanged(IResourceChangeEvent event) { 88 try { 89 final Set changedContainers = new HashSet (); 90 final Set externalDeletions = new HashSet (); 91 92 setProjectOpening(false); 93 94 event.getDelta().accept(new IResourceDeltaVisitor() { 95 96 public boolean visit(IResourceDelta delta) { 97 IResource resource = delta.getResource(); 98 99 if(resource.getType()==IResource.ROOT) { 100 return true; 102 } 103 104 if (resource.getType() == IResource.PROJECT) { 105 if (!resource.isAccessible()) return false; 107 setProjectOpening((delta.getFlags() & IResourceDelta.OPEN) != 0); 108 } 109 110 String name = resource.getName(); 111 int kind = delta.getKind(); 112 113 if(kind == IResourceDelta.CHANGED && 116 (delta.getFlags() & INTERESTING_CHANGES) == 0) { 117 return true; 118 } 119 120 if(name.equals(SyncFileWriter.CVS_DIRNAME)) { 121 handleCVSDir((IContainer)resource, kind); 122 if(isProjectOpening()) return false; 125 } else { 126 if(isProjectOpening()) return true; 128 } 129 130 if(isMetaFile(resource)) { 131 IResource[] toBeNotified = handleChangedMetaFile(resource); 132 if(toBeNotified.length>0 && isModifiedBy3rdParty(resource)) { 133 for (int i = 0; i < toBeNotified.length; i++) { 134 changedContainers.add(toBeNotified[i]); 135 } 136 if(Policy.DEBUG_METAFILE_CHANGES) { 137 System.out.println("[cvs] metafile changed by 3rd party: " + resource.getFullPath()); } 139 return false; 140 } 141 } else if(isIgnoreFile(resource) && isModifiedBy3rdParty(resource)) { 142 deferredHandler.ignoreFileChanged((IFile)resource); 143 } else if (isExternalDeletion(resource, kind)) { 144 externalDeletions.add(resource); 145 } else if (kind == IResourceDelta.ADDED && isRecreation(resource)) { 146 deferredHandler.recreated(resource); 147 } 148 return true; 149 } 150 }, IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS); 151 152 if(!changedContainers.isEmpty() || !externalDeletions.isEmpty()) { 153 EclipseSynchronizer.getInstance().syncFilesChangedExternally( 154 (IContainer[])changedContainers.toArray(new IContainer[changedContainers.size()]), 155 (IFile[]) externalDeletions.toArray(new IFile[externalDeletions.size()])); 156 } 157 } catch(CoreException e) { 158 CVSProviderPlugin.log(e); 159 } 160 } 161 162 176 protected boolean isExternalDeletion(IResource resource, int kind) { 177 if (kind != IResourceDelta.REMOVED) return false; 178 if (resource.getType() != IResource.FILE) return false; 179 ICVSFile file = CVSWorkspaceRoot.getCVSFileFor((IFile)resource); 180 try { 181 return (!file.isManaged() && file.getParent().isCVSFolder() && file.getParent().exists()); 182 } catch (CVSException e) { 183 CVSProviderPlugin.log(e); 184 return false; 185 } 186 } 187 188 192 protected boolean isModifiedBy3rdParty(IResource resource) { 193 if(!resource.exists()) return true; 194 long modStamp = resource.getModificationStamp(); 195 Long whenWeWrote; 196 try { 197 whenWeWrote = (Long )resource.getSessionProperty(SyncFileWriter.MODSTAMP_KEY); 198 } catch(CoreException e) { 199 CVSProviderPlugin.log(e); 200 whenWeWrote = null; 201 } 202 return (whenWeWrote==null || whenWeWrote.longValue() != modStamp); 203 } 204 205 209 protected void handleCVSDir(IContainer cvsDir, int kind) { 210 if((kind & IResourceDelta.ALL_WITH_PHANTOMS)!=0) { 211 if(kind==IResourceDelta.ADDED) { 212 IFile rootFile = cvsDir.getFile(new Path(SyncFileWriter.ROOT)); 214 IFile repositoryFile = cvsDir.getFile(new Path(SyncFileWriter.REPOSITORY)); 215 if(rootFile.exists() && repositoryFile.exists() && !cvsDir.isTeamPrivateMember()) { 216 try { 217 cvsDir.setTeamPrivateMember(true); 219 if(Policy.DEBUG_METAFILE_CHANGES) { 220 System.out.println("[cvs] found a new CVS meta folder, marking as team-private: " + cvsDir.getFullPath()); } 222 } catch(CoreException e) { 223 CVSProviderPlugin.log(CVSException.wrapException(cvsDir, CVSMessages.SyncFileChangeListener_errorSettingTeamPrivateFlag, e)); 224 } 225 } 226 } 227 } 228 } 229 230 protected boolean isIgnoreFile(IResource resource) { 231 return resource.getType() == IResource.FILE && 232 resource.getName().equals(SyncFileWriter.IGNORE_FILE); 233 } 234 235 private boolean isRecreation(IResource resource) { 236 return EclipseSynchronizer.getInstance().wasPhantom(resource); 237 } 238 239 242 protected boolean isMetaFile(IResource resource) { 243 IContainer parent = resource.getParent(); 244 return resource.getType() == IResource.FILE && 245 parent!=null && 246 parent.getName().equals(SyncFileWriter.CVS_DIRNAME) && 247 (parent.isTeamPrivateMember() || !parent.exists()); 248 } 249 250 255 protected IContainer[] handleChangedMetaFile(IResource resource) { 256 IContainer changedContainer = resource.getParent().getParent(); 257 if(changedContainer.exists()) { 258 return new IContainer[] {changedContainer}; 259 } else { 260 return new IContainer[0]; 261 } 262 } 263 264 267 public boolean isProjectOpening() { 268 return isProjectOpening; 269 } 270 271 275 public void setProjectOpening(boolean isProjectOpening) { 276 this.isProjectOpening = isProjectOpening; 277 } 278 } 279 | Popular Tags |