PageRenderTime 42ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/galaxy-coordinator/src/main/java/com/proofpoint/galaxy/coordinator/HttpRepository.java

http://github.com/dain/galaxy-server
Java | 356 lines | 310 code | 42 blank | 4 comment | 56 complexity | 1808a04027ca6da81369121e1d61b854 MD5 | raw file
  1. package com.proofpoint.galaxy.coordinator;
  2. import com.google.common.base.Function;
  3. import com.google.common.base.Preconditions;
  4. import com.google.common.collect.ImmutableList;
  5. import com.google.common.collect.Lists;
  6. import com.google.common.io.ByteProcessor;
  7. import com.google.common.io.ByteStreams;
  8. import com.google.common.io.InputSupplier;
  9. import com.google.common.io.Resources;
  10. import com.proofpoint.galaxy.shared.Repository;
  11. import javax.annotation.Nullable;
  12. import javax.inject.Inject;
  13. import java.io.InputStream;
  14. import java.net.URI;
  15. import java.util.List;
  16. import java.util.Set;
  17. import java.util.regex.Matcher;
  18. import java.util.regex.Pattern;
  19. import static com.google.common.collect.Sets.newHashSet;
  20. import static com.proofpoint.galaxy.shared.HttpUriBuilder.uriBuilderFrom;
  21. import static com.proofpoint.galaxy.shared.MavenCoordinates.DEFAULT_BINARY_PACKAGING;
  22. import static com.proofpoint.galaxy.shared.MavenCoordinates.DEFAULT_CONFIG_PACKAGING;
  23. public class HttpRepository implements Repository
  24. {
  25. private final List<URI> baseUris;
  26. private final Pattern configShortNamePattern;
  27. private final Pattern configVersionPattern;
  28. private final Pattern binaryVersionPattern;
  29. @Inject
  30. public HttpRepository(CoordinatorConfig config)
  31. {
  32. this(
  33. Lists.transform(config.getRepositories(), new Function<String, URI>()
  34. {
  35. @Override
  36. public URI apply(@Nullable String uri)
  37. {
  38. return URI.create(uri);
  39. }
  40. }),
  41. config.getHttpShortNamePattern(),
  42. config.getHttpRepoConfigVersionPattern(),
  43. config.getHttpRepoBinaryVersionPattern());
  44. }
  45. public HttpRepository(Iterable<URI> baseUris, String configShortNamePattern, String configVersionPattern, String binaryVersionPattern)
  46. {
  47. Preconditions.checkNotNull(baseUris, "baseUris is null");
  48. this.baseUris = ImmutableList.copyOf(baseUris);
  49. if (configShortNamePattern != null) {
  50. this.configShortNamePattern = Pattern.compile(configShortNamePattern);
  51. Preconditions.checkArgument(this.configShortNamePattern.matcher("").groupCount() == 1, "configShortNamePattern must have one capturing group");
  52. }
  53. else {
  54. this.configShortNamePattern = null;
  55. }
  56. if (configVersionPattern != null) {
  57. this.configVersionPattern = Pattern.compile(configVersionPattern);
  58. Preconditions.checkArgument(this.configVersionPattern.matcher("").groupCount() >= 1, "configVersionPattern must have at least one capturing group");
  59. }
  60. else {
  61. this.configVersionPattern = null;
  62. }
  63. if (binaryVersionPattern != null) {
  64. this.binaryVersionPattern = Pattern.compile(binaryVersionPattern);
  65. Preconditions.checkArgument(this.configVersionPattern.matcher("").groupCount() >= 1, "configVersionPattern must have at least one capturing group");
  66. }
  67. else {
  68. this.binaryVersionPattern = null;
  69. }
  70. }
  71. @Override
  72. public String configShortName(String config)
  73. {
  74. if (!config.startsWith("@")) {
  75. return null;
  76. }
  77. config = config.substring(1);
  78. if (configShortNamePattern != null) {
  79. Matcher matcher = configShortNamePattern.matcher(config);
  80. if (matcher.matches()) {
  81. return matcher.group(1).replaceAll("[:%/ !$]", "_");
  82. }
  83. }
  84. return config;
  85. }
  86. @Override
  87. public String configRelativize(String config)
  88. {
  89. if (!config.startsWith("@")) {
  90. return null;
  91. }
  92. config = config.substring(1);
  93. for (URI baseUri : baseUris) {
  94. String baseUriString = baseUri.toASCIIString();
  95. if (config.startsWith(baseUriString)) {
  96. return config.substring(0, baseUriString.length());
  97. }
  98. }
  99. return null;
  100. }
  101. @Override
  102. public String configResolve(String config)
  103. {
  104. if (!config.startsWith("@")) {
  105. return null;
  106. }
  107. config = config.substring(1);
  108. URI uri = toHttpUri(config, DEFAULT_CONFIG_PACKAGING);
  109. if (uri != null) {
  110. return "@" + config;
  111. }
  112. return null;
  113. }
  114. @Override
  115. public String configUpgrade(String config, String version)
  116. {
  117. if (!config.startsWith("@") || !version.startsWith("@")) {
  118. return null;
  119. }
  120. config = config.substring(1);
  121. version = version.substring(1);
  122. String upgrade = upgrade(config, version, configVersionPattern, DEFAULT_CONFIG_PACKAGING);
  123. if (upgrade != null) {
  124. return "@" + upgrade;
  125. }
  126. return null;
  127. }
  128. @Override
  129. public boolean configEqualsIgnoreVersion(String config1, String config2)
  130. {
  131. return config1.startsWith("@") &&
  132. config2.startsWith("@") &&
  133. equalsIgnoreVersion(config1, config2, configVersionPattern);
  134. }
  135. @Override
  136. public URI configToHttpUri(String config)
  137. {
  138. if (!config.startsWith("@")) {
  139. return null;
  140. }
  141. config = config.substring(1);
  142. return toHttpUri(config, DEFAULT_CONFIG_PACKAGING);
  143. }
  144. @Override
  145. public String binaryRelativize(String binary)
  146. {
  147. for (URI baseUri : baseUris) {
  148. String baseUriString = baseUri.toASCIIString();
  149. if (binary.startsWith(baseUriString)) {
  150. return binary.substring(0, baseUriString.length());
  151. }
  152. }
  153. return null;
  154. }
  155. @Override
  156. public String binaryResolve(String binary)
  157. {
  158. URI uri = toHttpUri(binary, DEFAULT_BINARY_PACKAGING);
  159. if (uri != null) {
  160. return binary;
  161. }
  162. return null;
  163. }
  164. @Override
  165. public String binaryUpgrade(String binary, String version)
  166. {
  167. return upgrade(binary, version, binaryVersionPattern, DEFAULT_BINARY_PACKAGING);
  168. }
  169. @Override
  170. public boolean binaryEqualsIgnoreVersion(String binary1, String binary2)
  171. {
  172. return equalsIgnoreVersion(binary1, binary2, binaryVersionPattern);
  173. }
  174. @Override
  175. public URI binaryToHttpUri(String binary)
  176. {
  177. return toHttpUri(binary, DEFAULT_BINARY_PACKAGING);
  178. }
  179. private String upgrade(String path, String version, Pattern versionPattern, String defaultPackaging)
  180. {
  181. // try to replace version in existing config
  182. if (versionPattern != null) {
  183. String newConfig = upgradePath(path, version, versionPattern);
  184. if (newConfig != null && toHttpUri(newConfig, defaultPackaging) != null) {
  185. return newConfig;
  186. }
  187. }
  188. // version pattern did not match, so check if new version is an absolute uri
  189. URI uri = toHttpUri(version, defaultPackaging);
  190. if (uri != null) {
  191. return version;
  192. }
  193. return null;
  194. }
  195. private boolean equalsIgnoreVersion(String path1, String path2, Pattern versionPattern)
  196. {
  197. if (versionPattern == null) {
  198. return false;
  199. }
  200. String path1NoVersion;
  201. Matcher matcher1 = versionPattern.matcher(path1);
  202. if (!matcher1.find()) {
  203. return false;
  204. }
  205. path1NoVersion = matcher1.replaceAll("");
  206. String path2NoVersion;
  207. Matcher matcher2 = versionPattern.matcher(path2);
  208. if (!matcher2.find()) {
  209. return false;
  210. }
  211. path2NoVersion = matcher2.replaceAll("");
  212. return path1NoVersion.equals(path2NoVersion);
  213. }
  214. private URI toHttpUri(String path, String defaultExtension)
  215. {
  216. try {
  217. URI uri = URI.create(path);
  218. if (uri.isAbsolute()) {
  219. if (isValidLocation(uri)) {
  220. return uri;
  221. }
  222. else {
  223. uri = uri.resolve("." + defaultExtension);
  224. if (isValidLocation(uri)) {
  225. return uri;
  226. }
  227. else {
  228. return null;
  229. }
  230. }
  231. }
  232. }
  233. catch (Exception ignored) {
  234. }
  235. Set<URI> uris = newHashSet();
  236. for (URI baseUri : baseUris) {
  237. try {
  238. URI uri = uriBuilderFrom(baseUri).appendPath(path).build();
  239. if (isValidLocation(uri)) {
  240. uris.add(uri);
  241. }
  242. else {
  243. uri = uri.resolve("." + defaultExtension);
  244. if (isValidLocation(uri)) {
  245. uris.add(uri);
  246. }
  247. }
  248. }
  249. catch (Exception ignored) {
  250. }
  251. }
  252. if (uris.size() > 1) {
  253. throw new RuntimeException("Ambiguous spec " + path + " matched " + uris);
  254. }
  255. if (uris.isEmpty()) {
  256. return null;
  257. }
  258. return uris.iterator().next();
  259. }
  260. private boolean isValidLocation(URI uri)
  261. {
  262. try {
  263. InputSupplier<InputStream> inputSupplier = Resources.newInputStreamSupplier(uri.toURL());
  264. ByteStreams.readBytes(inputSupplier, new ByteProcessor<Void>()
  265. {
  266. private int count;
  267. public boolean processBytes(byte[] buffer, int offset, int length)
  268. {
  269. count += length;
  270. // make sure we got at least 10 bytes
  271. return count < 10;
  272. }
  273. public Void getResult()
  274. {
  275. return null;
  276. }
  277. });
  278. return true;
  279. }
  280. catch (Exception ignored) {
  281. }
  282. return false;
  283. }
  284. public static String upgradePath(String spec, String version, Pattern versionPattern)
  285. {
  286. Matcher matcher = versionPattern.matcher(spec);
  287. StringBuilder out = new StringBuilder();
  288. int end = 0;
  289. while (matcher.find()) {
  290. for (int group = 0; group < matcher.groupCount(); group++) {
  291. out.append(spec.substring(end, matcher.start(group + 1))).append(version);
  292. end = matcher.end(group + 1);
  293. }
  294. }
  295. // no matches
  296. if (end == 0) {
  297. return null;
  298. }
  299. out.append(spec.substring(end));
  300. return out.toString();
  301. }
  302. @Override
  303. public String toString()
  304. {
  305. final StringBuilder sb = new StringBuilder();
  306. sb.append("HttpRepository");
  307. sb.append("{baseUris=").append(baseUris);
  308. sb.append(", configShortNamePattern=").append(configShortNamePattern);
  309. sb.append(", configVersionPattern=").append(configVersionPattern);
  310. sb.append(", binaryVersionPattern=").append(binaryVersionPattern);
  311. sb.append('}');
  312. return sb.toString();
  313. }
  314. }