/*
 * 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.plugin;

import org.pf4j.PropertiesPluginDescriptorFinder;

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;

    protected PluginZip(Builder builder) {
        this.path = builder.path;
        this.pluginId = builder.pluginId;
        this.pluginClass = builder.pluginClass;
        this.pluginVersion = builder.pluginVersion;
    }

    public Path path() {
        return path;
    }

    public String pluginId() {
        return pluginId;
    }

    public String pluginClass() {
        return pluginClass;
    }

    public String pluginVersion() {
        return pluginVersion;
    }

    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 Map<String, String> properties;

        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;
        }

        /**
         * Add extra properties to the {@code properties} file.
         */
        public Builder properties(Map<String, String> properties) {
            this.properties = properties;

            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 (pluginClass != null) {
                map.put(PropertiesPluginDescriptorFinder.PLUGIN_CLASS, pluginClass);
            }
            if (properties != null) {
                map.putAll(properties);
            }

            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();
            outputStream.close();
        }

    }

}

@@ -698,16 +698,37 @@
 inder;%0A%0A
+import java.io.File;%0A
 import j
@@ -1586,32 +1586,94 @@
 rn path;%0A    %7D%0A%0A
+    public File file() %7B%0A        return path.toFile();%0A    %7D%0A%0A
     public Strin
@@ -2509,32 +2509,56 @@
 ring%3E properties
+ = new LinkedHashMap%3C%3E()
 ;%0A%0A        publi
@@ -3036,16 +3036,107 @@
 %7D file.%0A
+         * As possible attribute name please see %7B@link PropertiesPluginDescriptorFinder%7D.%0A
         
@@ -3238,21 +3238,342 @@
 ties
- = properties
+.putAll(properties);%0A%0A            return this;%0A        %7D%0A%0A        /**%0A         * Add extra property to the %7B@code properties%7D file.%0A         * As possible property name please see %7B@link PropertiesPluginDescriptorFinder%7D.%0A         */%0A        public Builder property(String name, String value) %7B%0A            properties.put(name, value)
 ;%0A%0A 

Improve PluginZip