KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > core > ResourceVariantCacheEntry


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.core;
12
13 import java.io.*;
14 import java.util.Date JavaDoc;
15
16 import org.eclipse.core.runtime.IProgressMonitor;
17 import org.eclipse.core.runtime.jobs.ILock;
18 import org.eclipse.osgi.util.NLS;
19 import org.eclipse.team.core.TeamException;
20 import org.eclipse.team.core.variants.CachedResourceVariant;
21
22 /**
23  * This class provides the implementation for the ICacheEntry
24  */

25 public class ResourceVariantCacheEntry {
26     
27     public static final int UNINITIALIZED = 0;
28     public static final int READY = 1;
29     public static final int DISPOSED = 2;
30     
31     private String JavaDoc id;
32     private String JavaDoc filePath;
33     private ResourceVariantCache cache;
34     private int state = UNINITIALIZED;
35     private long lastAccess;
36     private CachedResourceVariant resourceVariant;
37     private ILock lock;
38
39     public ResourceVariantCacheEntry(ResourceVariantCache cache, ILock lock, String JavaDoc id, String JavaDoc filePath) {
40         this.lock = lock;
41         state = UNINITIALIZED;
42         this.cache = cache;
43         this.id = id;
44         this.filePath = filePath;
45         registerHit();
46     }
47
48     /* (non-Javadoc)
49      * @see org.eclipse.team.core.sync.ICacheEntry#getContents()
50      */

51     public InputStream getContents() throws TeamException {
52         if (state != READY) return null;
53         registerHit();
54         File ioFile = getFile();
55         try {
56             try {
57                 if (ioFile.exists()) {
58                     return new FileInputStream(ioFile);
59                 }
60             } catch (IOException e) {
61                 // Try to purge the cache and continue
62
cache.purgeFromCache(this);
63                 throw e;
64             }
65         } catch (IOException e) {
66             // We will end up here if we couldn't read or delete the cache file
67
throw new TeamException(NLS.bind(Messages.RemoteContentsCache_fileError, new String JavaDoc[] { ioFile.getAbsolutePath() }), e);
68         }
69         // This can occur when there is no remote contents
70
return new ByteArrayInputStream(new byte[0]);
71     }
72
73     protected File getFile() {
74         return new File(cache.getCachePath().toFile(), filePath);
75     }
76
77     /**
78      * Set the contents of for this cache entry. This method supports concurrency by only allowing
79      * one cache entry to be written at a time. In the case of two concurrent writes to the same cache entry,
80      * the contents from the first write is used and the content from subsequent writes is ignored.
81      * @param stream an InputStream that provides the contents to be cached
82      * @param monitor a progress monitor
83      * @throws TeamException if the entry is DISPOSED or an I/O error occurres
84      */

85     public void setContents(InputStream stream, IProgressMonitor monitor) throws TeamException {
86         // Use a lock to only allow one write at a time
87
beginOperation();
88         try {
89             internalSetContents(stream, monitor);
90         } finally {
91             endOperation();
92         }
93     }
94     
95     private void endOperation() {
96         lock.release();
97     }
98
99     private void beginOperation() {
100         lock.acquire();
101     }
102
103     private void internalSetContents(InputStream stream, IProgressMonitor monitor) throws TeamException {
104         // if the state is DISPOSED then there is a problem
105
if (state == DISPOSED) {
106             throw new TeamException(NLS.bind(Messages.RemoteContentsCacheEntry_3, new String JavaDoc[] { cache.getName(), id }));
107         }
108         // Otherwise, the state is UNINITIALIZED or READY so we can proceed
109
registerHit();
110         File ioFile = getFile();
111         try {
112             
113             // Open the cache file for writing
114
OutputStream out;
115             try {
116                 if (state == UNINITIALIZED) {
117                     out = new BufferedOutputStream(new FileOutputStream(ioFile));
118                 } else {
119                     // If the entry is READY, the contents must have been read in another thread.
120
// We still need to red the contents but they can be ignored since presumably they are the same
121
out = new ByteArrayOutputStream();
122                 }
123             } catch (FileNotFoundException e) {
124                 throw new TeamException(NLS.bind(Messages.RemoteContentsCache_fileError, new String JavaDoc[] { ioFile.getAbsolutePath() }), e);
125             }
126             
127             // Transfer the contents
128
try {
129                 try {
130                     byte[] buffer = new byte[1024];
131                     int read;
132                     while ((read = stream.read(buffer)) >= 0) {
133                         Policy.checkCanceled(monitor);
134                         out.write(buffer, 0, read);
135                     }
136                 } finally {
137                     out.close();
138                 }
139             } catch (IOException e) {
140                 // Make sure we don't leave the cache file around as it may not have the right contents
141
cache.purgeFromCache(this);
142                 throw e;
143             }
144             
145             // Mark the cache entry as ready
146
state = READY;
147         } catch (IOException e) {
148             throw new TeamException(NLS.bind(Messages.RemoteContentsCache_fileError, new String JavaDoc[] { ioFile.getAbsolutePath() }), e);
149         } finally {
150             try {
151                 stream.close();
152             } catch (IOException e1) {
153                 // Ignore close errors
154
}
155         }
156
157     }
158
159     /* (non-Javadoc)
160      * @see org.eclipse.team.core.sync.ICacheEntry#getState()
161      */

162     public int getState() {
163         return state;
164     }
165     
166     /* (non-Javadoc)
167      * @see org.eclipse.team.core.sync.ICacheEntry#getSize()
168      */

169     public long getSize() {
170         if (state != READY) return 0;
171         File ioFile = getFile();
172         if (ioFile.exists()) {
173             return ioFile.length();
174         }
175         return 0;
176     }
177
178     /* (non-Javadoc)
179      * @see org.eclipse.team.core.sync.ICacheEntry#getLastAccessTimeStamp()
180      */

181     public long getLastAccessTimeStamp() {
182         return lastAccess;
183     }
184
185     /**
186      * Registers a hit on this cache entry. This updates the last access timestamp.
187      * Thsi method is intended to only be invokded from inside this class or the cahce itself.
188      * Other clients should not use it.
189      */

190     protected void registerHit() {
191         lastAccess = new Date JavaDoc().getTime();
192     }
193
194     public void dispose() {
195         // Use a lock to avoid changing state while another thread may be writting
196
beginOperation();
197         try {
198             state = DISPOSED;
199             cache.purgeFromCache(this);
200         } finally {
201             endOperation();
202         }
203     }
204
205     
206     public String JavaDoc getId() {
207         return id;
208     }
209     
210     public CachedResourceVariant getResourceVariant() {
211         return resourceVariant;
212     }
213     
214     public void setResourceVariant(CachedResourceVariant resourceVariant) {
215         this.resourceVariant = resourceVariant;
216     }
217 }
218
Popular Tags