1 package com.atlassian.plugins.rest.doclet.generators.resourcedoc;
2
3 import com.sun.jersey.api.model.AbstractResource;
4 import com.sun.jersey.server.wadl.WadlGenerator;
5 import com.sun.jersey.server.wadl.generators.resourcedoc.WadlGeneratorResourceDocSupport;
6 import com.sun.jersey.server.wadl.generators.resourcedoc.model.ResourceDocType;
7 import com.sun.research.ws.wadl.Resource;
8 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory;
10 import org.w3c.dom.Document;
11 import org.w3c.dom.NamedNodeMap;
12 import org.w3c.dom.Node;
13 import org.w3c.dom.NodeList;
14
15 import java.net.URL;
16 import java.util.HashMap;
17 import javax.xml.parsers.DocumentBuilder;
18 import javax.xml.parsers.DocumentBuilderFactory;
19
20
21
22
23
24
25
26
27
28
29
30
31
32 public class AtlassianWadlGeneratorResourceDocSupport extends WadlGeneratorResourceDocSupport
33 {
34 private HashMap<String, ResourcePathInformation> resourcePathInformation;
35
36 private static final Logger LOG = LoggerFactory.getLogger(AtlassianWadlGeneratorResourceDocSupport.class);
37 private static final String ATLASSIAN_PLUGIN_XML = "atlassian-plugin.xml";
38
39 public AtlassianWadlGeneratorResourceDocSupport()
40 {
41 super();
42 }
43
44 public AtlassianWadlGeneratorResourceDocSupport(WadlGenerator wadlGenerator, ResourceDocType resourceDoc)
45 {
46 super(wadlGenerator, resourceDoc);
47 }
48
49 @Override
50 public void init() throws Exception
51 {
52 super.init();
53 parseAtlassianPluginXML();
54 }
55
56 private void parseAtlassianPluginXML()
57 {
58
59 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
60
61 try
62 {
63 final URL resource = getClass().getClassLoader().getResource(ATLASSIAN_PLUGIN_XML);
64 if (resource == null) return;
65 LOG.info("Found " + ATLASSIAN_PLUGIN_XML + " file! Looking for rest plugin module descriptors...");
66
67 DocumentBuilder db = dbf.newDocumentBuilder();
68
69 resourcePathInformation = new HashMap<String, ResourcePathInformation>();
70
71 final Document document = db.parse(resource.toExternalForm());
72 final NodeList restPluginModuleDescriptors = document.getElementsByTagName("rest");
73 final int numPluginModuleDescriptors = restPluginModuleDescriptors.getLength();
74 LOG.info("Found " + numPluginModuleDescriptors + " rest plugin module descriptors.");
75
76 for (int i = 0; i < numPluginModuleDescriptors; i++)
77 {
78 final Node node = restPluginModuleDescriptors.item(i);
79
80 final NamedNodeMap attributes = node.getAttributes();
81 final Node pathItem = attributes.getNamedItem("path");
82 final Node versionItem = attributes.getNamedItem("version");
83 if (pathItem == null || versionItem == null)
84 continue;
85
86 String resourcePath = pathItem.getNodeValue();
87 String version = versionItem.getNodeValue();
88
89 LOG.info("Found rest end point with path '" + resourcePath + "' and version '" + version + "'");
90
91
92 if (resourcePath.indexOf("/") != -1)
93 {
94 resourcePath = resourcePath.substring(resourcePath.indexOf("/") + 1);
95 }
96
97 final NodeList list = node.getChildNodes();
98 for (int j = 0; j < list.getLength(); j++)
99 {
100 final Node child = list.item(j);
101 if (child.getNodeName().equals("package"))
102 {
103 final String packageName = child.getFirstChild().getNodeValue();
104 LOG.info("Map package '" + packageName + "' to resource path '" + resourcePath + "' and version '" + version + "'");
105 resourcePathInformation.put(packageName, new ResourcePathInformation(resourcePath, version));
106 }
107 }
108 }
109 }
110 catch (Exception ex)
111 {
112 LOG.error("Failed to read " + ATLASSIAN_PLUGIN_XML + " and parse rest plugin module descriptor information. Reason", ex);
113 }
114 }
115
116 @Override
117 public Resource createResource(AbstractResource r, String path)
118 {
119 final Resource result = super.createResource(r, path);
120 boolean resourcePathChanged = false;
121 for (String packageName : resourcePathInformation.keySet())
122 {
123 if (r.getResourceClass().getPackage().getName().startsWith(packageName))
124 {
125 final ResourcePathInformation pathInformation = resourcePathInformation.get(packageName);
126 final String newPath = pathInformation.getPath() + "/" + pathInformation.getVersion() + "/" + result.getPath();
127 result.setPath(newPath);
128 resourcePathChanged = true;
129 LOG.info("Setting resource path of rest end point '" + r.getResourceClass().getCanonicalName() + "' to '" + newPath + "'");
130 break;
131 }
132 }
133 if (!resourcePathChanged)
134 {
135 LOG.info("Resource path of rest end point '" + r.getResourceClass().getCanonicalName() + "' unchanged no mapping to rest plugin module descriptor found.");
136 }
137
138 return result;
139 }
140
141 public class ResourcePathInformation
142 {
143 private final String path;
144 private final String version;
145
146 public ResourcePathInformation(String path, String version)
147 {
148 this.path = path;
149 this.version = version;
150 }
151
152 public String getVersion()
153 {
154 return version;
155 }
156
157 public String getPath()
158 {
159 return path;
160 }
161 }
162
163 }