package com.atlassian.labs.speakeasy.manager;
import com.atlassian.labs.speakeasy.git.GitRepositoryManager;
import com.atlassian.plugin.PluginArtifact;
import com.atlassian.templaterenderer.TemplateRenderer;
import org.apache.commons.io.IOUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.osgi.framework.BundleContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.*;
import java.util.Collection;
import java.util.List;
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 JarPluginTypeHandler extends AbstractOsgiPluginTypeHandler implements PluginTypeHandler
{
private static final Iterable<Pattern> jarWhitelist = concat(CORE_WHITELIST, asList(
Pattern.compile("atlassian-plugin.xml")));
private static final Collection<String> pluginModulesWhitelist = asList(
"plugin-info",
"scoped-web-resource",
"scoped-web-item",
"scoped-web-section",
"scoped-modules");
@Autowired
public JarPluginTypeHandler(TemplateRenderer templateRenderer, GitRepositoryManager gitRepositoryManager)
{
super(templateRenderer, gitRepositoryManager);
}
protected String getExtension()
{
return "jar";
}
public String getDescriptorPath()
{
return "atlassian-plugin.xml";
}
@Override
protected void forkDescriptor(InputStream contents, OutputStream zout, String key, String description) throws IOException
{
try
{
Document doc = new SAXReader().read(contents);
doc.getRootElement().addAttribute("key", key);
Element pluginInfo = doc.getRootElement().element("plugin-info");
if (pluginInfo.element("description") != null)
{
pluginInfo.addElement("description");
}
pluginInfo.element("description").setText(description);
new XMLWriter( zout, OutputFormat.createPrettyPrint() ).write(doc);
}
catch (DocumentException e)
{
throw new IOException("Unable to create new forked descriptor", e);
}
}
@Override
protected void createExampleContents(ZipOutputStream zout, String pluginKey, String name, String description)
{
throw new UnsupportedOperationException("Don't support example apps for jars yet");
}
@Override
protected Iterable<Pattern> getWhitelistPatterns()
{
return jarWhitelist;
}
@Override
protected String extractPluginKey(PluginArtifact artifact)
{
return loadPluginDescriptor(artifact).getRootElement().attributeValue("key");
}
@Override
protected PluginArtifact validatePluginArtifact(PluginArtifact pluginArtifact)
{
Document doc = loadPluginDescriptor(pluginArtifact);
for (Element module : ((List<Element>)doc.getRootElement().elements()))
{
if (!pluginModulesWhitelist.contains(module.getName()))
{
throw new PluginOperationFailedException("Invalid plugin module: " + module.getName(), doc.getRootElement().attributeValue("key"));
}
}
return pluginArtifact;
}
private Document loadPluginDescriptor(PluginArtifact plugin) throws PluginOperationFailedException
{
InputStream in = null;
try
{
in = plugin.getResourceAsStream("atlassian-plugin.xml");
return new SAXReader().read(in);
}
catch (final DocumentException e)
{
throw new PluginOperationFailedException("Cannot parse XML plugin descriptor", e, null);
}
finally
{
IOUtils.closeQuietly(in);
}
}
}