com.atlassian.clientpluginsdemorefapp.rest.BackdoorResource Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of atlassian-clientside-extensions-demo Show documentation
Show all versions of atlassian-clientside-extensions-demo Show documentation
Demonstrates how product developers and plugin developers can make use of the Client-side Extensions APIs.
package com.atlassian.clientpluginsdemorefapp.rest;
import com.atlassian.plugin.ModuleDescriptor;
import com.atlassian.plugin.PluginAccessor;
import com.atlassian.plugin.descriptors.AbstractModuleDescriptor;
import com.atlassian.plugin.osgi.external.ListableModuleDescriptorFactory;
import com.atlassian.plugin.servlet.descriptors.ServletModuleDescriptor;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.atlassian.plugins.rest.common.security.AnonymousAllowed;
import org.codehaus.jackson.annotate.JsonCreator;
import org.codehaus.jackson.annotate.JsonProperty;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.function.Function;
import static com.atlassian.clientpluginsdemorefapp.rest.BackdoorResource.ModuleDto.toDto;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toCollection;
import static java.util.stream.Collectors.toList;
import static java.util.stream.StreamSupport.stream;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import static org.osgi.framework.FrameworkUtil.getBundle;
/**
* Provides a backdoor into this plugin.
*/
@AnonymousAllowed
@Path("backdoor")
@Produces(APPLICATION_JSON)
public class BackdoorResource {
private static final Function, String> GET_BSN = serviceReference ->
serviceReference.getBundle().getSymbolicName();
private final BundleContext bundleContext;
private final PluginAccessor pluginAccessor;
public BackdoorResource(@ComponentImport final PluginAccessor pluginAccessor) {
this.bundleContext = getBundle(getClass()).getBundleContext();
this.pluginAccessor = requireNonNull(pluginAccessor);
}
/**
* Returns the registered module types.
*
* The full URL is http://localhost:5990/refapp/rest/cse-demo/1/backdoor/module-types
*
* @return a JSON object where the property names are plugin BSNs and the value of each property is an
* array of the module types provided by that plugin
*/
@GET
@Path("module-types")
public Map> getModuleTypes() {
return moduleDescriptorFactories()
.stream()
.collect(groupingBy(
GET_BSN,
TreeMap::new,
mapping(this::getModuleType, toCollection(TreeSet::new))));
}
private String getModuleType(final ServiceReference serviceReference) {
final ListableModuleDescriptorFactory moduleDescriptorFactory = bundleContext.getService(serviceReference);
final Iterable moduleDescriptorKeyIter = moduleDescriptorFactory.getModuleDescriptorKeys();
final List moduleDescriptorKeys = stream(moduleDescriptorKeyIter.spliterator(), false).collect(toList());
switch (moduleDescriptorKeys.size()) {
case 0:
return "(none)"; // shouldn't happen
case 1:
return moduleDescriptorKeys.get(0);
default:
return "(multiple)"; // the CSE bootstrapper doesn't do this, so we don't care what these are
}
}
private Collection> moduleDescriptorFactories() {
try {
return bundleContext.getServiceReferences(ListableModuleDescriptorFactory.class, null);
} catch (InvalidSyntaxException e) {
throw new IllegalStateException("Filter is invalid", e);
}
}
/**
* Returns the details of all plugin-provided servlets.
*
* The full URL is http://localhost:5990/refapp/rest/cse-demo/1/backdoor/servlet-modules
*
* @return a JSON object where the property names are plugin keys and the value of each property is an
* array of the keys of the servlet modules provided by that plugin
*/
@GET
@Path("servlet-modules")
public Map> getServletModules() {
return pluginAccessor.getEnabledModuleDescriptorsByClass(ServletModuleDescriptor.class)
.stream()
.collect(groupingBy(
AbstractModuleDescriptor::getPluginKey,
TreeMap::new,
mapping(ServletModuleDescriptor::getKey, toCollection(TreeSet::new))));
}
@GET
@Path("module/{complete-key}")
public Object getModule(@PathParam("complete-key") final String completeKey) {
final ModuleDescriptor> moduleDescriptor = pluginAccessor.getEnabledPluginModule(completeKey);
if (moduleDescriptor == null) {
return Response.status(NOT_FOUND).build();
}
return toDto(moduleDescriptor);
}
public static class ModuleDto {
static ModuleDto toDto(final ModuleDescriptor> moduleDescriptor) {
return new ModuleDto(
moduleDescriptor.getDescription(),
moduleDescriptor.getKey(),
moduleDescriptor.getName(),
moduleDescriptor.getPluginKey());
}
@JsonProperty
private final String description;
@JsonProperty
private final String key;
@JsonProperty
private final String name;
@JsonProperty
private final String pluginKey;
@JsonCreator
private ModuleDto(@JsonProperty("description") final String description,
@JsonProperty("key") final String key,
@JsonProperty("name") final String name,
@JsonProperty("pluginKey") final String pluginKey) {
this.description = description;
this.key = key;
this.name = name;
this.pluginKey = pluginKey;
}
public String getDescription() {
return description;
}
public String getKey() {
return key;
}
public String getName() {
return name;
}
public String getPluginKey() {
return pluginKey;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy