12bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel/*
22bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel * Copyright (C) 2013 The Android Open Source Project
32bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel *
42bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel * Licensed under the Apache License, Version 2.0 (the "License");
52bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel * you may not use this file except in compliance with the License.
62bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel * You may obtain a copy of the License at
72bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel *
82bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel *      http://www.apache.org/licenses/LICENSE-2.0
92bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel *
102bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel * Unless required by applicable law or agreed to in writing, software
112bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel * distributed under the License is distributed on an "AS IS" BASIS,
122bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel * See the License for the specific language governing permissions and
142bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel * limitations under the License.
152bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel */
162bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel
172bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Rousselpackage com.android.multidex;
182bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel
192bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Rousselimport java.io.FileNotFoundException;
202bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Rousselimport java.io.IOException;
212bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Rousselimport java.io.InputStream;
22893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Rousselimport java.util.Enumeration;
23893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Rousselimport java.util.Iterator;
24893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Rousselimport java.util.NoSuchElementException;
252bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Rousselimport java.util.zip.ZipEntry;
262bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Rousselimport java.util.zip.ZipFile;
272bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel
282bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel/**
292bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel * A zip element.
302bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel */
312bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Rousselclass ArchivePathElement implements ClassPathElement {
322bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel
33893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel    static class DirectoryEntryException extends IOException {
34893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel    }
35893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel
36893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel    private final ZipFile archive;
372bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel
382bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel    public ArchivePathElement(ZipFile archive) {
392bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel        this.archive = archive;
402bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel    }
412bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel
422bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel    @Override
432bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel    public InputStream open(String path) throws IOException {
442bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel        ZipEntry entry = archive.getEntry(path);
452bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel        if (entry == null) {
46893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel            throw new FileNotFoundException("File \"" + path + "\" not found");
47893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel        } else if (entry.isDirectory()) {
48893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel            throw new DirectoryEntryException();
492bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel        } else {
502bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel            return archive.getInputStream(entry);
512bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel        }
522bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel    }
532bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel
542bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel    @Override
552bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel    public void close() throws IOException {
562bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel        archive.close();
572bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel    }
582bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel
59893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel    @Override
60893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel    public Iterable<String> list() {
61893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel        return new Iterable<String>() {
62893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel
63893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel            @Override
64893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel            public Iterator<String> iterator() {
65893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                return new Iterator<String>() {
66893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                    Enumeration<? extends ZipEntry> delegate = archive.entries();
67893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                    ZipEntry next = null;
68893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel
69893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                    @Override
70893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                    public boolean hasNext() {
71893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                        while (next == null && delegate.hasMoreElements()) {
72893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                            next = delegate.nextElement();
73893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                            if (next.isDirectory()) {
74893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                                next = null;
75893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                            }
76893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                        }
77893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                        return next != null;
78893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                    }
79893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel
80893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                    @Override
81893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                    public String next() {
82893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                        if (hasNext()) {
83893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                            String name = next.getName();
84893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                            next = null;
85893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                            return name;
86893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                        } else {
87893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                            throw new NoSuchElementException();
88893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                        }
89893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                    }
90893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel
91893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                    @Override
92893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                    public void remove() {
93893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                        throw new UnsupportedOperationException();
94893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                    }
95893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel                };
96893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel            }
97893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel        };
98893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel    }
99893795fc95fdd77d398ebb77a0fe336c45b596cfYohann Roussel
1002bb6fe45bf620525ba34bd7303d7ecb597aa0689Yohann Roussel}
101