1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.multidex;
18 
19 import java.io.FileNotFoundException;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.util.Enumeration;
23 import java.util.Iterator;
24 import java.util.NoSuchElementException;
25 import java.util.zip.ZipEntry;
26 import java.util.zip.ZipFile;
27 
28 /**
29  * A zip element.
30  */
31 class ArchivePathElement implements ClassPathElement {
32 
33     static class DirectoryEntryException extends IOException {
34     }
35 
36     private final ZipFile archive;
37 
ArchivePathElement(ZipFile archive)38     public ArchivePathElement(ZipFile archive) {
39         this.archive = archive;
40     }
41 
42     @Override
open(String path)43     public InputStream open(String path) throws IOException {
44         ZipEntry entry = archive.getEntry(path);
45         if (entry == null) {
46             throw new FileNotFoundException("File \"" + path + "\" not found");
47         } else if (entry.isDirectory()) {
48             throw new DirectoryEntryException();
49         } else {
50             return archive.getInputStream(entry);
51         }
52     }
53 
54     @Override
close()55     public void close() throws IOException {
56         archive.close();
57     }
58 
59     @Override
list()60     public Iterable<String> list() {
61         return new Iterable<String>() {
62 
63             @Override
64             public Iterator<String> iterator() {
65                 return new Iterator<String>() {
66                     Enumeration<? extends ZipEntry> delegate = archive.entries();
67                     ZipEntry next = null;
68 
69                     @Override
70                     public boolean hasNext() {
71                         while (next == null && delegate.hasMoreElements()) {
72                             next = delegate.nextElement();
73                             if (next.isDirectory()) {
74                                 next = null;
75                             }
76                         }
77                         return next != null;
78                     }
79 
80                     @Override
81                     public String next() {
82                         if (hasNext()) {
83                             String name = next.getName();
84                             next = null;
85                             return name;
86                         } else {
87                             throw new NoSuchElementException();
88                         }
89                     }
90 
91                     @Override
92                     public void remove() {
93                         throw new UnsupportedOperationException();
94                     }
95                 };
96             }
97         };
98     }
99 
100 }
101