{"action":"created","comment":{"url":"https://api.github.com/repos/OpenGamma/OG-Platform/pulls/comments/29653670","id":29653670,"diff_hunk":"@@ -0,0 +1,116 @@\n+/**\n+ * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies\n+ *\n+ * Please see distribution for license.\n+ */\n+package com.opengamma.engine.marketdata.spec;\n+\n+import org.threeten.bp.LocalDate;\n+import org.threeten.bp.format.DateTimeParseException;\n+\n+import com.opengamma.id.UniqueId;\n+\n+/**\n+ * Parses a string to produce a {@link MarketDataSpecification}.\n+ */\n+public class MarketDataSpecificationParser {\n+\n+  private static final String LIVE = \"live\";\n+  private static final String SNAPSHOT = \"snapshot\";\n+  private static final String FIXED_HISTORICAL = \"fixedhistorical\";\n+  private static final String LATEST_HISTORICAL = \"latesthistorical\";\n+\n+  /**\n+   * Parses a string to produce a {@link MarketDataSpecification}. See the output of {@link #getUsageMessage()}\n+   * for examples.\n+   * @param specStr String representation of a {@link MarketDataSpecification}\n+   * @return A {@link MarketDataSpecification} instance built from the string\n+   * @throws IllegalArgumentException If the string can't be parsed\n+   */\n+  public static MarketDataSpecification parse(String specStr) {\n+    if (specStr.startsWith(LIVE)) {\n+      return createLiveSpec(removePrefix(specStr, LIVE));\n+    } else {\n+      if (specStr.startsWith(SNAPSHOT)) {\n+        return createSnapshotSpec(removePrefix(specStr, SNAPSHOT));\n+      } else if (specStr.startsWith(FIXED_HISTORICAL)) {\n+        return createFixedHistoricalSpec(removePrefix(specStr, FIXED_HISTORICAL));\n+      } else if (specStr.startsWith(LATEST_HISTORICAL)) {\n+        return createLatestHistoricalSpec(removePrefix(specStr, LATEST_HISTORICAL));\n+      } else {\n+        throw new IllegalArgumentException(\"Market data must be one of 'live', 'fixedhistorical', 'latesthistorical'\" +\n+                                               \" or 'snapshot'\");\n+      }\n+    }\n+  }\n+\n+  private static MarketDataSpecification createLatestHistoricalSpec(String specStr) {\n+    if (specStr.isEmpty()) {\n+      return new LatestHistoricalMarketDataSpecification();\n+    }\n+    if (!specStr.startsWith(\":\")) {\n+      throw new IllegalArgumentException(specStr + \" doesn't match 'latesthistorical[:time series rating]'\");\n+    }\n+    String timeSeriesRating = specStr.substring(1).trim();\n+    if (timeSeriesRating.isEmpty()) {\n+      throw new IllegalArgumentException(specStr + \" doesn't match 'latesthistorical[:time series rating]'\");\n+    }\n+    return new LatestHistoricalMarketDataSpecification(timeSeriesRating);\n+  }\n+\n+  private static MarketDataSpecification createFixedHistoricalSpec(String specStr) {\n+    if (!specStr.startsWith(\":\")) {\n+      throw new IllegalArgumentException(specStr + \" doesn't match 'fixedhistorical:timestamp[,time series rating]'\");\n+    }\n+    String[] strings = specStr.split(\",\");\n+    LocalDate date;\n+    try {\n+      date = LocalDate.parse(strings[0].substring(1).trim());\n+    } catch (DateTimeParseException e) {\n+      throw new IllegalArgumentException(\"Unknown date format\", e);\n+    }\n+    if (strings.length > 1) {\n+      String timeSeriesRating = strings[1].trim();\n+      if (timeSeriesRating.isEmpty()) {\n+        throw new IllegalArgumentException(specStr + \" doesn't match 'fixedhistorical:timestamp[,time series rating]'\");\n+      }\n+      return new FixedHistoricalMarketDataSpecification(timeSeriesRating, date);\n+    } else {\n+      return new FixedHistoricalMarketDataSpecification(date);\n+    }\n+  }\n+\n+  // TODO accept 'snapshot name/timestamp'? friendlier but requires looking up data from the server\n+  private static MarketDataSpecification createSnapshotSpec(String specStr) {\n+    if (!specStr.startsWith(\":\")) {\n+      throw new IllegalArgumentException(specStr + \" doesn't match 'snapshot:snapshot ID'\");\n+    }\n+    String id = specStr.substring(1).trim();\n+    return UserMarketDataSpecification.of(UniqueId.parse(id));\n+  }\n+\n+  private static MarketDataSpecification createLiveSpec(String specStr) {\n+    if (!specStr.startsWith(\":\")) {\n+      throw new IllegalArgumentException(specStr + \" doesn't match 'live:source name'\");\n+    }\n+    String sourceName = specStr.substring(1).trim();\n+    if (sourceName.isEmpty()) {\n+      throw new IllegalArgumentException(specStr + \" doesn't match 'live:source name'\");\n+    }\n+    return LiveMarketDataSpecification.of(sourceName);\n+  }\n+\n+  private static String removePrefix(String specStr, String prefix) {\n+    return specStr.substring(prefix.length(), specStr.length());\n+  }\n+\n+  public static String getUsageMessage() {","path":"projects/OG-Engine/src/main/java/com/opengamma/engine/marketdata/spec/MarketDataSpecificationParser.java","position":107,"original_position":107,"commit_id":"545b7255e7b733a7d03629729cfd59dd628b60a8","original_commit_id":"545b7255e7b733a7d03629729cfd59dd628b60a8","user":{"login":"cjkent","id":98477,"avatar_url":"https://avatars.githubusercontent.com/u/98477?v=3","gravatar_id":"","url":"https://api.github.com/users/cjkent","html_url":"https://github.com/cjkent","followers_url":"https://api.github.com/users/cjkent/followers","following_url":"https://api.github.com/users/cjkent/following{/other_user}","gists_url":"https://api.github.com/users/cjkent/gists{/gist_id}","starred_url":"https://api.github.com/users/cjkent/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cjkent/subscriptions","organizations_url":"https://api.github.com/users/cjkent/orgs","repos_url":"https://api.github.com/users/cjkent/repos","events_url":"https://api.github.com/users/cjkent/events{/privacy}","received_events_url":"https://api.github.com/users/cjkent/received_events","type":"User","site_admin":false},"body":"This should probably be private","created_at":"2015-05-05T09:20:35Z","updated_at":"2015-05-05T09:20:35Z","html_url":"https://github.com/OpenGamma/OG-Platform/pull/345#discussion_r29653670","pull_request_url":"https://api.github.com/repos/OpenGamma/OG-Platform/pulls/345","_links":{"self":{"href":"https://api.github.com/repos/OpenGamma/OG-Platform/pulls/comments/29653670"},"html":{"href":"https://github.com/OpenGamma/OG-Platform/pull/345#discussion_r29653670"},"pull_request":{"href":"https://api.github.com/repos/OpenGamma/OG-Platform/pulls/345"}}},"pull_request":{"url":"https://api.github.com/repos/OpenGamma/OG-Platform/pulls/345","id":34706888,"html_url":"https://github.com/OpenGamma/OG-Platform/pull/345","diff_url":"https://github.com/OpenGamma/OG-Platform/pull/345.diff","patch_url":"https://github.com/OpenGamma/OG-Platform/pull/345.patch","issue_url":"https://api.github.com/repos/OpenGamma/OG-Platform/issues/345","number":345,"state":"open","locked":false,"title":"PLT-887 expose market data spec parser as utility","user":{"login":"pondmouse","id":179967,"avatar_url":"https://avatars.githubusercontent.com/u/179967?v=3","gravatar_id":"","url":"https://api.github.com/users/pondmouse","html_url":"https://github.com/pondmouse","followers_url":"https://api.github.com/users/pondmouse/followers","following_url":"https://api.github.com/users/pondmouse/following{/other_user}","gists_url":"https://api.github.com/users/pondmouse/gists{/gist_id}","starred_url":"https://api.github.com/users/pondmouse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pondmouse/subscriptions","organizations_url":"https://api.github.com/users/pondmouse/orgs","repos_url":"https://api.github.com/users/pondmouse/repos","events_url":"https://api.github.com/users/pondmouse/events{/privacy}","received_events_url":"https://api.github.com/users/pondmouse/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-05-05T09:13:03Z","updated_at":"2015-05-05T09:20:35Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f41f280599c7cd1758f09b9579ed9357a8f6e770","assignee":{"login":"cjkent","id":98477,"avatar_url":"https://avatars.githubusercontent.com/u/98477?v=3","gravatar_id":"","url":"https://api.github.com/users/cjkent","html_url":"https://github.com/cjkent","followers_url":"https://api.github.com/users/cjkent/followers","following_url":"https://api.github.com/users/cjkent/following{/other_user}","gists_url":"https://api.github.com/users/cjkent/gists{/gist_id}","starred_url":"https://api.github.com/users/cjkent/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cjkent/subscriptions","organizations_url":"https://api.github.com/users/cjkent/orgs","repos_url":"https://api.github.com/users/cjkent/repos","events_url":"https://api.github.com/users/cjkent/events{/privacy}","received_events_url":"https://api.github.com/users/cjkent/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/OpenGamma/OG-Platform/pulls/345/commits","review_comments_url":"https://api.github.com/repos/OpenGamma/OG-Platform/pulls/345/comments","review_comment_url":"https://api.github.com/repos/OpenGamma/OG-Platform/pulls/comments{/number}","comments_url":"https://api.github.com/repos/OpenGamma/OG-Platform/issues/345/comments","statuses_url":"https://api.github.com/repos/OpenGamma/OG-Platform/statuses/545b7255e7b733a7d03629729cfd59dd628b60a8","head":{"label":"OpenGamma:topic/PLT-887","ref":"topic/PLT-887","sha":"545b7255e7b733a7d03629729cfd59dd628b60a8","user":{"login":"OpenGamma","id":120064,"avatar_url":"https://avatars.githubusercontent.com/u/120064?v=3","gravatar_id":"","url":"https://api.github.com/users/OpenGamma","html_url":"https://github.com/OpenGamma","followers_url":"https://api.github.com/users/OpenGamma/followers","following_url":"https://api.github.com/users/OpenGamma/following{/other_user}","gists_url":"https://api.github.com/users/OpenGamma/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenGamma/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenGamma/subscriptions","organizations_url":"https://api.github.com/users/OpenGamma/orgs","repos_url":"https://api.github.com/users/OpenGamma/repos","events_url":"https://api.github.com/users/OpenGamma/events{/privacy}","received_events_url":"https://api.github.com/users/OpenGamma/received_events","type":"Organization","site_admin":false},"repo":{"id":933698,"name":"OG-Platform","full_name":"OpenGamma/OG-Platform","owner":{"login":"OpenGamma","id":120064,"avatar_url":"https://avatars.githubusercontent.com/u/120064?v=3","gravatar_id":"","url":"https://api.github.com/users/OpenGamma","html_url":"https://github.com/OpenGamma","followers_url":"https://api.github.com/users/OpenGamma/followers","following_url":"https://api.github.com/users/OpenGamma/following{/other_user}","gists_url":"https://api.github.com/users/OpenGamma/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenGamma/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenGamma/subscriptions","organizations_url":"https://api.github.com/users/OpenGamma/orgs","repos_url":"https://api.github.com/users/OpenGamma/repos","events_url":"https://api.github.com/users/OpenGamma/events{/privacy}","received_events_url":"https://api.github.com/users/OpenGamma/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/OpenGamma/OG-Platform","description":"The core OpenGamma Platform wrapper project","fork":false,"url":"https://api.github.com/repos/OpenGamma/OG-Platform","forks_url":"https://api.github.com/repos/OpenGamma/OG-Platform/forks","keys_url":"https://api.github.com/repos/OpenGamma/OG-Platform/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenGamma/OG-Platform/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenGamma/OG-Platform/teams","hooks_url":"https://api.github.com/repos/OpenGamma/OG-Platform/hooks","issue_events_url":"https://api.github.com/repos/OpenGamma/OG-Platform/issues/events{/number}","events_url":"https://api.github.com/repos/OpenGamma/OG-Platform/events","assignees_url":"https://api.github.com/repos/OpenGamma/OG-Platform/assignees{/user}","branches_url":"https://api.github.com/repos/OpenGamma/OG-Platform/branches{/branch}","tags_url":"https://api.github.com/repos/OpenGamma/OG-Platform/tags","blobs_url":"https://api.github.com/repos/OpenGamma/OG-Platform/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenGamma/OG-Platform/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenGamma/OG-Platform/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenGamma/OG-Platform/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenGamma/OG-Platform/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenGamma/OG-Platform/languages","stargazers_url":"https://api.github.com/repos/OpenGamma/OG-Platform/stargazers","contributors_url":"https://api.github.com/repos/OpenGamma/OG-Platform/contributors","subscribers_url":"https://api.github.com/repos/OpenGamma/OG-Platform/subscribers","subscription_url":"https://api.github.com/repos/OpenGamma/OG-Platform/subscription","commits_url":"https://api.github.com/repos/OpenGamma/OG-Platform/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenGamma/OG-Platform/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenGamma/OG-Platform/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenGamma/OG-Platform/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenGamma/OG-Platform/contents/{+path}","compare_url":"https://api.github.com/repos/OpenGamma/OG-Platform/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenGamma/OG-Platform/merges","archive_url":"https://api.github.com/repos/OpenGamma/OG-Platform/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenGamma/OG-Platform/downloads","issues_url":"https://api.github.com/repos/OpenGamma/OG-Platform/issues{/number}","pulls_url":"https://api.github.com/repos/OpenGamma/OG-Platform/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenGamma/OG-Platform/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenGamma/OG-Platform/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenGamma/OG-Platform/labels{/name}","releases_url":"https://api.github.com/repos/OpenGamma/OG-Platform/releases{/id}","created_at":"2010-09-23T15:47:12Z","updated_at":"2015-05-01T14:11:09Z","pushed_at":"2015-05-05T09:13:03Z","git_url":"git://github.com/OpenGamma/OG-Platform.git","ssh_url":"git@github.com:OpenGamma/OG-Platform.git","clone_url":"https://github.com/OpenGamma/OG-Platform.git","svn_url":"https://github.com/OpenGamma/OG-Platform","homepage":"http://developers.opengamma.com/","size":900289,"stargazers_count":207,"watchers_count":207,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":130,"mirror_url":null,"open_issues_count":13,"forks":130,"open_issues":13,"watchers":207,"default_branch":"master"}},"base":{"label":"OpenGamma:develop","ref":"develop","sha":"3d4bab83576570641e66e3be28fff9610c392a6c","user":{"login":"OpenGamma","id":120064,"avatar_url":"https://avatars.githubusercontent.com/u/120064?v=3","gravatar_id":"","url":"https://api.github.com/users/OpenGamma","html_url":"https://github.com/OpenGamma","followers_url":"https://api.github.com/users/OpenGamma/followers","following_url":"https://api.github.com/users/OpenGamma/following{/other_user}","gists_url":"https://api.github.com/users/OpenGamma/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenGamma/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenGamma/subscriptions","organizations_url":"https://api.github.com/users/OpenGamma/orgs","repos_url":"https://api.github.com/users/OpenGamma/repos","events_url":"https://api.github.com/users/OpenGamma/events{/privacy}","received_events_url":"https://api.github.com/users/OpenGamma/received_events","type":"Organization","site_admin":false},"repo":{"id":933698,"name":"OG-Platform","full_name":"OpenGamma/OG-Platform","owner":{"login":"OpenGamma","id":120064,"avatar_url":"https://avatars.githubusercontent.com/u/120064?v=3","gravatar_id":"","url":"https://api.github.com/users/OpenGamma","html_url":"https://github.com/OpenGamma","followers_url":"https://api.github.com/users/OpenGamma/followers","following_url":"https://api.github.com/users/OpenGamma/following{/other_user}","gists_url":"https://api.github.com/users/OpenGamma/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenGamma/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenGamma/subscriptions","organizations_url":"https://api.github.com/users/OpenGamma/orgs","repos_url":"https://api.github.com/users/OpenGamma/repos","events_url":"https://api.github.com/users/OpenGamma/events{/privacy}","received_events_url":"https://api.github.com/users/OpenGamma/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/OpenGamma/OG-Platform","description":"The core OpenGamma Platform wrapper project","fork":false,"url":"https://api.github.com/repos/OpenGamma/OG-Platform","forks_url":"https://api.github.com/repos/OpenGamma/OG-Platform/forks","keys_url":"https://api.github.com/repos/OpenGamma/OG-Platform/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenGamma/OG-Platform/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenGamma/OG-Platform/teams","hooks_url":"https://api.github.com/repos/OpenGamma/OG-Platform/hooks","issue_events_url":"https://api.github.com/repos/OpenGamma/OG-Platform/issues/events{/number}","events_url":"https://api.github.com/repos/OpenGamma/OG-Platform/events","assignees_url":"https://api.github.com/repos/OpenGamma/OG-Platform/assignees{/user}","branches_url":"https://api.github.com/repos/OpenGamma/OG-Platform/branches{/branch}","tags_url":"https://api.github.com/repos/OpenGamma/OG-Platform/tags","blobs_url":"https://api.github.com/repos/OpenGamma/OG-Platform/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenGamma/OG-Platform/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenGamma/OG-Platform/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenGamma/OG-Platform/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenGamma/OG-Platform/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenGamma/OG-Platform/languages","stargazers_url":"https://api.github.com/repos/OpenGamma/OG-Platform/stargazers","contributors_url":"https://api.github.com/repos/OpenGamma/OG-Platform/contributors","subscribers_url":"https://api.github.com/repos/OpenGamma/OG-Platform/subscribers","subscription_url":"https://api.github.com/repos/OpenGamma/OG-Platform/subscription","commits_url":"https://api.github.com/repos/OpenGamma/OG-Platform/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenGamma/OG-Platform/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenGamma/OG-Platform/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenGamma/OG-Platform/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenGamma/OG-Platform/contents/{+path}","compare_url":"https://api.github.com/repos/OpenGamma/OG-Platform/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenGamma/OG-Platform/merges","archive_url":"https://api.github.com/repos/OpenGamma/OG-Platform/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenGamma/OG-Platform/downloads","issues_url":"https://api.github.com/repos/OpenGamma/OG-Platform/issues{/number}","pulls_url":"https://api.github.com/repos/OpenGamma/OG-Platform/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenGamma/OG-Platform/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenGamma/OG-Platform/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenGamma/OG-Platform/labels{/name}","releases_url":"https://api.github.com/repos/OpenGamma/OG-Platform/releases{/id}","created_at":"2010-09-23T15:47:12Z","updated_at":"2015-05-01T14:11:09Z","pushed_at":"2015-05-05T09:13:03Z","git_url":"git://github.com/OpenGamma/OG-Platform.git","ssh_url":"git@github.com:OpenGamma/OG-Platform.git","clone_url":"https://github.com/OpenGamma/OG-Platform.git","svn_url":"https://github.com/OpenGamma/OG-Platform","homepage":"http://developers.opengamma.com/","size":900289,"stargazers_count":207,"watchers_count":207,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":130,"mirror_url":null,"open_issues_count":13,"forks":130,"open_issues":13,"watchers":207,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/OpenGamma/OG-Platform/pulls/345"},"html":{"href":"https://github.com/OpenGamma/OG-Platform/pull/345"},"issue":{"href":"https://api.github.com/repos/OpenGamma/OG-Platform/issues/345"},"comments":{"href":"https://api.github.com/repos/OpenGamma/OG-Platform/issues/345/comments"},"review_comments":{"href":"https://api.github.com/repos/OpenGamma/OG-Platform/pulls/345/comments"},"review_comment":{"href":"https://api.github.com/repos/OpenGamma/OG-Platform/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/OpenGamma/OG-Platform/pulls/345/commits"},"statuses":{"href":"https://api.github.com/repos/OpenGamma/OG-Platform/statuses/545b7255e7b733a7d03629729cfd59dd628b60a8"}}}}