1 11 package org.eclipse.debug.core.sourcelookup.containers; 12 13 import java.io.File ; 14 import java.io.IOException ; 15 import com.ibm.icu.text.MessageFormat; 16 import java.util.ArrayList ; 17 import java.util.Enumeration ; 18 import java.util.HashSet ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 import java.util.Set ; 22 import java.util.zip.ZipEntry ; 23 import java.util.zip.ZipFile ; 24 25 import org.eclipse.core.runtime.CoreException; 26 import org.eclipse.debug.core.DebugPlugin; 27 import org.eclipse.debug.core.sourcelookup.ISourceContainerType; 28 import org.eclipse.debug.internal.core.sourcelookup.SourceLookupMessages; 29 import org.eclipse.debug.internal.core.sourcelookup.SourceLookupUtils; 30 31 40 public class ExternalArchiveSourceContainer extends AbstractSourceContainer { 41 42 private boolean fDetectRoots = false; 43 private Set fPotentialRoots = null; 44 private List fRoots = new ArrayList (); 45 private String fArchivePath = null; 46 50 public static final String TYPE_ID = DebugPlugin.getUniqueIdentifier() + ".containerType.externalArchive"; 52 69 public ExternalArchiveSourceContainer(String archivePath, boolean detectRootPaths) { 70 fArchivePath = archivePath; 71 fDetectRoots = detectRootPaths; 72 } 73 74 77 public Object [] findSourceElements(String name) throws CoreException { 78 name = name.replace('\\', '/'); 79 ZipFile file = getArchive(); 80 synchronized (file) { 81 boolean isQualfied = name.indexOf('/') > 0; 82 if (fDetectRoots && isQualfied) { 83 ZipEntry entry = searchRoots(file, name); 84 if (entry != null) { 85 return new Object []{new ZipEntryStorage(file, entry)}; 86 } 87 } else { 88 ZipEntry entry = file.getEntry(name); 90 if (entry != null) { 91 return new Object []{new ZipEntryStorage(file, entry)}; 93 } 94 Enumeration entries = file.entries(); 96 List matches = null; 97 while (entries.hasMoreElements()) { 98 entry = (ZipEntry )entries.nextElement(); 99 String entryName = entry.getName(); 100 if (entryName.endsWith(name)) { 101 if (isQualfied || entryName.length() == name.length() || entryName.charAt(entryName.length() - name.length() - 1) == '/') { 102 if (isFindDuplicates()) { 103 if (matches == null) { 104 matches = new ArrayList (); 105 } 106 matches.add(new ZipEntryStorage(file, entry)); 107 } else { 108 return new Object []{new ZipEntryStorage(file, entry)}; 109 } 110 } 111 } 112 } 113 if (matches != null) { 114 return matches.toArray(); 115 } 116 } 117 } 118 return EMPTY; 119 } 120 121 130 private ZipEntry searchRoots(ZipFile file, String name) { 131 if (fPotentialRoots == null) { 132 fPotentialRoots = new HashSet (); 133 fPotentialRoots.add(""); Enumeration entries = file.entries(); 136 while (entries.hasMoreElements()) { 137 ZipEntry entry = (ZipEntry ) entries.nextElement(); 138 if (entry.isDirectory()) { 139 fPotentialRoots.add(entry.getName()); 140 } else { 141 String entryName = entry.getName(); 142 int index = entryName.lastIndexOf("/"); while (index > 0) { 144 if (fPotentialRoots.add(entryName.substring(0, index + 1))) { 145 entryName = entryName.substring(0, index); 146 index = entryName.lastIndexOf("/"); } else { 148 break; 149 } 150 } 151 } 152 } 153 } 154 int i = 0; 155 while (i < fRoots.size()) { 156 String root = (String ) fRoots.get(i); 157 ZipEntry entry = file.getEntry(root+name); 158 if (entry != null) { 159 return entry; 160 } 161 i++; 162 } 163 if (!fPotentialRoots.isEmpty()) { 164 Iterator roots = fPotentialRoots.iterator(); 165 String root = null; 166 ZipEntry entry = null; 167 while (roots.hasNext()) { 168 root = (String ) roots.next(); 169 entry = file.getEntry(root+name); 170 if (entry != null) { 171 break; 172 } 173 } 174 if (entry != null) { 175 if (root != null) { 176 fRoots.add(root); 177 fPotentialRoots.remove(root); 178 Iterator rs = fPotentialRoots.iterator(); 180 while (rs.hasNext()) { 181 String r = (String ) rs.next(); 182 if (r.startsWith(root)) { 183 rs.remove(); 184 } 185 } 186 } 187 return entry; 188 } 189 } 190 return null; 191 } 192 193 198 private ZipFile getArchive() throws CoreException { 199 try { 200 return SourceLookupUtils.getZipFile(fArchivePath); 201 } catch (IOException e) { 202 File file = new File (fArchivePath); 203 if (file.exists()) { 204 abort(MessageFormat.format(SourceLookupMessages.ExternalArchiveSourceContainer_2, new String []{fArchivePath}), e); 205 } else { 206 warn(MessageFormat.format(SourceLookupMessages.ExternalArchiveSourceContainer_1, new String []{fArchivePath}), e); 207 } 208 } 209 return null; 210 } 211 212 215 public String getName() { 216 return fArchivePath; 217 } 218 221 public ISourceContainerType getType() { 222 return getSourceContainerType(TYPE_ID); 223 } 224 225 232 public boolean isDetectRoot() { 233 return fDetectRoots; 234 } 235 238 public boolean equals(Object obj) { 239 return obj instanceof ExternalArchiveSourceContainer && 240 ((ExternalArchiveSourceContainer)obj).getName().equals(getName()); 241 } 242 245 public int hashCode() { 246 return getName().hashCode(); 247 } 248 249 253 public void dispose() { 254 super.dispose(); 255 if (fPotentialRoots != null) { 256 fPotentialRoots.clear(); 257 } 258 fRoots.clear(); 259 } 260 } 261 | Popular Tags |