com.gitee.starblues.plugin.pack.BasicRepackager Maven / Gradle / Ivy
The newest version!
/**
* Copyright [2019-Present] [starBlues]
*
* 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.gitee.starblues.plugin.pack;
import com.gitee.starblues.common.*;
import com.gitee.starblues.plugin.pack.utils.CommonUtils;
import com.gitee.starblues.utils.FilesUtils;
import com.gitee.starblues.utils.ObjectUtils;
import lombok.Getter;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Dependency;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.*;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import static com.gitee.starblues.common.PackageStructure.*;
import static com.gitee.starblues.common.PluginDescriptorKey.*;
/**
* 基础打包
*
* @author starBlues
* @since 3.0.0
* @version 3.1.1
*/
public class BasicRepackager implements Repackager{
@Getter
private String rootDir;
private String relativeManifestPath;
private String relativePluginMetaPath;
private String relativeResourcesDefinePath;
protected File resourcesDefineFile;
protected final RepackageMojo repackageMojo;
protected JarFile sourceJarFile;
public BasicRepackager(RepackageMojo repackageMojo) {
this.repackageMojo = repackageMojo;
}
@Override
public void repackage() throws MojoExecutionException, MojoFailureException {
sourceJarFile = CommonUtils.getSourceJarFile(repackageMojo.getProject());
checkPluginInfo();
rootDir = createRootDir();
relativeManifestPath = getRelativeManifestPath();
relativePluginMetaPath = getRelativePluginMetaPath();
relativeResourcesDefinePath = getRelativeResourcesDefinePath();
try {
Manifest manifest = getManifest();
writeManifest(manifest);
} catch (Exception e) {
repackageMojo.getLog().error(e.getMessage(), e);
throw new MojoFailureException(e);
} finally {
IOUtils.closeQuietly(sourceJarFile);
}
}
private void checkPluginInfo() throws MojoExecutionException {
PluginInfo pluginInfo = repackageMojo.getPluginInfo();
if(pluginInfo == null){
throw new MojoExecutionException("configuration.pluginInfo config cannot be empty");
}
if(ObjectUtils.isEmpty(pluginInfo.getId())){
throw new MojoExecutionException("configuration.pluginInfo.id config cannot be empty");
} else {
String id = pluginInfo.getId();
String illegal = PackageStructure.getIllegal(id);
if(illegal != null){
throw new MojoExecutionException("configuration.pluginInfo.id config can't contain: " + illegal);
}
}
if(ObjectUtils.isEmpty(pluginInfo.getBootstrapClass())){
throw new MojoExecutionException("configuration.pluginInfo.bootstrapClass config cannot be empty");
}
if(ObjectUtils.isEmpty(pluginInfo.getVersion())){
throw new MojoExecutionException("configuration.pluginInfo.version config cannot be empty");
} else {
String version = pluginInfo.getVersion();
String illegal = PackageStructure.getIllegal(version);
if(illegal != null){
throw new MojoExecutionException("configuration.pluginInfo.version config can't contain: " + illegal);
}
}
}
protected String getRelativeManifestPath(){
return MANIFEST;
}
protected String getRelativeResourcesDefinePath(){
return RESOURCES_DEFINE_NAME;
}
protected String getRelativePluginMetaPath(){
return PLUGIN_META_NAME;
}
protected String createRootDir() throws MojoFailureException {
String rootDirPath = getBasicRootDir();
File rootDir = new File(rootDirPath);
CommonUtils.deleteFile(rootDir);
if(rootDir.mkdir()){
return rootDirPath;
}
throw new MojoFailureException("Failed to create the plugin root directory. " + rootDirPath);
}
protected String getBasicRootDir(){
File outputDirectory = repackageMojo.getOutputDirectory();
return FilesUtils.joiningFilePath(outputDirectory.getPath(), PackageStructure.META_INF_NAME);
}
protected void writeManifest(Manifest manifest) throws Exception {
String manifestPath = FilesUtils.joiningFilePath(rootDir, resolvePath(this.relativeManifestPath));
File file = new File(manifestPath);
FileOutputStream outputStream = null;
try {
FileUtils.forceMkdirParent(file);
if(file.createNewFile()){
outputStream = new FileOutputStream(file, false);
manifest.write(outputStream);
}
} finally {
if(outputStream != null){
try {
outputStream.close();
} catch (IOException e) {
repackageMojo.getLog().error(e.getMessage(), e);
}
}
}
}
protected Manifest getManifest() throws Exception{
Manifest manifest = null;
if(sourceJarFile != null){
manifest = sourceJarFile.getManifest();
} else {
manifest = new Manifest();
}
Attributes attributes = manifest.getMainAttributes();
attributes.putValue(ManifestKey.MANIFEST_VERSION, ManifestKey.MANIFEST_VERSION_1_0);
attributes.putValue(ManifestKey.BUILD_TIME, CommonUtils.getDateTime());
attributes.putValue(ManifestKey.PLUGIN_META_PATH, getPluginMetaInfoPath());
attributes.putValue(ManifestKey.PLUGIN_PACKAGE_TYPE, PackageType.PLUGIN_PACKAGE_TYPE_DEV);
// 增加jar包title和version属性
MavenProject mavenProject = this.repackageMojo.getProject();
attributes.putValue(ManifestKey.IMPLEMENTATION_TITLE, mavenProject.getArtifactId());
attributes.putValue(ManifestKey.IMPLEMENTATION_VERSION, mavenProject.getVersion());
return manifest;
}
/**
* 得到插件信息存储文件路径
* @return 插件信息存储文件路径
* @throws Exception Exception
*/
protected String getPluginMetaInfoPath() throws Exception {
Properties pluginMetaInfo = createPluginMetaInfo();
return writePluginMetaInfo(pluginMetaInfo);
}
/**
* 创建插件信息
* @return Properties
* @throws Exception Exception
*/
protected Properties createPluginMetaInfo() throws Exception {
Properties properties = new Properties();
PluginInfo pluginInfo = repackageMojo.getPluginInfo();
properties.put(PLUGIN_ID, pluginInfo.getId());
properties.put(PLUGIN_BOOTSTRAP_CLASS, pluginInfo.getBootstrapClass());
properties.put(PLUGIN_VERSION, pluginInfo.getVersion());
properties.put(PLUGIN_PATH, getPluginPath());
String resourcesDefineFilePath = writeResourcesDefineFile(getResourcesDefineContent());
if(!ObjectUtils.isEmpty(resourcesDefineFilePath)){
properties.put(PLUGIN_RESOURCES_CONFIG, resourcesDefineFilePath);
}
String configFileName = pluginInfo.getConfigFileName();
if(!ObjectUtils.isEmpty(configFileName)){
properties.put(PLUGIN_CONFIG_FILE_NAME, configFileName);
}
String configFileLocation = pluginInfo.getConfigFileLocation();
if(!ObjectUtils.isEmpty(configFileLocation)){
properties.put(PLUGIN_CONFIG_FILE_LOCATION, configFileLocation);
}
String args = pluginInfo.getArgs();
if(!ObjectUtils.isEmpty(args)){
properties.put(PLUGIN_ARGS, args);
}
String provider = pluginInfo.getProvider();
if(!ObjectUtils.isEmpty(provider)){
properties.put(PLUGIN_PROVIDER, provider);
}
String requires = pluginInfo.getRequires();
if(!ObjectUtils.isEmpty(requires)){
properties.put(PLUGIN_REQUIRES, requires);
}
String dependencyPlugins = getDependencyPlugin(pluginInfo);
if(!ObjectUtils.isEmpty(dependencyPlugins)){
properties.put(PLUGIN_DEPENDENCIES, dependencyPlugins);
}
String description = pluginInfo.getDescription();
if(!ObjectUtils.isEmpty(description)){
properties.put(PLUGIN_DESCRIPTION, description);
}
String license = pluginInfo.getLicense();
if(!ObjectUtils.isEmpty(license)){
properties.put(PLUGIN_LICENSE, license);
}
return properties;
}
protected String getDependencyPlugin(PluginInfo pluginInfo){
List dependencyPlugins = pluginInfo.getDependencyPlugins();
return AbstractDependencyPlugin.toStr(dependencyPlugins);
}
/**
* 写入插件信息
* @param properties properties
* @return String
* @throws IOException IOException
*/
protected String writePluginMetaInfo(Properties properties) throws Exception {
File pluginMetaFile = createPluginMetaFile();
try (OutputStreamWriter writer = new OutputStreamWriter(
Files.newOutputStream(pluginMetaFile.toPath()), StandardCharsets.UTF_8)){
properties.store(writer, Constant.PLUGIN_METE_COMMENTS);
return pluginMetaFile.getPath();
}
}
/**
* 创建插件信息存储文件
* @return File
* @throws IOException 创建文件异常
*/
protected File createPluginMetaFile() throws IOException {
String path = FilesUtils.joiningFilePath(rootDir, resolvePath(relativePluginMetaPath));
return FilesUtils.createFile(path);
}
/**
* 获取插件路径
* @return 插件路径
*/
protected String getPluginPath(){
return repackageMojo.getProject().getBuild().getOutputDirectory();
}
protected String writeResourcesDefineFile(String resourcesDefineContent) throws Exception{
resourcesDefineFile = createResourcesDefineFile();
FileUtils.write(resourcesDefineFile, resourcesDefineContent, CHARSET_NAME, true);
return resourcesDefineFile.getPath();
}
protected File createResourcesDefineFile() throws IOException {
String path = FilesUtils.joiningFilePath(rootDir, resolvePath(relativeResourcesDefinePath));
return FilesUtils.createFile(path);
}
protected String getResourcesDefineContent() throws Exception {
String dependenciesIndex = getDependenciesIndex();
String loadMainResources = getLoadMainResources();
boolean indexIsEmpty = ObjectUtils.isEmpty(dependenciesIndex);
boolean resourceIsEmpty = ObjectUtils.isEmpty(loadMainResources);
if(!indexIsEmpty && !resourceIsEmpty){
return dependenciesIndex + "\n" + loadMainResources;
} else if(!indexIsEmpty){
return dependenciesIndex;
} else if(!resourceIsEmpty){
return loadMainResources;
} else {
return "";
}
}
protected String getDependenciesIndex() throws Exception {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(RESOURCES_DEFINE_DEPENDENCIES).append("\n");
Set libIndex = getDependenciesIndexSet();
for (String index : libIndex) {
stringBuilder.append(index).append("\n");
}
return stringBuilder.toString();
}
protected String getLoadMainResources(){
LoadMainResourcePattern loadMainResourcePattern = repackageMojo.getLoadMainResourcePattern();
if(loadMainResourcePattern == null){
return null;
}
String[] includes = loadMainResourcePattern.getIncludes();
String[] excludes = loadMainResourcePattern.getExcludes();
StringBuilder stringBuilder = new StringBuilder();
addLoadMainResources(stringBuilder, RESOURCES_DEFINE_LOAD_MAIN_INCLUDES, includes);
addLoadMainResources(stringBuilder, RESOURCES_DEFINE_LOAD_MAIN_EXCLUDES, excludes);
return stringBuilder.toString();
}
protected Set getDependenciesIndexSet() throws Exception {
Set dependencies = repackageMojo.getFilterDependencies();
Set libPaths = new HashSet<>(dependencies.size());
for (Artifact artifact : dependencies) {
if(filterArtifact(artifact)){
continue;
}
libPaths.add(getLibIndex(artifact));
}
return libPaths;
}
protected String getLibIndex(Artifact artifact){
return artifact.getFile().getPath() + repackageMojo.resolveLoadToMain(artifact);
}
private void addLoadMainResources(StringBuilder stringBuilder, String header, String[] patterns){
if(ObjectUtils.isEmpty(patterns)){
return;
}
Set patternSet = new HashSet<>(Arrays.asList(patterns));
stringBuilder.append(header).append("\n");
for (String patternStr : patternSet) {
if(ObjectUtils.isEmpty(patternStr)){
continue;
}
stringBuilder.append(resolvePattern(patternStr)).append("\n");
}
}
protected String resolvePattern(String patternStr){
return patternStr.replace(".", "/");
}
/**
* 过滤Artifact
* @param artifact Artifact
* @return 返回true表示被过滤掉
*/
protected boolean filterArtifact(Artifact artifact){
return Constant.filterMainTypeArtifact(artifact) ||
Constant.filterArtifact(artifact, repackageMojo.getIncludeSystemScope());
}
}