blob: 03fa8f7790bf2408b6276b83c19809a099d76439 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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 proguard;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class ProguardMappingMunger {
private static final Map<String, String> PACKAGE_NAME_MAPPING = new HashMap<>();
static {
PACKAGE_NAME_MAPPING.put("sun.nio.ch", "xx001");
PACKAGE_NAME_MAPPING.put("sun.nio.fs", "xx002");
PACKAGE_NAME_MAPPING.put("sun.misc", "xx003");
PACKAGE_NAME_MAPPING.put("sun.net.spi", "xx004");
}
private static final Set<String> PROBLEMATIC_CLASSES = new HashSet<>();
static {
PROBLEMATIC_CLASSES.add("sun.nio.ch.NativeThread");
PROBLEMATIC_CLASSES.add("sun.nio.ch.UnixAsynchronousSocketChannelImpl");
PROBLEMATIC_CLASSES.add("sun.nio.ch.FileDispatcherImpl");
PROBLEMATIC_CLASSES.add("sun.nio.ch.UnixAsynchronousServerSocketChannelImpl");
PROBLEMATIC_CLASSES.add("sun.nio.ch.ServerSocketChannelImpl");
PROBLEMATIC_CLASSES.add("sun.nio.ch.DatagramChannelImpl");
PROBLEMATIC_CLASSES.add("sun.nio.ch.EPollPort");
PROBLEMATIC_CLASSES.add("sun.nio.ch.IOUtil");
PROBLEMATIC_CLASSES.add("sun.nio.ch.KQueuePort");
PROBLEMATIC_CLASSES.add("sun.nio.ch.InheritedChannel");
PROBLEMATIC_CLASSES.add("sun.nio.ch.DatagramDispatcher");
PROBLEMATIC_CLASSES.add("sun.nio.ch.EPoll");
PROBLEMATIC_CLASSES.add("sun.nio.ch.SolarisEventPort");
PROBLEMATIC_CLASSES.add("sun.nio.ch.FileKey");
PROBLEMATIC_CLASSES.add("sun.nio.ch.FileChannelImpl");
PROBLEMATIC_CLASSES.add("sun.nio.ch.SocketChannelImpl");
PROBLEMATIC_CLASSES.add("sun.nio.ch.DevPollArrayWrapper");
PROBLEMATIC_CLASSES.add("sun.nio.ch.EPollArrayWrapper");
PROBLEMATIC_CLASSES.add("sun.nio.ch.PollArrayWrapper");
PROBLEMATIC_CLASSES.add("sun.nio.ch.KQueue");
PROBLEMATIC_CLASSES.add("sun.nio.ch.Net");
PROBLEMATIC_CLASSES.add("sun.nio.fs.UnixNativeDispatcher");
PROBLEMATIC_CLASSES.add("sun.nio.fs.UnixCopyFile");
PROBLEMATIC_CLASSES.add("sun.misc.Unsafe");
PROBLEMATIC_CLASSES.add("sun.misc.Version");
PROBLEMATIC_CLASSES.add("sun.net.spi.DefaultProxySelector");
}
public static void main(String[] args) throws Exception {
if (args.length != 2) {
System.out.println("Usage ProguardMappingMunger <infile> <outfile>");
return;
}
process(args[0], args[1]);
System.out.println("Done..");
}
private static String[] parseMapping(String line) {
String trimmed = line.trim();
int separator = trimmed.indexOf("->");
String from = trimmed.substring(0, separator).trim();
String to = trimmed.substring(separator + 2).trim();
if (to.lastIndexOf(':') == (to.length() - 1)) {
to = to.substring(0, (to.length() - 1));
}
return new String[] { from, to };
}
private static String getName(String methodOrFieldName) {
if (methodOrFieldName.indexOf('(') != -1) {
String nameAndReturnType = methodOrFieldName.substring(0, methodOrFieldName.indexOf('('));
return nameAndReturnType.substring(nameAndReturnType.lastIndexOf(' ')).trim();
} else {
return methodOrFieldName.substring(methodOrFieldName.lastIndexOf(' ')).trim();
}
}
private static void process(String infile, String outfile) throws Exception {
Reader reader = new BufferedReader(new FileReader(infile));
Writer writer = new BufferedWriter(new FileWriter(outfile));
Scanner scanner = new Scanner(reader);
boolean processingProblematicClass = false;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
// Lines starting with spaces are method transformations,
// Lines starting without spaces are class transformations.
String[] mapping = parseMapping(line);
if (line.charAt(0) != ' ') {
String className = mapping[0];
String transform = mapping[1];
if (PROBLEMATIC_CLASSES.contains(className)) {
processingProblematicClass = true;
} else {
processingProblematicClass = false;
}
if (!className.equals("sun.misc.Unsafe")) {
for (Map.Entry<String, String> entries : PACKAGE_NAME_MAPPING.entrySet()) {
if (transform.startsWith(entries.getKey())) {
String nonQualifiedClassName = processingProblematicClass ?
className.substring(entries.getKey().length()) :
transform.substring(entries.getKey().length());
transform = entries.getValue() + nonQualifiedClassName;
break;
}
}
}
writer.write(className + " -> " + transform + ":\n");
} else {
String methodOrFieldName = mapping[0];
String transform = mapping[1];
writer.write(" " + methodOrFieldName + " -> " +
(processingProblematicClass ? getName(methodOrFieldName) : transform) + "\n");
}
}
}
}