001/* 002 * Copyright (C) 2015-2021 KeepSafe Software 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.getkeepsafe.dexcount.treegen.workers; 017 018import com.getkeepsafe.dexcount.Deobfuscator; 019import com.getkeepsafe.dexcount.PackageTree; 020import com.getkeepsafe.dexcount.PrintOptions; 021import com.getkeepsafe.dexcount.source.SourceFile; 022import com.getkeepsafe.dexcount.source.SourceFiles; 023import org.apache.commons.io.IOUtils; 024import org.gradle.api.file.RegularFileProperty; 025import org.slf4j.Logger; 026import org.slf4j.LoggerFactory; 027 028import java.io.File; 029import java.io.IOException; 030import java.util.List; 031 032public abstract class LegacyWorker extends BaseWorker<LegacyWorker.Params> { 033 private static final Logger LOGGER = LoggerFactory.getLogger(LegacyWorker.class); 034 035 public interface Params extends BaseWorker.Params { 036 RegularFileProperty getInputFile(); 037 RegularFileProperty getMappingFile(); 038 } 039 040 @Override 041 protected PackageTree generatePackageTree() throws IOException { 042 PrintOptions options = getParameters().getPrintOptions().get(); 043 Deobfuscator deobfuscator = Deobfuscator.create(getParameters().getMappingFile().getAsFile().getOrNull()); 044 File inputFile = getParameters().getInputFile().getAsFile().get(); 045 String fileName = inputFile.getName(); 046 047 boolean isApk = fileName.endsWith(".apk"); 048 boolean isAar = fileName.endsWith(".aar"); 049 boolean isJar = fileName.endsWith(".jar"); 050 boolean isAndroid = isApk || isAar; 051 052 if (!isApk && !isAar && !isJar) { 053 throw new IllegalStateException("File type is unclear: " + fileName); 054 } 055 056 PackageTree tree = new PackageTree(deobfuscator); 057 058 if (isAndroid) { 059 List<SourceFile> sourceFiles = SourceFiles.extractDexData(inputFile); 060 try { 061 sourceFiles.stream().flatMap(f -> f.getMethodRefs().stream()).forEach(tree::addMethodRef); 062 sourceFiles.stream().flatMap(f -> f.getFieldRefs().stream()).forEach(tree::addFieldRef); 063 } finally { 064 sourceFiles.forEach(IOUtils::closeQuietly); 065 } 066 } 067 068 SourceFile jar = null; 069 if (isAar && options.getPrintDeclarations()) { 070 jar = SourceFiles.extractJarFromAar(inputFile); 071 } else if (isJar && options.getPrintDeclarations()) { 072 jar = SourceFiles.extractJarFromJar(inputFile); 073 } 074 075 if (jar != null) { 076 try { 077 jar.getMethodRefs().forEach(tree::addDeclaredMethodRef); 078 jar.getFieldRefs().forEach(tree::addDeclaredFieldRef); 079 } finally { 080 IOUtils.closeQuietly(jar); 081 } 082 } 083 084 return tree; 085 } 086 087 @Override 088 protected String getInputRepresentation() { 089 return getParameters().getInputFile().getAsFile().get().getName(); 090 } 091 092 @Override 093 protected Logger getLogger() { 094 return LOGGER; 095 } 096}