{"action":"created","comment":{"url":"https://api.github.com/repos/Qabel/qabel-desktop/pulls/comments/62626948","id":62626948,"diff_hunk":"@@ -3,11 +3,13 @@\n import de.qabel.desktop.config.BoxSyncConfig;\n import de.qabel.desktop.daemon.sync.event.ChangeEvent;\n import de.qabel.desktop.daemon.sync.event.WatchEvent;\n+import de.qabel.desktop.nio.boxfs.BoxFileSystem;\n+import de.qabel.desktop.nio.boxfs.BoxPath;\n import de.qabel.desktop.storage.BoxVolume;\n \n import java.nio.file.Path;\n \n-public abstract class AbstractBoxSyncBasedTransaction extends AbstractTransaction {\n+public abstract class AbstractBoxSyncBasedTransaction<S extends Path, D extends Path> extends AbstractTransaction<S, D> {","path":"src/main/java/de/qabel/desktop/daemon/management/AbstractBoxSyncBasedTransaction.java","position":11,"original_position":11,"commit_id":"3573d81224927110ee8b14cdd660bbecdc16c8bc","original_commit_id":"3573d81224927110ee8b14cdd660bbecdc16c8bc","user":{"login":"julianseeger","id":3258762,"avatar_url":"https://avatars.githubusercontent.com/u/3258762?v=3","gravatar_id":"","url":"https://api.github.com/users/julianseeger","html_url":"https://github.com/julianseeger","followers_url":"https://api.github.com/users/julianseeger/followers","following_url":"https://api.github.com/users/julianseeger/following{/other_user}","gists_url":"https://api.github.com/users/julianseeger/gists{/gist_id}","starred_url":"https://api.github.com/users/julianseeger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/julianseeger/subscriptions","organizations_url":"https://api.github.com/users/julianseeger/orgs","repos_url":"https://api.github.com/users/julianseeger/repos","events_url":"https://api.github.com/users/julianseeger/events{/privacy}","received_events_url":"https://api.github.com/users/julianseeger/received_events","type":"User","site_admin":false},"body":"That's why they are generics.\r\nS (source) and D (destination) varies between Uploads and Downloads.\r\nUploads transfer from BoxPath to (local) Path and Downloads transfer from (local) Path to BoxPath. Kind of confusing but at least it is hidden for users of the Up- and Downloads.\r\n```JAVA\r\npublic interface Upload extends Transaction<Path, BoxPath>\r\n```","created_at":"2016-05-10T07:58:25Z","updated_at":"2016-05-10T07:58:25Z","html_url":"https://github.com/Qabel/qabel-desktop/pull/355#discussion_r62626948","pull_request_url":"https://api.github.com/repos/Qabel/qabel-desktop/pulls/355","_links":{"self":{"href":"https://api.github.com/repos/Qabel/qabel-desktop/pulls/comments/62626948"},"html":{"href":"https://github.com/Qabel/qabel-desktop/pull/355#discussion_r62626948"},"pull_request":{"href":"https://api.github.com/repos/Qabel/qabel-desktop/pulls/355"}}},"pull_request":{"url":"https://api.github.com/repos/Qabel/qabel-desktop/pulls/355","id":68561244,"html_url":"https://github.com/Qabel/qabel-desktop/pull/355","diff_url":"https://github.com/Qabel/qabel-desktop/pull/355.diff","patch_url":"https://github.com/Qabel/qabel-desktop/pull/355.patch","issue_url":"https://api.github.com/repos/Qabel/qabel-desktop/issues/355","number":355,"state":"open","locked":false,"title":"#347 persistent SyncIndex","user":{"login":"julianseeger","id":3258762,"avatar_url":"https://avatars.githubusercontent.com/u/3258762?v=3","gravatar_id":"","url":"https://api.github.com/users/julianseeger","html_url":"https://github.com/julianseeger","followers_url":"https://api.github.com/users/julianseeger/followers","following_url":"https://api.github.com/users/julianseeger/following{/other_user}","gists_url":"https://api.github.com/users/julianseeger/gists{/gist_id}","starred_url":"https://api.github.com/users/julianseeger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/julianseeger/subscriptions","organizations_url":"https://api.github.com/users/julianseeger/orgs","repos_url":"https://api.github.com/users/julianseeger/repos","events_url":"https://api.github.com/users/julianseeger/events{/privacy}","received_events_url":"https://api.github.com/users/julianseeger/received_events","type":"User","site_admin":false},"body":"resolves #347 \r\nit seems to resolve #310 \r\n\r\nWhile implementing the persistence of the syncIndex, I also modeled the \"new\" sync index that consists of 3 states per path: known local state, known remote state and known synced state. The known synced state is persisted and represents the last state that has been successfully synced (up- or downloaded). The local and remote states are unknown at application start (have to be looked up) and get updated on each filesystem notification. This change is a preparation for the discussed conflict handling and enables the system to detect conflicts (local state != synced state != remote state) and validate which side was changed (local state == synced state != remote state => download new remote change; local state != synced state == remote state => upload new local change). I just don't wanted to implement this twice.\r\n\r\nThe Path => BoxPath change is currently to prevent misuse of the Paths, because they are not fully compatible and need to be normalized differently. BoxPath should be used for everything concerning the RemoteFS / BoxFS and the Path (which defaults to an OS specific implementation) for everything concerning the local FS.","created_at":"2016-05-02T13:40:55Z","updated_at":"2016-05-10T07:58:25Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f9a6f90d5ab5467f17e6f20eb946b2d3b08a8f5f","assignee":{"login":"audax","id":858339,"avatar_url":"https://avatars.githubusercontent.com/u/858339?v=3","gravatar_id":"","url":"https://api.github.com/users/audax","html_url":"https://github.com/audax","followers_url":"https://api.github.com/users/audax/followers","following_url":"https://api.github.com/users/audax/following{/other_user}","gists_url":"https://api.github.com/users/audax/gists{/gist_id}","starred_url":"https://api.github.com/users/audax/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/audax/subscriptions","organizations_url":"https://api.github.com/users/audax/orgs","repos_url":"https://api.github.com/users/audax/repos","events_url":"https://api.github.com/users/audax/events{/privacy}","received_events_url":"https://api.github.com/users/audax/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/Qabel/qabel-desktop/pulls/355/commits","review_comments_url":"https://api.github.com/repos/Qabel/qabel-desktop/pulls/355/comments","review_comment_url":"https://api.github.com/repos/Qabel/qabel-desktop/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Qabel/qabel-desktop/issues/355/comments","statuses_url":"https://api.github.com/repos/Qabel/qabel-desktop/statuses/3573d81224927110ee8b14cdd660bbecdc16c8bc","head":{"label":"julianseeger:syncIndex","ref":"syncIndex","sha":"3573d81224927110ee8b14cdd660bbecdc16c8bc","user":{"login":"julianseeger","id":3258762,"avatar_url":"https://avatars.githubusercontent.com/u/3258762?v=3","gravatar_id":"","url":"https://api.github.com/users/julianseeger","html_url":"https://github.com/julianseeger","followers_url":"https://api.github.com/users/julianseeger/followers","following_url":"https://api.github.com/users/julianseeger/following{/other_user}","gists_url":"https://api.github.com/users/julianseeger/gists{/gist_id}","starred_url":"https://api.github.com/users/julianseeger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/julianseeger/subscriptions","organizations_url":"https://api.github.com/users/julianseeger/orgs","repos_url":"https://api.github.com/users/julianseeger/repos","events_url":"https://api.github.com/users/julianseeger/events{/privacy}","received_events_url":"https://api.github.com/users/julianseeger/received_events","type":"User","site_admin":false},"repo":{"id":49275847,"name":"qabel-desktop","full_name":"julianseeger/qabel-desktop","owner":{"login":"julianseeger","id":3258762,"avatar_url":"https://avatars.githubusercontent.com/u/3258762?v=3","gravatar_id":"","url":"https://api.github.com/users/julianseeger","html_url":"https://github.com/julianseeger","followers_url":"https://api.github.com/users/julianseeger/followers","following_url":"https://api.github.com/users/julianseeger/following{/other_user}","gists_url":"https://api.github.com/users/julianseeger/gists{/gist_id}","starred_url":"https://api.github.com/users/julianseeger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/julianseeger/subscriptions","organizations_url":"https://api.github.com/users/julianseeger/orgs","repos_url":"https://api.github.com/users/julianseeger/repos","events_url":"https://api.github.com/users/julianseeger/events{/privacy}","received_events_url":"https://api.github.com/users/julianseeger/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/julianseeger/qabel-desktop","description":"Desktop Frontend of Qabel","fork":true,"url":"https://api.github.com/repos/julianseeger/qabel-desktop","forks_url":"https://api.github.com/repos/julianseeger/qabel-desktop/forks","keys_url":"https://api.github.com/repos/julianseeger/qabel-desktop/keys{/key_id}","collaborators_url":"https://api.github.com/repos/julianseeger/qabel-desktop/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/julianseeger/qabel-desktop/teams","hooks_url":"https://api.github.com/repos/julianseeger/qabel-desktop/hooks","issue_events_url":"https://api.github.com/repos/julianseeger/qabel-desktop/issues/events{/number}","events_url":"https://api.github.com/repos/julianseeger/qabel-desktop/events","assignees_url":"https://api.github.com/repos/julianseeger/qabel-desktop/assignees{/user}","branches_url":"https://api.github.com/repos/julianseeger/qabel-desktop/branches{/branch}","tags_url":"https://api.github.com/repos/julianseeger/qabel-desktop/tags","blobs_url":"https://api.github.com/repos/julianseeger/qabel-desktop/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/julianseeger/qabel-desktop/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/julianseeger/qabel-desktop/git/refs{/sha}","trees_url":"https://api.github.com/repos/julianseeger/qabel-desktop/git/trees{/sha}","statuses_url":"https://api.github.com/repos/julianseeger/qabel-desktop/statuses/{sha}","languages_url":"https://api.github.com/repos/julianseeger/qabel-desktop/languages","stargazers_url":"https://api.github.com/repos/julianseeger/qabel-desktop/stargazers","contributors_url":"https://api.github.com/repos/julianseeger/qabel-desktop/contributors","subscribers_url":"https://api.github.com/repos/julianseeger/qabel-desktop/subscribers","subscription_url":"https://api.github.com/repos/julianseeger/qabel-desktop/subscription","commits_url":"https://api.github.com/repos/julianseeger/qabel-desktop/commits{/sha}","git_commits_url":"https://api.github.com/repos/julianseeger/qabel-desktop/git/commits{/sha}","comments_url":"https://api.github.com/repos/julianseeger/qabel-desktop/comments{/number}","issue_comment_url":"https://api.github.com/repos/julianseeger/qabel-desktop/issues/comments{/number}","contents_url":"https://api.github.com/repos/julianseeger/qabel-desktop/contents/{+path}","compare_url":"https://api.github.com/repos/julianseeger/qabel-desktop/compare/{base}...{head}","merges_url":"https://api.github.com/repos/julianseeger/qabel-desktop/merges","archive_url":"https://api.github.com/repos/julianseeger/qabel-desktop/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/julianseeger/qabel-desktop/downloads","issues_url":"https://api.github.com/repos/julianseeger/qabel-desktop/issues{/number}","pulls_url":"https://api.github.com/repos/julianseeger/qabel-desktop/pulls{/number}","milestones_url":"https://api.github.com/repos/julianseeger/qabel-desktop/milestones{/number}","notifications_url":"https://api.github.com/repos/julianseeger/qabel-desktop/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/julianseeger/qabel-desktop/labels{/name}","releases_url":"https://api.github.com/repos/julianseeger/qabel-desktop/releases{/id}","deployments_url":"https://api.github.com/repos/julianseeger/qabel-desktop/deployments","created_at":"2016-01-08T14:15:51Z","updated_at":"2016-01-27T09:21:26Z","pushed_at":"2016-05-10T07:08:19Z","git_url":"git://github.com/julianseeger/qabel-desktop.git","ssh_url":"git@github.com:julianseeger/qabel-desktop.git","clone_url":"https://github.com/julianseeger/qabel-desktop.git","svn_url":"https://github.com/julianseeger/qabel-desktop","homepage":null,"size":4055,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"Qabel:master","ref":"master","sha":"b7aa856cb85e2126720f80381e6409a88e804f14","user":{"login":"Qabel","id":7711470,"avatar_url":"https://avatars.githubusercontent.com/u/7711470?v=3","gravatar_id":"","url":"https://api.github.com/users/Qabel","html_url":"https://github.com/Qabel","followers_url":"https://api.github.com/users/Qabel/followers","following_url":"https://api.github.com/users/Qabel/following{/other_user}","gists_url":"https://api.github.com/users/Qabel/gists{/gist_id}","starred_url":"https://api.github.com/users/Qabel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Qabel/subscriptions","organizations_url":"https://api.github.com/users/Qabel/orgs","repos_url":"https://api.github.com/users/Qabel/repos","events_url":"https://api.github.com/users/Qabel/events{/privacy}","received_events_url":"https://api.github.com/users/Qabel/received_events","type":"Organization","site_admin":false},"repo":{"id":25461792,"name":"qabel-desktop","full_name":"Qabel/qabel-desktop","owner":{"login":"Qabel","id":7711470,"avatar_url":"https://avatars.githubusercontent.com/u/7711470?v=3","gravatar_id":"","url":"https://api.github.com/users/Qabel","html_url":"https://github.com/Qabel","followers_url":"https://api.github.com/users/Qabel/followers","following_url":"https://api.github.com/users/Qabel/following{/other_user}","gists_url":"https://api.github.com/users/Qabel/gists{/gist_id}","starred_url":"https://api.github.com/users/Qabel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Qabel/subscriptions","organizations_url":"https://api.github.com/users/Qabel/orgs","repos_url":"https://api.github.com/users/Qabel/repos","events_url":"https://api.github.com/users/Qabel/events{/privacy}","received_events_url":"https://api.github.com/users/Qabel/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Qabel/qabel-desktop","description":"Desktop Frontend of Qabel","fork":false,"url":"https://api.github.com/repos/Qabel/qabel-desktop","forks_url":"https://api.github.com/repos/Qabel/qabel-desktop/forks","keys_url":"https://api.github.com/repos/Qabel/qabel-desktop/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Qabel/qabel-desktop/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Qabel/qabel-desktop/teams","hooks_url":"https://api.github.com/repos/Qabel/qabel-desktop/hooks","issue_events_url":"https://api.github.com/repos/Qabel/qabel-desktop/issues/events{/number}","events_url":"https://api.github.com/repos/Qabel/qabel-desktop/events","assignees_url":"https://api.github.com/repos/Qabel/qabel-desktop/assignees{/user}","branches_url":"https://api.github.com/repos/Qabel/qabel-desktop/branches{/branch}","tags_url":"https://api.github.com/repos/Qabel/qabel-desktop/tags","blobs_url":"https://api.github.com/repos/Qabel/qabel-desktop/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Qabel/qabel-desktop/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Qabel/qabel-desktop/git/refs{/sha}","trees_url":"https://api.github.com/repos/Qabel/qabel-desktop/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Qabel/qabel-desktop/statuses/{sha}","languages_url":"https://api.github.com/repos/Qabel/qabel-desktop/languages","stargazers_url":"https://api.github.com/repos/Qabel/qabel-desktop/stargazers","contributors_url":"https://api.github.com/repos/Qabel/qabel-desktop/contributors","subscribers_url":"https://api.github.com/repos/Qabel/qabel-desktop/subscribers","subscription_url":"https://api.github.com/repos/Qabel/qabel-desktop/subscription","commits_url":"https://api.github.com/repos/Qabel/qabel-desktop/commits{/sha}","git_commits_url":"https://api.github.com/repos/Qabel/qabel-desktop/git/commits{/sha}","comments_url":"https://api.github.com/repos/Qabel/qabel-desktop/comments{/number}","issue_comment_url":"https://api.github.com/repos/Qabel/qabel-desktop/issues/comments{/number}","contents_url":"https://api.github.com/repos/Qabel/qabel-desktop/contents/{+path}","compare_url":"https://api.github.com/repos/Qabel/qabel-desktop/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Qabel/qabel-desktop/merges","archive_url":"https://api.github.com/repos/Qabel/qabel-desktop/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Qabel/qabel-desktop/downloads","issues_url":"https://api.github.com/repos/Qabel/qabel-desktop/issues{/number}","pulls_url":"https://api.github.com/repos/Qabel/qabel-desktop/pulls{/number}","milestones_url":"https://api.github.com/repos/Qabel/qabel-desktop/milestones{/number}","notifications_url":"https://api.github.com/repos/Qabel/qabel-desktop/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Qabel/qabel-desktop/labels{/name}","releases_url":"https://api.github.com/repos/Qabel/qabel-desktop/releases{/id}","deployments_url":"https://api.github.com/repos/Qabel/qabel-desktop/deployments","created_at":"2014-10-20T10:38:47Z","updated_at":"2016-05-02T13:41:03Z","pushed_at":"2016-05-10T07:08:20Z","git_url":"git://github.com/Qabel/qabel-desktop.git","ssh_url":"git@github.com:Qabel/qabel-desktop.git","clone_url":"https://github.com/Qabel/qabel-desktop.git","svn_url":"https://github.com/Qabel/qabel-desktop","homepage":null,"size":4066,"stargazers_count":4,"watchers_count":4,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":11,"mirror_url":null,"open_issues_count":69,"forks":11,"open_issues":69,"watchers":4,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Qabel/qabel-desktop/pulls/355"},"html":{"href":"https://github.com/Qabel/qabel-desktop/pull/355"},"issue":{"href":"https://api.github.com/repos/Qabel/qabel-desktop/issues/355"},"comments":{"href":"https://api.github.com/repos/Qabel/qabel-desktop/issues/355/comments"},"review_comments":{"href":"https://api.github.com/repos/Qabel/qabel-desktop/pulls/355/comments"},"review_comment":{"href":"https://api.github.com/repos/Qabel/qabel-desktop/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Qabel/qabel-desktop/pulls/355/commits"},"statuses":{"href":"https://api.github.com/repos/Qabel/qabel-desktop/statuses/3573d81224927110ee8b14cdd660bbecdc16c8bc"}}}}