package com.atlassian.labs.speakeasy.manager.convention;
import com.atlassian.labs.speakeasy.git.GitRepositoryManager;
import com.atlassian.labs.speakeasy.manager.*;
import com.atlassian.labs.speakeasy.model.JsonManifest;
import com.atlassian.labs.speakeasy.util.JavascriptEscaper;
import com.atlassian.plugin.PluginArtifact;
import com.atlassian.templaterenderer.TemplateRenderer;
import com.google.common.collect.ImmutableMap;
import org.osgi.framework.BundleContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.*;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.zip.ZipOutputStream;
import static com.google.common.collect.Iterables.concat;
import static java.util.Arrays.asList;
/**
*
*/
@Component
public class ZipPluginTypeHandler extends AbstractOsgiPluginTypeHandler implements PluginTypeHandler
{
private static final Iterable<Pattern> zipWhitelist = concat(CORE_WHITELIST, asList(
Pattern.compile("atlassian-extension.json")));
private final TemplateRenderer templateRenderer;
private final ZipTransformer zipTransformer;
private final JsonManifestHandler jsonHandler;
private final SettingsManager settingsManager;
@Autowired
public ZipPluginTypeHandler(ZipTransformer zipTransformer, TemplateRenderer templateRenderer,
JsonManifestHandler jsonHandler, SettingsManager settingsManager, GitRepositoryManager gitRepositoryManager)
{
super(templateRenderer, gitRepositoryManager);
this.templateRenderer = templateRenderer;
this.zipTransformer = zipTransformer;
this.jsonHandler = jsonHandler;
this.settingsManager = settingsManager;
}
@Override
public File getPluginAsProject(String pluginKey, Map<String, Object> context)
{
throw new UnsupportedOperationException("Cannot create AMPS project for convention extension");
}
@Override
protected String getDescriptorPath()
{
return JsonManifest.ATLASSIAN_EXTENSION_PATH;
}
@Override
protected String getExtension()
{
return "zip";
}
@Override
protected void forkDescriptor(InputStream original, OutputStream output, String key, String description) throws IOException
{
JsonManifest mf = zipTransformer.readManifest(key, original);
mf.setKey(key);
mf.setDescription(description);
zipTransformer.writeManifest(mf, output);
}
@Override
protected void createExampleContents(ZipOutputStream zout, String pluginKey, String name, String description) throws IOException
{
ZipWriter.addDirectoryToZip(zout, "js/");
ZipWriter.addFileToZip(zout, "js/" + pluginKey + "/main.js", "main.js");
ZipWriter.addDirectoryToZip(zout, "css/");
ZipWriter.addFileToZip(zout, "css/main.css", "main.css");
ZipWriter.addDirectoryToZip(zout, "images/");
ZipWriter.addFileToZip(zout, "images/projectavatar.png", "projectavatar.png");
ZipWriter.addDirectoryToZip(zout, "ui/");
ZipWriter.addFileToZip(zout, "ui/web-items.json", "web-items.json");
ZipWriter.addFileToZip(zout, "screenshot.png", "screenshot.png");
ZipWriter.addVelocityFileToZip(zout, "atlassian-extension.json", "atlassian-extension.vm", templateRenderer,
ImmutableMap.<String,Object>of(
"key", pluginKey,
"description", JavascriptEscaper.escape(description),
"name", JavascriptEscaper.escape(name)));
}
@Override
protected Iterable<Pattern> getWhitelistPatterns()
{
return zipWhitelist;
}
@Override
protected String extractPluginKey(PluginArtifact artifact)
{
return zipTransformer.extractPluginKey(artifact);
}
@Override
protected PluginArtifact validatePluginArtifact(PluginArtifact pluginArtifact)
{
if (pluginArtifact.doesResourceExist(JsonManifest.ATLASSIAN_EXTENSION_PATH))
{
JsonManifest descriptor = jsonHandler.read(pluginArtifact);
final List<String> errors = descriptor.isValid(settingsManager.getSettings());
if (!errors.isEmpty())
{
throw new PluginOperationFailedException("Error validating '" + JsonManifest.ATLASSIAN_EXTENSION_PATH + "': " + errors, descriptor.getKey());
}
return zipTransformer.convertConventionZipToPluginJar(descriptor, pluginArtifact);
}
else
{
throw new PluginOperationFailedException("File '" + JsonManifest.ATLASSIAN_EXTENSION_PATH + "' expected", null);
}
}
}