/wonderland/core/src/classes/org/jdesktop/wonderland/common/ContentURI.java

https://github.com/jehc/MondocosmOS · Java · 332 lines · 183 code · 33 blank · 116 comment · 51 complexity · f16431f6d5ce9447b2c0daae470c415a MD5 · raw file

  1. /**
  2. * Project Wonderland
  3. *
  4. * Copyright (c) 2004-2009, Sun Microsystems, Inc., All Rights Reserved
  5. *
  6. * Redistributions in source code form must reproduce the above
  7. * copyright and this condition.
  8. *
  9. * The contents of this file are subject to the GNU General Public
  10. * License, Version 2 (the "License"); you may not use this file
  11. * except in compliance with the License. A copy of the License is
  12. * available at http://www.opensource.org/licenses/gpl-license.php.
  13. *
  14. * Sun designates this particular file as subject to the "Classpath"
  15. * exception as provided by Sun in the License file that accompanied
  16. * this code.
  17. */
  18. package org.jdesktop.wonderland.common;
  19. import java.io.File;
  20. import java.net.MalformedURLException;
  21. import java.net.URISyntaxException;
  22. import java.net.URL;
  23. /**
  24. * The ContentURI class uniquely identifies a resource within the content
  25. * repository.
  26. *
  27. * @author Jordan Slott <jslott@dev.java.net>
  28. */
  29. @ExperimentalAPI
  30. public class ContentURI extends AssetURI {
  31. /* Protocol: wlcontent */
  32. private String protocol = null;
  33. /* Repository root: system or user */
  34. private String root = null;
  35. /* Content path beneath root */
  36. private String assetPath = null;
  37. /* Host and port from annotation */
  38. private String hostName = null;
  39. private int hostPort = -1;
  40. /**
  41. * Constructor which takes the string represents of the URI.
  42. *
  43. * @param uri The string URI representation
  44. * @throw URISyntaxException If the URI is not well-formed
  45. */
  46. public ContentURI(String uri) throws URISyntaxException {
  47. super(uri);
  48. parseURI(uri);
  49. }
  50. /**
  51. * Constructor, takes the components of the URI: protocol, server name and
  52. * port, root, and asset path
  53. */
  54. public ContentURI(String protocol, String root, String hostName, int hostPort, String assetPath) {
  55. super(toURI(protocol, root, hostName, hostPort, assetPath));
  56. this.protocol = protocol;
  57. this.hostName = hostName;
  58. this.hostPort = hostPort;
  59. this.root = root;
  60. this.assetPath = assetPath;
  61. }
  62. /**
  63. * Construct, takes the components of the URI: protocol, root name, host
  64. * name and port, and asset path. The host name and port is given as:
  65. * <host name>:<port>
  66. */
  67. public ContentURI(String protocol, String root, String hostNameAndPort, String assetPath) {
  68. super(toURI(protocol, root, hostNameAndPort, assetPath));
  69. this.protocol = protocol;
  70. this.root = root;
  71. this.assetPath = assetPath;
  72. parseHostNameAndPort(hostNameAndPort);
  73. }
  74. /**
  75. * Returns the root repository name of this URI.
  76. *
  77. * @return The root name
  78. */
  79. public String getRoot() {
  80. return root;
  81. }
  82. /**
  83. * Returns the raw relative path of the asset, without prepending any
  84. * assumed directory like "art/". It has no leading "/".
  85. */
  86. public String getAssetPath() {
  87. return assetPath;
  88. }
  89. /**
  90. * Returns the protocol of the URI
  91. */
  92. @Override
  93. public String getProtocol() {
  94. return protocol;
  95. }
  96. /**
  97. * Returns the host port, -1 if none is set.
  98. *
  99. * @return The host port
  100. */
  101. public int getHostPort() {
  102. return hostPort;
  103. }
  104. /**
  105. * Returns the host name, null if none is set.
  106. *
  107. * @return The host name
  108. */
  109. public String getHostName() {
  110. return hostName;
  111. }
  112. /**
  113. * Returns the relative resource path beneath some base repository URL
  114. */
  115. public String getRelativePath() {
  116. return getRoot() + "/" + getAssetPath();
  117. }
  118. /**
  119. * @inheritDoc()
  120. */
  121. @Override
  122. public String getRelativeCachePath() {
  123. return getProtocol() + File.separator + getRoot() + File.separator + getAssetPath();
  124. }
  125. /**
  126. * Must override toString() to not equal toExternalForm(). In this case,
  127. * toString() will return the URI with the host name and port for display
  128. * purposes.
  129. */
  130. @Override
  131. public String toString() {
  132. StringBuilder sb = new StringBuilder(protocol + "://" + root);
  133. if (hostName != null) {
  134. sb.append("@" + hostName);
  135. if (hostPort != -1) {
  136. sb.append(":" + hostPort);
  137. }
  138. }
  139. sb.append("/" + assetPath);
  140. return sb.toString();
  141. }
  142. /**
  143. * Must override toExternalForm() to not include the host name and port.
  144. * This method is used to generate a string representation to use in the
  145. * asset cache. In the case of federation, even if the host name and
  146. * port differ, they are considered the same for asset purposes.
  147. */
  148. @Override
  149. public String toExternalForm() {
  150. return protocol + "://" + root + "/" + assetPath;
  151. }
  152. /**
  153. * @inheritDoc()
  154. */
  155. public void setServerHostAndPort(String hostNameAndPort) {
  156. parseHostNameAndPort(hostNameAndPort);
  157. }
  158. /**
  159. * Returns a URL from the URI.
  160. *
  161. * @return A URL
  162. */
  163. public URL toURL() throws MalformedURLException {
  164. return new URL(this.toString());
  165. }
  166. /**
  167. * Returns the URI given the components: protocol, module name, host name,
  168. * host port, and asset path.
  169. */
  170. private static String toURI(String protocol, String root, String hostName, int hostPort, String assetPath) {
  171. StringBuilder sb = new StringBuilder(protocol + "://" + root);
  172. if (hostName != null) {
  173. sb.append("@" + hostName);
  174. if (hostPort != -1) {
  175. sb.append(":" + hostPort);
  176. }
  177. }
  178. sb.append("/" + assetPath);
  179. return sb.toString();
  180. }
  181. /**
  182. * Returns the URI given the components: protocol, root name, host name
  183. * and port, and asset path.
  184. */
  185. private static String toURI(String protocol, String root, String hostNameAndPort, String assetPath) {
  186. StringBuilder sb = new StringBuilder(protocol + "://" + root);
  187. if (hostNameAndPort != null) {
  188. sb.append("@" + hostNameAndPort);
  189. }
  190. sb.append("/" + assetPath);
  191. return sb.toString();
  192. }
  193. /**
  194. * Parse the a server name and port as <host name>:<port> into its parts
  195. */
  196. private void parseHostNameAndPort(String hostNameAndPort) {
  197. /* Sanity check: see if the argument is null */
  198. if (hostNameAndPort == null) {
  199. this.hostName = null;
  200. this.hostPort = -1;
  201. return;
  202. }
  203. /* Check if there is a colon (:), if so, parse both host and port */
  204. int colonIndex = hostNameAndPort.indexOf(":");
  205. if (colonIndex != -1) {
  206. this.hostName = hostNameAndPort.substring(0, colonIndex);
  207. try {
  208. this.hostPort = new Integer(hostNameAndPort.substring(colonIndex + 1, hostNameAndPort.length()));
  209. } catch (NumberFormatException excp) {
  210. this.hostPort = -1;
  211. }
  212. }
  213. else {
  214. this.hostName = hostNameAndPort;
  215. this.hostPort = -1;
  216. }
  217. }
  218. @Override
  219. public boolean equals(Object obj) {
  220. if (obj == null) {
  221. return false;
  222. }
  223. if (getClass() != obj.getClass()) {
  224. return false;
  225. }
  226. final ContentURI other = (ContentURI) obj;
  227. if ((this.protocol == null) ? (other.protocol != null) : !this.protocol.equals(other.protocol)) {
  228. return false;
  229. }
  230. if ((this.root == null) ? (other.root != null) : !this.root.equals(other.root)) {
  231. return false;
  232. }
  233. if ((this.assetPath == null) ? (other.assetPath != null) : !this.assetPath.equals(other.assetPath)) {
  234. return false;
  235. }
  236. return true;
  237. }
  238. @Override
  239. public int hashCode() {
  240. int hash = 7;
  241. hash = 79 * hash + (this.protocol != null ? this.protocol.hashCode() : 0);
  242. hash = 79 * hash + (this.root != null ? this.root.hashCode() : 0);
  243. hash = 79 * hash + (this.assetPath != null ? this.assetPath.hashCode() : 0);
  244. return hash;
  245. }
  246. /**
  247. * Parses the string representation of the URI into its component parts.
  248. */
  249. private void parseURI(String uri) throws URISyntaxException {
  250. /* If the uri is null, throw an Exception */
  251. if (uri == null) {
  252. throw new URISyntaxException(uri, "URI is NULL");
  253. }
  254. /* First check whether the uri contains a <protocol>:// */
  255. int protocolIndex = uri.indexOf("://");
  256. if (protocolIndex == -1 || protocolIndex == 0) {
  257. throw new URISyntaxException(uri, "URI does not contain a protocol");
  258. }
  259. protocol = uri.substring(0, protocolIndex);
  260. /* Advance the index to after the "://" */
  261. protocolIndex += 3;
  262. /*
  263. * Next parse out the root. If we find a "@" first, then there
  264. * is also a hostname. If we find a "/" next, then there is no host name
  265. */
  266. int atIndex = uri.indexOf("@", protocolIndex);
  267. int slashIndex = uri.indexOf("/", protocolIndex);
  268. if (atIndex != -1 && atIndex < slashIndex) {
  269. root = uri.substring(protocolIndex, atIndex);
  270. }
  271. else if (slashIndex != -1) {
  272. root = uri.substring(protocolIndex, slashIndex);
  273. }
  274. else {
  275. throw new URISyntaxException(uri, "Cannot find module name in URI");
  276. }
  277. /*
  278. * Next parse out the host name and port if there is one.
  279. */
  280. if (atIndex != -1 && atIndex < slashIndex) {
  281. int colonIndex = uri.indexOf(":", atIndex + 1);
  282. if (colonIndex != -1 && colonIndex < slashIndex) {
  283. hostName = uri.substring(atIndex + 1, colonIndex);
  284. try {
  285. hostPort = new Integer(uri.substring(colonIndex + 1, slashIndex));
  286. } catch (NumberFormatException excp) {
  287. hostPort = -1;
  288. throw new URISyntaxException(uri, "Invalid Host port given in URI");
  289. }
  290. }
  291. else {
  292. hostName = uri.substring(atIndex + 1, slashIndex);
  293. hostPort = -1;
  294. }
  295. }
  296. /* Finally, take everything past the slash as the asset path */
  297. assetPath = uri.substring(slashIndex + 1, uri.length());
  298. }
  299. }