/** * Copyright 2017 Gunnar Morling (http://www.gunnarmorling.de/) * and/or other contributors as indicated by the @authors tag. See the * copyright.txt file in the distribution for a full listing of all * contributors. * * 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.moditect.commands; import java.io.IOException; import java.net.URI; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.util.HashMap; import java.util.Map; import org.moditect.internal.compiler.ModuleInfoCompiler; import com.github.javaparser.ast.modules.ModuleDeclaration; /** * Creates a copy of a given JAR file, adding a module-info.class descriptor. * * @author Gunnar Morling */ public class AddModuleInfo { private final String moduleInfoSource; private final String mainClass; private final Path inputJar; private final Path outputDirectory; private final boolean overwriteExistingFiles; public AddModuleInfo(String moduleInfoSource, String mainClass, Path inputJar, Path outputDirectory, boolean overwriteExistingFiles) { this.moduleInfoSource = moduleInfoSource; this.mainClass = mainClass; this.inputJar = inputJar; this.outputDirectory = outputDirectory; this.overwriteExistingFiles = overwriteExistingFiles; } public void run() { if ( Files.isDirectory( inputJar ) ) { throw new IllegalArgumentException( "Input JAR must not be a directory" ); } if ( !Files.exists( outputDirectory ) ) { throw new IllegalArgumentException( "Output directory doesn't exist: " + outputDirectory); } Path outputJar = outputDirectory.resolve( inputJar.getFileName() ); if ( Files.exists( outputJar ) && !overwriteExistingFiles ) { throw new RuntimeException( "File " + outputJar + " already exists; either set 'overwriteExistingFiles' to true or specify another output directory" ); } try { Files.copy(inputJar, outputJar, StandardCopyOption.REPLACE_EXISTING); } catch(IOException e) { throw new RuntimeException( "Couldn't copy JAR file", e ); } ModuleDeclaration module = ModuleInfoCompiler.parseModuleInfo( moduleInfoSource ); byte[] clazz = ModuleInfoCompiler.compileModuleInfo( module, mainClass ); Map<String, String> env = new HashMap<>(); env.put( "create", "true" ); URI uri = URI.create( "jar:" + outputJar.toUri().toString() ); try (FileSystem zipfs = FileSystems.newFileSystem( uri, env ) ) { Files.write( zipfs.getPath( "module-info.class" ), clazz ); } catch(IOException e) { throw new RuntimeException( "Couldn't add module-info.class to JAR", e ); } } }