/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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 org.jetbrains.kotlin.generators.mockJDK;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.intellij.openapi.util.io.FileUtil;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
public class GenerateMockJdk {
private static final String[] ENTRIES = {
"java/awt/Component.class",
"java/awt/Container.class",
"java/awt/Dimension.class",
"java/awt/event/ActionEvent.class",
"java/awt/event/ActionListener.class",
"java/awt/AWTKeyStroke.class",
"java/awt/Frame.class",
"java/awt/GridBagConstraints.class",
"java/awt/Window.class",
"java/beans/beancontext/BeanContextServiceRevokedListener.class",
"java/beans/beancontext/BeanContextServicesSupport.class",
"java/io/BufferedInputStream.class",
"java/io/BufferedOutputStream.class",
"java/io/BufferedReader.class",
"java/io/BufferedWriter.class",
"java/io/ByteArrayInputStream.class",
"java/io/ByteArrayOutputStream.class",
"java/io/Closeable.class",
"java/io/DataInputStream.class",
"java/io/EOFException.class",
"java/io/Externalizable.class",
"java/io/File.class",
"java/io/FileInputStream.class",
"java/io/FilenameFilter.class",
"java/io/FileFilter.class",
"java/io/FileNotFoundException.class",
"java/io/FileOutputStream.class",
"java/io/FileReader.class",
"java/io/FileWriter.class",
"java/io/FilterOutputStream.class",
"java/io/InputStream.class",
"java/io/InputStreamReader.class",
"java/io/IOException.class",
"java/io/ObjectInput.class",
"java/io/ObjectInputStream.class",
"java/io/ObjectOutput.class",
"java/io/ObjectOutputStream.class",
"java/io/ObjectStreamException.class",
"java/io/OutputStream.class",
"java/io/OutputStreamWriter.class",
"java/io/PrintStream.class",
"java/io/RandomAccessFile.class",
"java/io/Reader.class",
"java/io/Serializable.class",
"java/io/Writer.class",
"java/lang/AbstractStringBuilder.class",
"java/lang/annotation/Annotation.class",
"java/lang/annotation/AnnotationFormatError.class",
"java/lang/annotation/AnnotationTypeMismatchException.class",
"java/lang/annotation/Documented.class",
"java/lang/annotation/ElementType.class",
"java/lang/annotation/IncompleteAnnotationException.class",
"java/lang/annotation/Inherited.class",
"java/lang/annotation/Retention.class",
"java/lang/annotation/RetentionPolicy.class",
"java/lang/annotation/Target.class",
"java/lang/Appendable.class",
"java/lang/AutoCloseable.class",
"java/lang/ArithmeticException.class",
"java/lang/ArrayIndexOutOfBoundsException.class",
"java/lang/ArrayStoreException.class",
"java/lang/AssertionError.class",
"java/lang/Boolean.class",
"java/lang/Byte.class",
"java/lang/Character.class",
"java/lang/CharSequence.class",
"java/lang/Class.class",
"java/lang/ClassCastException.class",
"java/lang/ClassLoader.class",
"java/lang/ClassNotFoundException.class",
"java/lang/Cloneable.class",
"java/lang/CloneNotSupportedException.class",
"java/lang/Comparable.class",
"java/lang/Deprecated.class",
"java/lang/Double.class",
"java/lang/Enum.class",
"java/lang/Error.class",
"java/lang/Exception.class",
"java/lang/Float.class",
"java/lang/IllegalAccessException.class",
"java/lang/IllegalArgumentException.class",
"java/lang/IllegalStateException.class",
"java/lang/IndexOutOfBoundsException.class",
"java/lang/Integer.class",
"java/lang/Iterable.class",
"java/lang/Long.class",
"java/lang/Math.class",
"java/lang/NegativeArraySizeException.class",
"java/lang/NoSuchFieldException.class",
"java/lang/NullPointerException.class",
"java/lang/Number.class",
"java/lang/NumberFormatException.class",
"java/lang/Object.class",
"java/lang/Override.class",
"java/lang/Readable.class",
"java/lang/reflect/AccessibleObject.class",
"java/lang/reflect/AnnotatedElement.class",
"java/lang/reflect/Array.class",
"java/lang/reflect/Constructor.class",
"java/lang/reflect/Field.class",
"java/lang/reflect/GenericDeclaration.class",
"java/lang/reflect/Member.class",
"java/lang/reflect/Method.class",
"java/lang/reflect/Type.class",
"java/lang/Runnable.class",
"java/lang/RuntimeException.class",
"java/lang/Short.class",
"java/lang/String.class",
"java/lang/StringBuffer.class",
"java/lang/StringBuilder.class",
"java/lang/SuppressWarnings.class",
"java/lang/System.class",
"java/lang/Thread.class",
"java/lang/ThreadLocal.class",
"java/lang/Throwable.class",
"java/lang/UnsupportedOperationException.class",
"java/lang/Void.class",
"java/net/ConnectException.class",
"java/net/DatagramPacket.class",
"java/net/DatagramSocket.class",
"java/net/InetAddress.class",
"java/net/InetAddressImpl.class",
"java/net/MalformedURLException.class",
"java/net/ServerSocket.class",
"java/net/Socket.class",
"java/net/SocketException.class",
"java/net/UnknownHostException.class",
"java/net/URI.class",
"java/net/URL.class",
"java/net/URLConnection.class",
"java/nio/charset/Charset.class",
"java/rmi/Remote.class",
"java/rmi/RemoteException.class",
"java/security/GeneralSecurityException.class",
"java/security/Identity.class",
"java/security/NoSuchAlgorithmException.class",
"java/security/Policy.class",
"java/security/Provider.class",
"java/security/Security.class",
"java/security/Signer.class",
"java/sql/Array.class",
"java/sql/BatchUpdateException.class",
"java/sql/Blob.class",
"java/sql/CallableStatement.class",
"java/sql/Clob.class",
"java/sql/Connection.class",
"java/sql/DatabaseMetaData.class",
"java/sql/DataTruncation.class",
"java/sql/Date.class",
"java/sql/Driver.class",
"java/sql/DriverInfo.class",
"java/sql/DriverManager.class",
"java/sql/DriverPropertyInfo.class",
"java/sql/ParameterMetaData.class",
"java/sql/PreparedStatement.class",
"java/sql/Ref.class",
"java/sql/ResultSet.class",
"java/sql/ResultSetMetaData.class",
"java/sql/Savepoint.class",
"java/sql/SQLData.class",
"java/sql/SQLException.class",
"java/sql/SQLInput.class",
"java/sql/SQLOutput.class",
"java/sql/SQLPermission.class",
"java/sql/SQLWarning.class",
"java/sql/Statement.class",
"java/sql/Struct.class",
"java/sql/Time.class",
"java/sql/Timestamp.class",
"java/sql/Types.class",
"java/util/AbstractCollection.class",
"java/util/AbstractList.class",
"java/util/AbstractMap.class",
"java/util/AbstractQueue.class",
"java/util/AbstractSequentialList.class",
"java/util/AbstractSet.class",
"java/util/ArrayList.class",
"java/util/Arrays.class",
"java/util/Calendar.class",
"java/util/Collection.class",
"java/util/Collections.class",
"java/util/Comparator.class",
"java/util/concurrent/atomic/AtomicBoolean.class",
"java/util/concurrent/atomic/AtomicInteger.class",
"java/util/concurrent/atomic/AtomicIntegerArray.class",
"java/util/concurrent/atomic/AtomicIntegerFieldUpdater.class",
"java/util/concurrent/atomic/AtomicLong.class",
"java/util/concurrent/atomic/AtomicLongArray.class",
"java/util/concurrent/atomic/AtomicLongFieldUpdater.class",
"java/util/concurrent/atomic/AtomicMarkableReference.class",
"java/util/concurrent/atomic/AtomicReference.class",
"java/util/concurrent/atomic/AtomicReferenceArray.class",
"java/util/concurrent/atomic/AtomicReferenceFieldUpdater.class",
"java/util/concurrent/atomic/AtomicStampedReference.class",
"java/util/concurrent/Callable.class",
"java/util/concurrent/ConcurrentHashMap.class",
"java/util/concurrent/locks/AbstractQueuedSynchronizer.class",
"java/util/concurrent/locks/Condition.class",
"java/util/concurrent/locks/Lock.class",
"java/util/concurrent/locks/LockSupport.class",
"java/util/concurrent/locks/ReadWriteLock.class",
"java/util/concurrent/locks/ReentrantLock.class",
"java/util/concurrent/locks/ReentrantReadWriteLock.class",
"java/util/concurrent/TimeUnit.class",
"java/util/ConcurrentModificationException.class",
"java/util/Date.class",
"java/util/Enumeration.class",
"java/util/EventListener.class",
"java/util/GregorianCalendar.class",
"java/util/HashMap.class",
"java/util/HashSet.class",
"java/util/IdentityHashMap.class",
"java/util/Iterator.class",
"java/util/LinkedHashSet.class",
"java/util/List.class",
"java/util/ListIterator.class",
"java/util/Locale.class",
"java/util/Map.class",
"java/util/NoSuchElementException.class",
"java/util/Properties.class",
"java/util/Random.class",
"java/util/RandomAccess.class",
"java/util/regex/Pattern.class",
"java/util/Objects.class",
"java/util/Set.class",
"java/util/SortedMap.class",
"java/util/SortedSet.class",
"java/util/TimeZone.class",
"java/util/TreeMap.class",
"java/util/TreeSet.class",
"javax/swing/AbstractButton.class",
"javax/swing/Icon.class",
"javax/swing/JButton.class",
"javax/swing/JComponent.class",
"javax/swing/JDialog.class",
"javax/swing/JFrame.class",
"javax/swing/JLabel.class",
"javax/swing/JPanel.class",
"javax/swing/JScrollPane.class",
"javax/swing/JTable.class",
"javax/swing/SwingConstants.class",
"javax/swing/SwingUtilities.class",
"javax/swing/table/TableModel.class",
"sun/util/calendar/BaseCalendar.class",
"META-INF/",
"META-INF/MANIFEST.MF",
};
private static void generateFilteredJar(File source, File target, Set<String> entryNamesToInclude, boolean assertAllFound) throws IOException {
if (!source.exists()) {
throw new AssertionError(source + " doesn't exist");
}
JarFile sourceJar = new JarFile(source);
JarOutputStream targetJar = new JarOutputStream(new FileOutputStream(target));
List<String> foundEntries = Lists.newArrayList();
List<JarEntry> sourceList = Collections.list(sourceJar.entries());
for (JarEntry entry : sourceList) {
// For Map$Entry.class we want to check Map.class presense
String topLevelClassFile = entry.getName().replaceAll("\\$.+\\.class$", ".class");
if (entryNamesToInclude.contains(topLevelClassFile)) {
targetJar.putNextEntry(new ZipEntry(entry.getName()));
FileUtil.copy(sourceJar.getInputStream(entry), targetJar);
foundEntries.add(topLevelClassFile);
}
}
targetJar.close();
sourceJar.close();
if (assertAllFound) {
HashSet<String> notFound = Sets.newHashSet(entryNamesToInclude);
notFound.removeAll(foundEntries);
if (!notFound.isEmpty()) {
System.err.println("Not found:");
for (String entry : notFound) {
System.err.println(entry);
}
throw new AssertionError("See errors above");
}
}
}
private static Set<String> getSourceFileEntries() {
Set<String> entrySet = Sets.newHashSet();
for (String entry : ENTRIES) {
String javaFile = // "src/" + (in jdk 1.7 under Mac there is no src folder in src.zip)
entry.replaceAll(".class$", ".java");
entrySet.add(javaFile);
}
return entrySet;
}
private static Set<String> getClassFileEntries() {
return Sets.newHashSet(Arrays.asList(ENTRIES));
}
public static void main(String[] args) throws IOException {
String rtJarPath = System.getProperty("rt.jar");
String srcZipPath = System.getProperty("src.zip");
if (rtJarPath == null || srcZipPath == null) {
throw new AssertionError("Provide path to rt.jar and src.zip in VM options: \"-Drt.jar=... -Dsrc.zip=...\"");
}
File rtJar = new File(rtJarPath);
File srcJar = new File(srcZipPath);
generateFilteredJar(
rtJar,
new File("compiler/testData/mockJDK/jre/lib/rt.jar"),
getClassFileEntries(),
true);
generateFilteredJar(
srcJar,
new File("compiler/testData/mockJDK/src.zip"),
getSourceFileEntries(),
false);
}
private GenerateMockJdk() {
}
}