/* * dex2jar - Tools to work with android .dex and java .class files * Copyright (c) 2009-2012 Panxiaobo * * 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 com.googlecode.dex2jar.tools; import java.io.File; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.spi.FileSystemProvider; import java.util.*; public abstract class BaseCmd { public static String getBaseName(String fn) { int x = fn.lastIndexOf('.'); return x >= 0 ? fn.substring(0, x) : fn; } public static String getBaseName(Path fn) { return getBaseName(fn.getFileName().toString()); } public interface FileVisitorX { // change the relative from Path to String // java.nio.file.ProviderMismatchException on jdk8 void visitFile(Path file, String relative) throws IOException; } public static void walkFileTreeX(final Path base, final FileVisitorX fv) throws IOException { Files.walkFileTree(base, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { fv.visitFile(file, base.relativize(file).toString()); return super.visitFile(file, attrs); } }); } public static void walkJarOrDir(final Path in, final FileVisitorX fv) throws IOException { if (Files.isDirectory(in)) { walkFileTreeX(in, fv); } else { try (FileSystem inputFileSystem = openZip(in)) { walkFileTreeX(inputFileSystem.getPath("/"), fv); } } } public static void createParentDirectories(Path p) throws IOException { // merge patch from t3stwhat, fix crash on save to windows path like 'C:\\abc.jar' Path parent = p.getParent(); if (parent != null && !Files.exists(parent)) { Files.createDirectories(parent); } } public static FileSystem createZip(Path output) throws IOException { Map env = new HashMap<>(); env.put("create", "true"); Files.deleteIfExists(output); createParentDirectories(output); for (FileSystemProvider p : FileSystemProvider.installedProviders()) { String s = p.getScheme(); if ("jar".equals(s) || "zip".equalsIgnoreCase(s)) { return p.newFileSystem(output, env); } } throw new IOException("cant find zipfs support"); } public static FileSystem openZip(Path in) throws IOException { for (FileSystemProvider p : FileSystemProvider.installedProviders()) { String s = p.getScheme(); if ("jar".equals(s) || "zip".equalsIgnoreCase(s)) { return p.newFileSystem(in, new HashMap()); } } throw new IOException("cant find zipfs support"); } protected static class HelpException extends RuntimeException { private static final long serialVersionUID = 5538069795297477488L; public HelpException() { super(); } public HelpException(String message) { super(message); } } @Retention(value = RetentionPolicy.RUNTIME) @Target(value = { ElementType.FIELD }) public @interface Opt { String argName() default ""; String description() default ""; boolean hasArg() default true; String longOpt() default ""; String opt() default ""; boolean required() default false; } static protected class Option implements Comparable