KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ccvs > core > resources > UpdateContentCachingService


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.team.internal.ccvs.core.resources;
12
13 import java.util.*;
14
15 import org.eclipse.core.resources.IProject;
16 import org.eclipse.core.resources.IResource;
17 import org.eclipse.core.runtime.IProgressMonitor;
18 import org.eclipse.core.runtime.IStatus;
19 import org.eclipse.osgi.util.NLS;
20 import org.eclipse.team.core.RepositoryProvider;
21 import org.eclipse.team.core.TeamException;
22 import org.eclipse.team.internal.ccvs.core.*;
23 import org.eclipse.team.internal.ccvs.core.client.*;
24 import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption;
25 import org.eclipse.team.internal.ccvs.core.client.listeners.*;
26 import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation;
27 import org.eclipse.team.internal.ccvs.core.connection.CVSServerException;
28 import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
29 import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
30
31 /**
32  * This class can be used to fetch and cache file contents for remote files.
33  */

34 public class UpdateContentCachingService implements IUpdateMessageListener {
35
36     private CVSRepositoryLocation repository;
37     private ICVSFolder remoteRoot;
38     private final CVSTag tag;
39     private final int depth;
40     private boolean fetchAbsentDirectories = true;
41     private ArrayList removed = new ArrayList();
42
43     public class SandboxUpdate extends Update {
44         
45         /* (non-Javadoc)
46          * @see org.eclipse.team.internal.ccvs.core.client.Update#shouldRetrieveAbsentDirectories(org.eclipse.team.internal.ccvs.core.client.Session)
47          */

48         protected boolean shouldRetrieveAbsentDirectories(Session session) {
49             return fetchAbsentDirectories;
50         }
51         
52         /* (non-Javadoc)
53          * @see org.eclipse.team.internal.ccvs.core.client.Command#commandFinished(org.eclipse.team.internal.ccvs.core.client.Session, org.eclipse.team.internal.ccvs.core.client.Command.GlobalOption[], org.eclipse.team.internal.ccvs.core.client.Command.LocalOption[], org.eclipse.team.internal.ccvs.core.ICVSResource[], org.eclipse.core.runtime.IProgressMonitor, org.eclipse.core.runtime.IStatus)
54          */

55         protected IStatus commandFinished(Session session, GlobalOption[] globalOptions, LocalOption[] localOptions, ICVSResource[] resources, IProgressMonitor monitor, IStatus status) throws CVSException {
56             // Don't do anything (i.e. don't prune)
57
return status;
58         }
59
60         /* (non-Javadoc)
61          * @see org.eclipse.team.internal.ccvs.core.client.Command#doExecute(org.eclipse.team.internal.ccvs.core.client.Session, org.eclipse.team.internal.ccvs.core.client.Command.GlobalOption[], org.eclipse.team.internal.ccvs.core.client.Command.LocalOption[], java.lang.String[], org.eclipse.team.internal.ccvs.core.client.listeners.ICommandOutputListener, org.eclipse.core.runtime.IProgressMonitor)
62          */

63         protected IStatus doExecute(Session session, GlobalOption[] globalOptions, LocalOption[] localOptions, String JavaDoc[] arguments, ICommandOutputListener listener, IProgressMonitor monitor) throws CVSException {
64             session.registerResponseHandler(new SandboxUpdatedHandler(UpdatedHandler.HANDLE_CREATED));
65             session.registerResponseHandler(new SandboxUpdatedHandler(UpdatedHandler.HANDLE_MERGED));
66             session.registerResponseHandler(new SandboxUpdatedHandler(UpdatedHandler.HANDLE_UPDATE_EXISTING));
67             session.registerResponseHandler(new SandboxUpdatedHandler(UpdatedHandler.HANDLE_UPDATED));
68             return super.doExecute(session, globalOptions, localOptions, arguments, listener, monitor);
69         }
70     }
71     
72     /**
73      * This class overrides the "Created" handler in order to configure the remote file
74      * to receive and cache the contents
75      */

76     public class SandboxUpdatedHandler extends UpdatedHandler {
77         public SandboxUpdatedHandler(int type) {
78             super(type);
79         }
80         /* (non-Javadoc)
81          * @see org.eclipse.team.internal.ccvs.core.client.UpdatedHandler#receiveTargetFile(org.eclipse.team.internal.ccvs.core.client.Session, org.eclipse.team.internal.ccvs.core.ICVSFile, java.lang.String, java.util.Date, boolean, boolean, org.eclipse.core.runtime.IProgressMonitor)
82          */

83         protected void receiveTargetFile(
84             Session session,
85             ICVSFile mFile,
86             String JavaDoc entryLine,
87             Date modTime,
88             boolean binary,
89             boolean readOnly,
90             boolean executable,
91             IProgressMonitor monitor)
92             throws CVSException {
93             
94             // Set the sync info first so that the contents are cached properly
95
ResourceSyncInfo info = new ResourceSyncInfo(entryLine, modTime);
96             // We're always excepting new revisions so the file is clean
97
mFile.setSyncInfo(info, ICVSFile.CLEAN);
98             
99             // receive the file contents from the server
100
session.receiveFile(mFile, binary, getHandlerType(), monitor);
101             
102             // Handle execute
103
try {
104                 if (executable) mFile.setExecutable(true);
105             } catch (CVSException e) {
106                 // Just log and keep going
107
CVSProviderPlugin.log(e);
108             }
109         }
110     }
111     
112     public static RemoteFolder buildRemoteTree(final CVSRepositoryLocation repository, ICVSFolder root, CVSTag tag, int depth, IProgressMonitor monitor) throws CVSException {
113         monitor.beginTask(null, 100);
114         try {
115             RemoteFolder tree = buildBaseTree(repository, root, tag, Policy.subMonitorFor(monitor, 50));
116             UpdateContentCachingService service = new UpdateContentCachingService(repository, tree, tag, depth);
117             service.setFetchAbsentDirectories(getFetchAbsentDirectories(root));
118             if (!service.cacheFileContents(Policy.subMonitorFor(monitor, 50)))
119                 return null;
120             return tree;
121         } finally {
122             monitor.done();
123         }
124     }
125     
126     private void setFetchAbsentDirectories(boolean fetchAbsentDirectories) {
127         this.fetchAbsentDirectories = fetchAbsentDirectories;
128     }
129
130     private static boolean getFetchAbsentDirectories(ICVSFolder root) {
131         IResource resource = root.getIResource();
132         if (resource != null) {
133             IProject project = resource.getProject();
134             RepositoryProvider provider = RepositoryProvider.getProvider(project, CVSProviderPlugin.getTypeId());
135             if (provider instanceof CVSTeamProvider) {
136                 CVSTeamProvider cp = (CVSTeamProvider) provider;
137                 try {
138                     return cp.getFetchAbsentDirectories();
139                 } catch (CVSException e) {
140                     CVSProviderPlugin.log(e);
141                 }
142             }
143         }
144         return CVSProviderPlugin.getPlugin().getFetchAbsentDirectories();
145     }
146
147     private static RemoteFolder buildBaseTree(final CVSRepositoryLocation repository, ICVSFolder root, CVSTag tag, IProgressMonitor progress) throws CVSException {
148         try {
149             RemoteFolderTreeBuilder builder = new RemoteFolderTreeBuilder(repository, root, tag) {
150                 protected RemoteFolder createRemoteFolder(ICVSFolder local, RemoteFolder parent, FolderSyncInfo folderSyncInfo) {
151                     return new RemoteFolderSandbox(parent, local.getName(), repository, folderSyncInfo.getRepository(), folderSyncInfo.getTag(), folderSyncInfo.getIsStatic());
152                 }
153                 protected RemoteFile createRemoteFile(RemoteFolder remote, byte[] syncBytes) throws CVSException {
154                     return new RemoteFile(remote, syncBytes){
155                         public boolean isModified(IProgressMonitor monitor) throws CVSException {
156                             return false;
157                         }
158                         public void delete() {
159                             RemoteFolderSandbox parent = (RemoteFolderSandbox)getParent();
160                             parent.remove(this);
161                         }
162                     };
163                 }
164                 protected boolean isPruneEmptyDirectories() {
165                     return true;
166                 }
167             };
168             progress.beginTask(null, 100);
169             IProgressMonitor subProgress = Policy.infiniteSubMonitorFor(progress, 100);
170             subProgress.beginTask(null, 512);
171             subProgress.subTask(NLS.bind(CVSMessages.RemoteFolderTreeBuilder_buildingBase, new String JavaDoc[] { root.getName() }));
172             RemoteFolder tree = builder.buildBaseTree(null, root, subProgress);
173             if (tree == null) {
174                 // The local tree is empty and was pruned.
175
// Return the root folder so that the operation can proceed
176
FolderSyncInfo folderSyncInfo = root.getFolderSyncInfo();
177                 if (folderSyncInfo == null) return null;
178                 return new RemoteFolderSandbox(null, root.getName(), repository, folderSyncInfo.getRepository(), folderSyncInfo.getTag(), folderSyncInfo.getIsStatic());
179             }
180             return tree;
181         } finally {
182             progress.done();
183         }
184     }
185     
186     public static RemoteFile buildRemoteTree(CVSRepositoryLocation repository, ICVSFile file, CVSTag tag, IProgressMonitor monitor) throws CVSException {
187         monitor.beginTask(null, 100);
188         try {
189             RemoteFolderTreeBuilder builder = new RemoteFolderTreeBuilder(repository, file.getParent(), tag);
190             RemoteFile remote = builder.buildTree(file, Policy.subMonitorFor(monitor, 10));
191             
192             if (remote == null)
193                 return null;
194             
195             byte[] syncBytes = remote.getSyncBytes();
196             if (builder.getFileDiffs().length > 0) {
197                 // Getting the storage of the file will cache the contents
198
remote.getStorage(Policy.subMonitorFor(monitor, 90));
199             }
200             // We need to set the sync bytes back because the content fetch
201
// makes the handle sticky
202
remote.setSyncBytes(syncBytes, ICVSFile.CLEAN);
203             return remote;
204         } catch (TeamException e) {
205             throw CVSException.wrapException(e);
206         } finally {
207             monitor.done();
208         }
209     }
210     
211     public UpdateContentCachingService(CVSRepositoryLocation repository, RemoteFolder tree, CVSTag tag, int depth) {
212         this.repository = repository;
213         this.remoteRoot = tree;
214         this.tag = tag;
215         this.depth = depth;
216     }
217     
218     private boolean cacheFileContents(IProgressMonitor monitor) throws CVSException {
219         // Fetch the file contents for all out-of-sync files by running an update
220
// on the remote tree passing the known changed files as arguments
221
monitor.beginTask(null, 100);
222         Policy.checkCanceled(monitor);
223         Session session = new Session(repository, remoteRoot, false);
224         session.open(Policy.subMonitorFor(monitor, 10), false /* read-only */);
225         try {
226             Policy.checkCanceled(monitor);
227             IStatus status = new SandboxUpdate().execute(session,
228                 Command.NO_GLOBAL_OPTIONS,
229                 getLocalOptions(),
230                 new String JavaDoc[] { Session.CURRENT_LOCAL_FOLDER },
231                 new UpdateListener(this),
232                 Policy.subMonitorFor(monitor, 90));
233             if (!status.isOK()) {
234                 if (status.getCode() == CVSStatus.SERVER_ERROR) {
235                     CVSServerException e = new CVSServerException(status);
236                     if ( ! e.isNoTagException() && e.containsErrors())
237                         throw e;
238                     return false;
239                 } else if (status.getSeverity() == IStatus.ERROR && isReportableError(status)) {
240                     throw new CVSException(status);
241                 }
242             }
243             for (Iterator iterator = removed.iterator(); iterator.hasNext();) {
244                 ICVSResource resource = (ICVSResource) iterator.next();
245                 if (resource.exists())
246                     resource.delete();
247             }
248         } finally {
249             session.close();
250             monitor.done();
251         }
252         return true;
253     }
254
255     private boolean isReportableError(IStatus status) {
256         return CVSStatus.isInternalError(status)
257             || status.getCode() == TeamException.UNABLE
258             || status.getCode() == CVSStatus.INVALID_LOCAL_RESOURCE_PATH
259             || status.getCode() == CVSStatus.RESPONSE_HANDLING_FAILURE;
260     }
261
262     private LocalOption[] getLocalOptions() {
263         ArrayList options = new ArrayList();
264         if (tag != null)
265             options.add(Update.makeTagOption(tag));
266         
267         if (depth != IResource.DEPTH_INFINITE )
268             options.add(Command.DO_NOT_RECURSE);
269         
270         if (fetchAbsentDirectories)
271             options.add(Update.RETRIEVE_ABSENT_DIRECTORIES);
272         
273         if (!options.isEmpty())
274             return (LocalOption[]) options.toArray(new LocalOption[options.size()]);
275         
276         return Command.NO_LOCAL_OPTIONS;
277     }
278
279     public void directoryDoesNotExist(ICVSFolder commandRoot, String JavaDoc path) {
280         try {
281             removed.add(commandRoot.getChild(path));
282         } catch (CVSException e) {
283             CVSProviderPlugin.log(e);
284         }
285     }
286
287     public void directoryInformation(ICVSFolder commandRoot, String JavaDoc path,
288             boolean newDirectory) {
289         // Nothing to do
290
}
291
292     public void fileDoesNotExist(ICVSFolder parent, String JavaDoc filename) {
293         try {
294             removed.add(parent.getChild(filename));
295         } catch (CVSException e) {
296             CVSProviderPlugin.log(e);
297         }
298     }
299
300     public void fileInformation(int type, ICVSFolder parent, String JavaDoc filename) {
301         // Nothing to do
302
}
303 }
304
Popular Tags