--- /dev/null
+ /*
+ * Copyright (C) 2012-present the original author or authors.
+ *
+ * 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.pf4j.test;
+
+ import org.pf4j.PropertiesPluginDescriptorFinder;
+
+ import java.io.File;
+ import java.io.FileOutputStream;
+ import java.io.IOException;
+ import java.nio.file.Path;
+ import java.util.LinkedHashMap;
+ import java.util.Map;
+ import java.util.Properties;
+ import java.util.zip.ZipEntry;
+ import java.util.zip.ZipOutputStream;
+
+ /**
+ * Represents a plugin {@code zip} file.
+ * The {@code plugin.properties} file is created on the fly from the information supplied in {@link Builder}.
+ *
+ * @author Decebal Suiu
+ */
+ public class PluginZip {
+
+ private final Path path;
+ private final String pluginId;
+ private final String pluginClass;
+ private final String pluginVersion;
++ private final String pluginDependencies;
+
+ protected PluginZip(Builder builder) {
+ this.path = builder.path;
+ this.pluginId = builder.pluginId;
+ this.pluginClass = builder.pluginClass;
+ this.pluginVersion = builder.pluginVersion;
++ this.pluginDependencies = builder.pluginDependencies;
+ }
+
+ public Path path() {
+ return path;
+ }
+
+ public File file() {
+ return path.toFile();
+ }
+
+ public String pluginId() {
+ return pluginId;
+ }
+
+ public String pluginClass() {
+ return pluginClass;
+ }
+
+ public String pluginVersion() {
+ return pluginVersion;
+ }
+
++ public String pluginDependencies() { return pluginDependencies; }
++
+ public Path unzippedPath() {
+ Path path = path();
+ String fileName = path.getFileName().toString();
+
+ return path.getParent().resolve(fileName.substring(0, fileName.length() - 4)); // without ".zip" suffix
+ }
+
+ public static Properties createProperties(Map<String, String> map) {
+ Properties properties = new Properties();
+ properties.putAll(map);
+
+ return properties;
+ }
+
+ public static class Builder {
+
+ private final Path path;
+ private final String pluginId;
+
+ private String pluginClass;
+ private String pluginVersion;
++ private String pluginDependencies;
+ private Map<String, String> properties = new LinkedHashMap<>();
+ private Map<Path, byte[]> files = new LinkedHashMap<>();
+
+ public Builder(Path path, String pluginId) {
+ this.path = path;
+ this.pluginId = pluginId;
+ }
+
+ public Builder pluginClass(String pluginClass) {
+ this.pluginClass = pluginClass;
+
+ return this;
+ }
+
+ public Builder pluginVersion(String pluginVersion) {
+ this.pluginVersion = pluginVersion;
+
+ return this;
+ }
+
++ public Builder pluginDependencies(String pluginDependencies) {
++ this.pluginDependencies = pluginDependencies;
++
++ return this;
++ }
++
+ /**
+ * Add extra properties to the {@code properties} file.
+ * As possible attribute name please see {@link PropertiesPluginDescriptorFinder}.
+ */
+ public Builder properties(Map<String, String> properties) {
+ this.properties.putAll(properties);
+
+ return this;
+ }
+
+ /**
+ * Add extra property to the {@code properties} file.
+ * As possible property name please see {@link PropertiesPluginDescriptorFinder}.
+ */
+ public Builder property(String name, String value) {
+ properties.put(name, value);
+
+ return this;
+ }
+
+ /**
+ * Adds a file to the archive.
+ *
+ * @param path the relative path of the file
+ * @param content the content of the file
+ */
+ public Builder addFile(Path path, byte[] content) {
+ files.put(path, content.clone());
+
+ return this;
+ }
+
+ /**
+ * Adds a file to the archive.
+ *
+ * @param path the relative path of the file
+ * @param content the content of the file
+ */
+ public Builder addFile(Path path, String content) {
+ files.put(path, content.getBytes());
+
+ return this;
+ }
+
+ public PluginZip build() throws IOException {
+ createPropertiesFile();
+
+ return new PluginZip(this);
+ }
+
+ protected void createPropertiesFile() throws IOException {
+ Map<String, String> map = new LinkedHashMap<>();
+ map.put(PropertiesPluginDescriptorFinder.PLUGIN_ID, pluginId);
+ map.put(PropertiesPluginDescriptorFinder.PLUGIN_VERSION, pluginVersion);
++ if (pluginDependencies != null) {
++ map.put(PropertiesPluginDescriptorFinder.PLUGIN_DEPENDENCIES, pluginDependencies);
++ }
+ if (pluginClass != null) {
+ map.put(PropertiesPluginDescriptorFinder.PLUGIN_CLASS, pluginClass);
+ }
+ if (properties != null) {
+ map.putAll(properties);
+ }
+
+ try (ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(path.toFile()))) {
+ ZipEntry propertiesFile = new ZipEntry(PropertiesPluginDescriptorFinder.DEFAULT_PROPERTIES_FILE_NAME);
+ outputStream.putNextEntry(propertiesFile);
+ createProperties(map).store(outputStream, "");
+ outputStream.closeEntry();
+
+ for (Map.Entry<Path, byte[]> fileEntry : files.entrySet()) {
+ ZipEntry file = new ZipEntry(fileEntry.getKey().toString());
+ outputStream.putNextEntry(file);
+ outputStream.write(fileEntry.getValue());
+ outputStream.closeEntry();
+ }
+ }
+ }
+
+ }
+
+ }