package com.atlassian.labs.speakeasy.manager.convention;
import com.atlassian.labs.speakeasy.descriptor.DescriptorGeneratorManagerImpl;
import com.atlassian.labs.speakeasy.descriptor.external.SpeakeasyWebResourceModuleDescriptor;
import com.atlassian.labs.speakeasy.commonjs.descriptor.SpeakeasyCommonJsModulesDescriptor;
import com.atlassian.labs.speakeasy.manager.PluginOperationFailedException;
import com.atlassian.labs.speakeasy.descriptor.external.webfragment.SpeakeasyWebItemModuleDescriptor;
import com.atlassian.labs.speakeasy.manager.convention.external.ConventionDescriptorGenerator;
import com.atlassian.labs.speakeasy.model.JsonManifest;
import com.atlassian.labs.speakeasy.util.WebResourceUtil;
import com.atlassian.plugin.*;
import com.atlassian.plugin.event.PluginEventManager;
import com.atlassian.plugin.hostcontainer.HostContainer;
import com.atlassian.plugin.module.ModuleFactory;
import com.atlassian.plugin.osgi.util.OsgiHeaderUtil;
import com.atlassian.plugin.webresource.WebResourceManager;
import com.atlassian.plugin.webresource.WebResourceModuleDescriptor;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceRegistration;
import static com.google.common.collect.Sets.newHashSet;
/**
*
*/
public class ConventionDescriptorGeneratorServiceFactory implements ServiceFactory
{
private final ModuleFactory moduleFactory;
private final BundleContext bundleContext;
private final PluginAccessor pluginAccessor;
private final HostContainer hostContainer;
private final DescriptorGeneratorManagerImpl descriptorGeneratorManager;
private final PluginEventManager pluginEventManager;
private final JsonToElementParser jsonToElementParser;
private final WebResourceManager webResourceManager;
private final JsonManifestHandler jsonManifestHandler;
private final PluginController pluginController;
//private final Set<String> trackedPlugins = new CopyOnWriteArraySet<String>();
public ConventionDescriptorGeneratorServiceFactory(final ModuleFactory moduleFactory, final BundleContext bundleContext, final PluginAccessor pluginAccessor, HostContainer hostContainer, DescriptorGeneratorManagerImpl descriptorGeneratorManager, JsonToElementParser jsonToElementParser, WebResourceManager webResourceManager, PluginEventManager pluginEventManager, final PluginController pluginController, JsonManifestHandler jsonManifestHandler)
{
this.moduleFactory = moduleFactory;
this.bundleContext = bundleContext;
this.pluginAccessor = pluginAccessor;
this.hostContainer = hostContainer;
this.descriptorGeneratorManager = descriptorGeneratorManager;
this.jsonToElementParser = jsonToElementParser;
this.pluginEventManager = pluginEventManager;
this.webResourceManager = webResourceManager;
this.pluginController = pluginController;
this.jsonManifestHandler = jsonManifestHandler;
}
public Object getService(Bundle bundle, ServiceRegistration registration)
{
DocumentFactory factory = DocumentFactory.getInstance();
String pluginKey = OsgiHeaderUtil.getPluginKey(bundle);
Plugin plugin = pluginAccessor.getPlugin(pluginKey);
if (bundle.getEntry("atlassian-extension.json") != null)
{
JsonManifest mf = jsonManifestHandler.read(plugin);
if (mf.getScreenshot() != null)
{
registerScreenshotWebResourceDescriptor(bundle, factory, plugin, mf.getScreenshot());
}
}
if (bundle.getEntry("js/") != null)
{
SpeakeasyCommonJsModulesDescriptor descriptor = new SpeakeasyCommonJsModulesDescriptor(
moduleFactory, bundleContext, hostContainer, descriptorGeneratorManager, pluginAccessor);
Element modules = factory.createElement("scoped-modules")
.addAttribute("key", "modules")
.addAttribute("location", "js");
if (bundle.getEntry("css/") != null)
{
modules.addElement("dependency").setText("css");
}
descriptor.init(plugin, modules);
bundle.getBundleContext().registerService(ModuleDescriptor.class.getName(), descriptor, null);
}
if (bundle.getEntry("images/") != null)
{
registerSpeakeasyWebResourceDescriptor(bundle, factory, plugin, "images");
}
if (bundle.getEntry("css") != null)
{
registerSpeakeasyWebResourceDescriptor(bundle, factory, plugin, "css");
}
if (bundle.getEntry("ui/web-items.json") != null)
{
registerSpeakeasyWebItems(bundle, plugin);
}
//trackedPlugins.add(pluginKey);
return new ConventionDescriptorGenerator()
{
};
}
private void registerSpeakeasyWebItems(Bundle bundle, Plugin plugin)
{
try
{
for (Element element : jsonToElementParser.createWebItems(plugin.getResourceAsStream("ui/web-items.json")))
{
SpeakeasyWebItemModuleDescriptor descriptor = new SpeakeasyWebItemModuleDescriptor(moduleFactory, bundleContext, descriptorGeneratorManager, webResourceManager);
descriptor.init(plugin, element);
bundle.getBundleContext().registerService(ModuleDescriptor.class.getName(), descriptor, null);
}
}
catch (PluginOperationFailedException e)
{
e.setPluginKey(plugin.getKey());
throw e;
}
}
private void registerScreenshotWebResourceDescriptor(Bundle bundle, DocumentFactory factory, Plugin plugin, String screenshotPath)
{
WebResourceModuleDescriptor descriptor = WebResourceUtil.instantiateDescriptor(moduleFactory, hostContainer);
Element element = factory.createElement("web-resource")
.addAttribute("key", "screenshot");
element.addElement("resource")
.addAttribute("type", "download")
.addAttribute("name", "screenshot.png")
.addAttribute("location", screenshotPath);
descriptor.init(plugin, element);
bundle.getBundleContext().registerService(ModuleDescriptor.class.getName(), descriptor, null);
}
private void registerSpeakeasyWebResourceDescriptor(Bundle bundle, DocumentFactory factory, Plugin plugin, String type)
{
SpeakeasyWebResourceModuleDescriptor descriptor = new SpeakeasyWebResourceModuleDescriptor(moduleFactory, hostContainer, bundleContext, descriptorGeneratorManager);
Element element = factory.createElement("scoped-web-resource")
.addAttribute("key", type)
.addAttribute("scan", "/" + type);
element.addElement("transformation")
.addAttribute("extension", "css")
.addElement("transformer")
.addAttribute("key", "cssVariables")
.addAttribute("imagesModuleKey", plugin.getKey() + ":" + "images-" + bundle.getLastModified())
.addAttribute("fullModuleKey", plugin.getKey() + ":" + "css-" + bundle.getLastModified());
descriptor.init(plugin, element);
bundle.getBundleContext().registerService(ModuleDescriptor.class.getName(), descriptor, null);
}
public void ungetService(Bundle bundle, ServiceRegistration registration, Object service)
{
final String pluginKey = OsgiHeaderUtil.getPluginKey(bundle);
// Plugin plugin = pluginAccessor.getPlugin(pluginKey);
// if (trackedPlugins.contains(plugin.getKey()))
// {
// for (ModuleDescriptor descriptor : plugin.getModuleDescriptors())
// {
// if (descriptor instanceof StateAware)
// {
// ((StateAware)descriptor).disabled();
// }
// }
// }
//trackedPlugins.remove(pluginKey);
}
}