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