KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > compare > ZipFileStructureCreator


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.compare;
12
13 import java.io.*;
14 import java.util.HashMap JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.zip.*;
17
18 import org.eclipse.core.runtime.CoreException;
19
20 import org.eclipse.swt.graphics.Image;
21
22 import org.eclipse.jface.util.Assert;
23
24 import org.eclipse.compare.internal.*;
25 import org.eclipse.compare.structuremergeviewer.*;
26
27
28 /**
29  * This implementation of the <code>IStructureCreator</code> interface
30  * makes the contents of a zip archive available as a
31  * hierarchical structure of <code>IStructureComparator</code>s.
32  * <p>
33  * It is used when comparing the internal structure of a zip archive.
34  *
35  * @since 2.0
36  */

37 public class ZipFileStructureCreator implements IStructureCreator {
38
39     /**
40      * Common base class for ZipFolder and ZipFile
41      */

42     static abstract class ZipResource implements IStructureComparator, ITypedElement {
43
44         private String JavaDoc fName;
45
46         ZipResource(String JavaDoc name) {
47             fName= name;
48         }
49
50         public String JavaDoc getName() {
51             return fName;
52         }
53
54         public Image getImage() {
55             return CompareUI.getImage(getType());
56         }
57
58         /*
59          * Returns true if other is ITypedElement and names are equal.
60          * @see IComparator#equals
61          */

62         public boolean equals(Object JavaDoc other) {
63             if (other instanceof ITypedElement)
64                 return fName.equals(((ITypedElement) other).getName());
65             return super.equals(other);
66         }
67
68         public int hashCode() {
69             return fName.hashCode();
70         }
71     }
72
73     static class ZipFolder extends ZipResource {
74
75         private HashMap JavaDoc fChildren= new HashMap JavaDoc(10);
76
77         ZipFolder(String JavaDoc name) {
78             super(name);
79         }
80
81         public String JavaDoc getType() {
82             return ITypedElement.FOLDER_TYPE;
83         }
84
85         public Object JavaDoc[] getChildren() {
86             Object JavaDoc[] children= new Object JavaDoc[fChildren.size()];
87             Iterator JavaDoc iter= fChildren.values().iterator();
88             for (int i= 0; iter.hasNext(); i++)
89                 children[i]= iter.next();
90             return children;
91         }
92
93         ZipFile createContainer(String JavaDoc path) {
94             String JavaDoc entry= path;
95             int pos= path.indexOf('/');
96             if (pos < 0)
97                 pos= path.indexOf('\\');
98             if (pos >= 0) {
99                 entry= path.substring(0, pos);
100                 path= path.substring(pos + 1);
101             } else if (entry.length() > 0) {
102                 if (CompareUIPlugin.getDefault().filter(path, false, true))
103                     return null;
104                 ZipFile ze= new ZipFile(entry);
105                 fChildren.put(entry, ze);
106                 return ze;
107             } else
108                 return null;
109
110             ZipFolder folder= null;
111             if (fChildren != null) {
112                 Object JavaDoc o= fChildren.get(entry);
113                 if (o instanceof ZipFolder)
114                     folder= (ZipFolder) o;
115             }
116
117             if (folder == null) {
118                 if (path.length() > 0 && CompareUIPlugin.getDefault().filter(path, true, true))
119                     return null;
120                 folder= new ZipFolder(entry);
121                 fChildren.put(entry, folder);
122             }
123
124             return folder.createContainer(path);
125         }
126     }
127
128     static class ZipFile extends ZipResource implements IStreamContentAccessor {
129
130         private byte[] fContents;
131
132         ZipFile(String JavaDoc name) {
133             super(name);
134         }
135
136         public String JavaDoc getType() {
137             String JavaDoc s= this.getName();
138             int pos= s.lastIndexOf('.');
139             if (pos >= 0)
140                 return s.substring(pos + 1);
141             return ITypedElement.UNKNOWN_TYPE;
142         }
143
144         public Object JavaDoc[] getChildren() {
145             return null;
146         }
147         
148         public InputStream getContents() {
149             if (fContents == null)
150                 fContents= new byte[0];
151             return new ByteArrayInputStream(fContents);
152         }
153
154         byte[] getBytes() {
155             return fContents;
156         }
157
158         void setBytes(byte[] buffer) {
159             fContents= buffer;
160         }
161
162         void appendBytes(byte[] buffer, int length) {
163             if (length > 0) {
164                 int oldLen= 0;
165                 if (fContents != null)
166                     oldLen= fContents.length;
167                 byte[] newBuf= new byte[oldLen + length];
168                 if (oldLen > 0)
169                     System.arraycopy(fContents, 0, newBuf, 0, oldLen);
170                 System.arraycopy(buffer, 0, newBuf, oldLen, length);
171                 fContents= newBuf;
172             }
173         }
174     }
175     
176     private String JavaDoc fTitle;
177
178     /**
179      * Create a new ZipFileStructureCreator.
180      */

181     public ZipFileStructureCreator() {
182         this(Utilities.getString("ZipStructureCreator.name")); //$NON-NLS-1$
183
}
184     
185     /**
186      * Create a new ZipFileStructureCreator with the given title.
187      * The title is returned by the method <code>getName()</code>.
188      * @param title the title of this structure creator
189      */

190     public ZipFileStructureCreator(String JavaDoc title) {
191         fTitle= title;
192     }
193
194     public String JavaDoc getName() {
195         return fTitle;
196     }
197
198     public IStructureComparator getStructure(Object JavaDoc input) {
199
200         InputStream is= null;
201         
202         if (input instanceof IStreamContentAccessor) {
203             IStreamContentAccessor sca= (IStreamContentAccessor) input;
204             try {
205                 is= sca.getContents();
206             } catch (CoreException ex) {
207                 // NeedWork
208
}
209         }
210
211         if (is == null)
212             return null;
213
214         ZipInputStream zip= new ZipInputStream(is);
215         ZipFolder root= new ZipFolder(""); //$NON-NLS-1$
216
try {
217             for (;;) {
218                 ZipEntry entry= zip.getNextEntry();
219                 if (entry == null)
220                     break;
221
222                 ZipFile ze= root.createContainer(entry.getName());
223                 if (ze != null) {
224                     int length= (int) entry.getSize();
225                     if (length >= 0) {
226                         byte[] buffer= new byte[length];
227                         int offset= 0;
228     
229                         do {
230                             int n= zip.read(buffer, offset, length);
231                             offset += n;
232                             length -= n;
233                         } while (length > 0);
234     
235                         ze.setBytes(buffer);
236                     } else {
237                         byte[] buffer= new byte[1024];
238                         int n;
239                         do {
240                             n= zip.read(buffer, 0, 1024);
241                             ze.appendBytes(buffer, n);
242                         } while (n >= 0);
243                     }
244                 }
245                 zip.closeEntry();
246             }
247         } catch (IOException ex) {
248             return null;
249         } finally {
250             try {
251                 zip.close();
252             } catch (IOException ex) {
253                 // silently ignored
254
}
255         }
256
257         if (root.fChildren.size() == 1) {
258             Iterator JavaDoc iter= root.fChildren.values().iterator();
259             return (IStructureComparator) iter.next();
260         }
261         return root;
262     }
263
264     public String JavaDoc getContents(Object JavaDoc o, boolean ignoreWhitespace) {
265         if (o instanceof ZipFile) {
266             byte[] bytes= ((ZipFile)o).getBytes();
267             if (bytes != null)
268                 return new String JavaDoc(bytes);
269             return ""; //$NON-NLS-1$
270
}
271         return null;
272     }
273
274     /**
275      * Returns <code>false</code> since we cannot update a zip archive.
276      * @return <code>false</code>
277      */

278     public boolean canSave() {
279         return false;
280     }
281
282     /**
283      * Called whenever a copy operation has been performed on a tree node.
284      * This implementation throws an <code>AssertionFailedException</code>
285      * since we cannot update a zip archive.
286      *
287      * @param structure the node for which to save the new content
288      * @param input the object from which the structure tree was created in <code>getStructure</code>
289      */

290     public void save(IStructureComparator structure, Object JavaDoc input) {
291         Assert.isTrue(false); // Cannot update zip archive
292
}
293     
294     public IStructureComparator locate(Object JavaDoc path, Object JavaDoc source) {
295         return null;
296     }
297         
298     /**
299      * Returns <code>false</code> since this <code>IStructureCreator</code>
300      * cannot rewrite the diff tree in order to fold certain combinations of
301      * additions and deletions.
302      * <p>
303      * Note: this method is for internal use only. Clients should not call this method.
304      * @return <code>false</code>
305      */

306     public boolean canRewriteTree() {
307         return false;
308     }
309     
310     /**
311      * Empty implementation since this <code>IStructureCreator</code>
312      * cannot rewrite the diff tree in order to fold certain combinations of
313      * additions and deletions.
314      * <p>
315      * Note: this method is for internal use only. Clients should not call this method.
316      * @param differencer
317      * @param root
318      */

319     public void rewriteTree(Differencer differencer, IDiffContainer root) {
320         // empty default implementation
321
}
322 }
323
324
Popular Tags