mirror of
https://github.com/revanced/Apktool.git
synced 2025-05-02 06:54:25 +02:00
280 lines
8.4 KiB
Java
280 lines
8.4 KiB
Java
/**
|
|
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package brut.directory;
|
|
|
|
import java.io.File;
|
|
import java.io.InputStream;
|
|
import java.io.OutputStream;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.LinkedHashSet;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
public abstract class AbstractDirectory implements Directory {
|
|
protected Set<String> mFiles;
|
|
protected Map<String, AbstractDirectory> mDirs;
|
|
|
|
@Override
|
|
public Set<String> getFiles() {
|
|
return getFiles(false);
|
|
}
|
|
|
|
@Override
|
|
public Set<String> getFiles(boolean recursive) {
|
|
if (mFiles == null) {
|
|
loadFiles();
|
|
}
|
|
if (!recursive) {
|
|
return mFiles;
|
|
}
|
|
|
|
Set<String> files = new LinkedHashSet<String>(mFiles);
|
|
for (Map.Entry<String, ? extends Directory> dir : getAbstractDirs().entrySet()) {
|
|
for (String path : dir.getValue().getFiles(true)) {
|
|
files.add(dir.getKey() + separator + path);
|
|
}
|
|
}
|
|
return files;
|
|
}
|
|
|
|
@Override
|
|
public boolean containsFile(String path) {
|
|
SubPath subpath;
|
|
try {
|
|
subpath = getSubPath(path);
|
|
} catch (PathNotExist e) {
|
|
return false;
|
|
}
|
|
|
|
if (subpath.dir != null) {
|
|
return subpath.dir.containsFile(subpath.path);
|
|
}
|
|
return getFiles().contains(subpath.path);
|
|
}
|
|
|
|
@Override
|
|
public boolean containsDir(String path) {
|
|
SubPath subpath;
|
|
try {
|
|
subpath = getSubPath(path);
|
|
} catch (PathNotExist e) {
|
|
return false;
|
|
}
|
|
|
|
if (subpath.dir != null) {
|
|
return subpath.dir.containsDir(subpath.path);
|
|
}
|
|
return getAbstractDirs().containsKey(subpath.path);
|
|
}
|
|
|
|
@Override
|
|
public Map<String, Directory> getDirs()
|
|
throws UnsupportedOperationException {
|
|
return getDirs(false);
|
|
}
|
|
|
|
@Override
|
|
public Map<String, Directory> getDirs(boolean recursive)
|
|
throws UnsupportedOperationException {
|
|
return new LinkedHashMap<String, Directory>(getAbstractDirs(recursive));
|
|
}
|
|
|
|
@Override
|
|
public InputStream getFileInput(String path) throws DirectoryException {
|
|
SubPath subpath = getSubPath(path);
|
|
if (subpath.dir != null) {
|
|
return subpath.dir.getFileInput(subpath.path);
|
|
}
|
|
if (! getFiles().contains(subpath.path)) {
|
|
throw new PathNotExist(path);
|
|
}
|
|
return getFileInputLocal(subpath.path);
|
|
}
|
|
|
|
@Override
|
|
public OutputStream getFileOutput(String path) throws DirectoryException {
|
|
ParsedPath parsed = parsePath(path);
|
|
if (parsed.dir == null) {
|
|
getFiles().add(parsed.subpath);
|
|
return getFileOutputLocal(parsed.subpath);
|
|
}
|
|
|
|
Directory dir;
|
|
// IMPOSSIBLE_EXCEPTION
|
|
try {
|
|
dir = createDir(parsed.dir);
|
|
} catch (PathAlreadyExists e) {
|
|
dir = getAbstractDirs().get(parsed.dir);
|
|
}
|
|
return dir.getFileOutput(parsed.subpath);
|
|
}
|
|
|
|
@Override
|
|
public Directory getDir(String path) throws PathNotExist {
|
|
SubPath subpath = getSubPath(path);
|
|
if (subpath.dir != null) {
|
|
return subpath.dir.getDir(subpath.path);
|
|
}
|
|
if (! getAbstractDirs().containsKey(subpath.path)) {
|
|
throw new PathNotExist(path);
|
|
}
|
|
return getAbstractDirs().get(subpath.path);
|
|
}
|
|
|
|
@Override
|
|
public Directory createDir(String path) throws DirectoryException {
|
|
ParsedPath parsed = parsePath(path);
|
|
AbstractDirectory dir;
|
|
if (parsed.dir == null) {
|
|
if (getAbstractDirs().containsKey(parsed.subpath)) {
|
|
throw new PathAlreadyExists(path);
|
|
}
|
|
dir = createDirLocal(parsed.subpath);
|
|
getAbstractDirs().put(parsed.subpath, dir);
|
|
return dir;
|
|
}
|
|
|
|
if (getAbstractDirs().containsKey(parsed.dir)) {
|
|
dir = getAbstractDirs().get(parsed.dir);
|
|
} else {
|
|
dir = createDirLocal(parsed.dir);
|
|
getAbstractDirs().put(parsed.dir, dir);
|
|
}
|
|
return dir.createDir(parsed.subpath);
|
|
}
|
|
|
|
@Override
|
|
public boolean removeFile(String path) {
|
|
SubPath subpath;
|
|
try {
|
|
subpath = getSubPath(path);
|
|
} catch (PathNotExist e) {
|
|
return false;
|
|
}
|
|
|
|
if (subpath.dir != null) {
|
|
return subpath.dir.removeFile(subpath.path);
|
|
}
|
|
if (! getFiles().contains(subpath.path)) {
|
|
return false;
|
|
}
|
|
removeFileLocal(subpath.path);
|
|
getFiles().remove(subpath.path);
|
|
return true;
|
|
}
|
|
|
|
public void copyToDir(Directory out) throws DirectoryException {
|
|
DirUtil.copyToDir(out, out);
|
|
}
|
|
|
|
public void copyToDir(Directory out, String[] fileNames)
|
|
throws DirectoryException {
|
|
DirUtil.copyToDir(out, out, fileNames);
|
|
}
|
|
|
|
public void copyToDir(Directory out, String fileName)
|
|
throws DirectoryException {
|
|
DirUtil.copyToDir(out, out, fileName);
|
|
}
|
|
|
|
public void copyToDir(File out) throws DirectoryException {
|
|
DirUtil.copyToDir(this, out);
|
|
}
|
|
|
|
public void copyToDir(File out, String[] fileNames)
|
|
throws DirectoryException {
|
|
DirUtil.copyToDir(this, out, fileNames);
|
|
}
|
|
|
|
public void copyToDir(File out, String fileName)
|
|
throws DirectoryException {
|
|
DirUtil.copyToDir(this, out, fileName);
|
|
}
|
|
|
|
protected Map<String, AbstractDirectory> getAbstractDirs() {
|
|
return getAbstractDirs(false);
|
|
}
|
|
|
|
protected Map<String, AbstractDirectory> getAbstractDirs(boolean recursive) {
|
|
if (mDirs == null) {
|
|
loadDirs();
|
|
}
|
|
if (!recursive) {
|
|
return mDirs;
|
|
}
|
|
|
|
Map<String, AbstractDirectory> dirs = new LinkedHashMap<String, AbstractDirectory>(mDirs);
|
|
for (Map.Entry<String, AbstractDirectory> dir : getAbstractDirs().entrySet()) {
|
|
for (Map.Entry<String, AbstractDirectory> subdir : dir.getValue().getAbstractDirs(
|
|
true).entrySet()) {
|
|
dirs.put(dir.getKey() + separator + subdir.getKey(),
|
|
subdir.getValue());
|
|
}
|
|
}
|
|
return dirs;
|
|
}
|
|
|
|
private SubPath getSubPath(String path) throws PathNotExist {
|
|
ParsedPath parsed = parsePath(path);
|
|
if (parsed.dir == null) {
|
|
return new SubPath(null, parsed.subpath);
|
|
}
|
|
if (! getAbstractDirs().containsKey(parsed.dir)) {
|
|
throw new PathNotExist(path);
|
|
}
|
|
return new SubPath(getAbstractDirs().get(parsed.dir), parsed.subpath);
|
|
}
|
|
|
|
private ParsedPath parsePath(String path) {
|
|
int pos = path.indexOf(separator);
|
|
if (pos == -1) {
|
|
return new ParsedPath(null, path);
|
|
}
|
|
return new ParsedPath(path.substring(0, pos), path.substring(pos + 1));
|
|
}
|
|
|
|
abstract protected void loadFiles();
|
|
abstract protected void loadDirs();
|
|
abstract protected InputStream getFileInputLocal(String name)
|
|
throws DirectoryException;
|
|
abstract protected OutputStream getFileOutputLocal(String name)
|
|
throws DirectoryException;
|
|
abstract protected AbstractDirectory createDirLocal(String name)
|
|
throws DirectoryException;
|
|
abstract protected void removeFileLocal(String name);
|
|
|
|
|
|
private class ParsedPath {
|
|
public String dir;
|
|
public String subpath;
|
|
public ParsedPath(String dir, String subpath) {
|
|
this.dir = dir;
|
|
this.subpath = subpath;
|
|
}
|
|
}
|
|
|
|
private class SubPath {
|
|
public AbstractDirectory dir;
|
|
public String path;
|
|
|
|
public SubPath(AbstractDirectory dir, String path) {
|
|
this.dir = dir;
|
|
this.path = path;
|
|
}
|
|
}
|
|
}
|