{"action":"created","comment":{"url":"https://api.github.com/repos/eclipse/smarthome/pulls/comments/32208541","id":32208541,"diff_hunk":"@@ -0,0 +1,196 @@\n+/*******************************************************************************\n+ * Copyright (c) 1997, 2015 by ProSyst Software GmbH\n+ * http://www.prosyst.com\n+ * All rights reserved. This program and the accompanying materials\n+ * are made available under the terms of the Eclipse Public License v1.0\n+ * which accompanies this distribution, and is available at\n+ * http://www.eclipse.org/legal/epl-v10.html\n+ *\n+ * Contributors:\n+ *    ProSyst Software GmbH - initial API and implementation\n+ *******************************************************************************/\n+\n+package org.eclipse.smarthome.automation.core.provider;\n+\n+import java.util.ArrayList;\n+import java.util.Iterator;\n+import java.util.List;\n+\n+import org.eclipse.smarthome.automation.template.Template;\n+import org.osgi.framework.Bundle;\n+import org.osgi.framework.BundleContext;\n+import org.osgi.framework.BundleEvent;\n+import org.osgi.util.tracker.BundleTracker;\n+import org.osgi.util.tracker.BundleTrackerCustomizer;\n+\n+/**\n+ * @author Ana Dimova - Initial Contribution\n+ *\n+ */\n+class AutomationResourceBundlesEventQueue implements Runnable, BundleTrackerCustomizer {\n+\n+    public static final String AUTOMATION_RESOURCES_HEADER = \"Automation-ResourceType\";\n+\n+    private List queue = new ArrayList();\n+\n+    private boolean running = false;\n+    private boolean closed = false;\n+    private boolean shared = false;\n+\n+    private BundleTracker bTracker;\n+    private TemplateResourceBundleProvider tProvider;\n+    private ModuleTypeResourceBundleProvider mProvider;\n+    private RuleResourceBundleImporter rProvider;\n+\n+    public AutomationResourceBundlesEventQueue(BundleContext bc, TemplateResourceBundleProvider tProvider,\n+            ModuleTypeResourceBundleProvider mProvider, RuleResourceBundleImporter rProvider) {\n+        this.tProvider = tProvider;\n+        this.mProvider = mProvider;\n+        this.rProvider = rProvider;\n+        bTracker = new BundleTracker(bc, ~Bundle.UNINSTALLED, this);\n+    }\n+\n+    public void open() {\n+        bTracker.open();\n+    }\n+\n+    @Override\n+    public void run() {\n+        boolean waitForEvents = true;\n+        while (true) {\n+            List l_queue = null;\n+            synchronized (this) {\n+                if (closed) {\n+                    notifyAll();\n+                    return;\n+                }\n+                if (queue.isEmpty()) {\n+                    if (waitForEvents) {\n+                        try {\n+                            wait(180000);\n+                        } catch (Throwable _) {\n+                        }\n+                        waitForEvents = false;\n+                        continue;\n+                    }\n+                    running = false;\n+                    notifyAll();\n+                    return;\n+                }\n+                l_queue = queue;\n+                shared = true;\n+            }\n+            try {\n+                Iterator events = l_queue.iterator();\n+                while (events.hasNext()) {\n+                    processBundleChanged((BundleEvent) events.next());\n+                }\n+            } catch (Throwable t) {\n+                t.printStackTrace(); // TODO\n+            }\n+            synchronized (this) {\n+                if (shared)\n+                    queue.clear();\n+                shared = false;\n+                waitForEvents = true;\n+                notifyAll();\n+            }\n+        }\n+    }\n+\n+    public void stop() {\n+        synchronized (this) {\n+            closed = true;\n+            notifyAll();\n+        }\n+        bTracker.close();\n+    }\n+\n+    /**\n+     * @see org.osgi.util.tracker.BundleTrackerCustomizer#addingBundle(org.osgi.framework.Bundle,\n+     *      org.osgi.framework.BundleEvent)\n+     */\n+    @Override\n+    public Object addingBundle(Bundle bundle, BundleEvent event) {\n+        if (isAnAutomationProvider(bundle)) {\n+            addEvent(event == null ? new BundleEvent(BundleEvent.INSTALLED, bundle) : event);\n+        }\n+        return bundle;\n+    }\n+\n+    /**\n+     * @see org.osgi.util.tracker.BundleTrackerCustomizer#modifiedBundle(org.osgi.framework.Bundle,\n+     *      org.osgi.framework.BundleEvent, java.lang.Object)\n+     */\n+    @Override\n+    public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) {\n+        if (isAnAutomationProvider(bundle) && event.getType() == BundleEvent.UPDATED) {\n+            addEvent(event);\n+        }\n+    }\n+\n+    /**\n+     * @see org.osgi.util.tracker.BundleTrackerCustomizer#removedBundle(org.osgi.framework.Bundle,\n+     *      org.osgi.framework.BundleEvent, java.lang.Object)\n+     */\n+    @Override\n+    public void removedBundle(Bundle bundle, BundleEvent event, Object object) {\n+        if (!closed) {\n+            if (isAnAutomationProvider(bundle)) {\n+                addEvent(event);\n+            }\n+        }\n+    }\n+\n+    /**\n+     * This method is used to check if the specified {@link Bundle} contains resource files providing {@link Template}s.\n+     *\n+     * @param bundle is a {@link Bundle} object to check.\n+     * @return <tt>true</tt> if the specified {@link Bundle} contains resource files providing {@link Template}s,\n+     *         <tt>false</tt> otherwise.\n+     */\n+    private boolean isAnAutomationProvider(Bundle bundle) {\n+        return bundle.getHeaders().get(AUTOMATION_RESOURCES_HEADER) != null;\n+    }\n+\n+    private synchronized void addEvent(BundleEvent event) {\n+        if (closed)\n+            return;\n+        if (shared) {\n+            queue = new ArrayList();\n+            shared = false;\n+        }\n+        if (queue.add(event)) {\n+            if (running)\n+                notifyAll();\n+            else {\n+                Thread th = new Thread(this, \"Template Provider Processing Queue\");","path":"bundles/automation/org.eclipse.smarthome.automation.providers/src/main/java/org/eclipse/smarthome/automation/core/provider/AutomationResourceBundlesEventQueue.java","position":167,"original_position":167,"commit_id":"4db006a1299091ee423e429017e56bd3f12230e1","original_commit_id":"4db006a1299091ee423e429017e56bd3f12230e1","user":{"login":"kaikreuzer","id":3244965,"avatar_url":"https://avatars.githubusercontent.com/u/3244965?v=3","gravatar_id":"","url":"https://api.github.com/users/kaikreuzer","html_url":"https://github.com/kaikreuzer","followers_url":"https://api.github.com/users/kaikreuzer/followers","following_url":"https://api.github.com/users/kaikreuzer/following{/other_user}","gists_url":"https://api.github.com/users/kaikreuzer/gists{/gist_id}","starred_url":"https://api.github.com/users/kaikreuzer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kaikreuzer/subscriptions","organizations_url":"https://api.github.com/users/kaikreuzer/orgs","repos_url":"https://api.github.com/users/kaikreuzer/repos","events_url":"https://api.github.com/users/kaikreuzer/events{/privacy}","received_events_url":"https://api.github.com/users/kaikreuzer/received_events","type":"User","site_admin":false},"body":"It's not only for Template providers, right? So better change to \"Automation Provider\"","created_at":"2015-06-11T10:38:36Z","updated_at":"2015-06-11T10:38:36Z","html_url":"https://github.com/eclipse/smarthome/pull/317#discussion_r32208541","pull_request_url":"https://api.github.com/repos/eclipse/smarthome/pulls/317","_links":{"self":{"href":"https://api.github.com/repos/eclipse/smarthome/pulls/comments/32208541"},"html":{"href":"https://github.com/eclipse/smarthome/pull/317#discussion_r32208541"},"pull_request":{"href":"https://api.github.com/repos/eclipse/smarthome/pulls/317"}}},"pull_request":{"url":"https://api.github.com/repos/eclipse/smarthome/pulls/317","id":36026769,"html_url":"https://github.com/eclipse/smarthome/pull/317","diff_url":"https://github.com/eclipse/smarthome/pull/317.diff","patch_url":"https://github.com/eclipse/smarthome/pull/317.patch","issue_url":"https://api.github.com/repos/eclipse/smarthome/issues/317","number":317,"state":"open","locked":false,"title":"Initial implementation of the automation component","user":{"login":"marinmitev","id":10187512,"avatar_url":"https://avatars.githubusercontent.com/u/10187512?v=3","gravatar_id":"","url":"https://api.github.com/users/marinmitev","html_url":"https://github.com/marinmitev","followers_url":"https://api.github.com/users/marinmitev/followers","following_url":"https://api.github.com/users/marinmitev/following{/other_user}","gists_url":"https://api.github.com/users/marinmitev/gists{/gist_id}","starred_url":"https://api.github.com/users/marinmitev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/marinmitev/subscriptions","organizations_url":"https://api.github.com/users/marinmitev/orgs","repos_url":"https://api.github.com/users/marinmitev/repos","events_url":"https://api.github.com/users/marinmitev/events{/privacy}","received_events_url":"https://api.github.com/users/marinmitev/received_events","type":"User","site_admin":false},"body":"Author: Marin Mitev <marin.mitev@gmail.com>\r\nAlso-by: Jordan Mihailov <j.mihailov@prosyst.com>\r\nAlso-by: Vasil Ilchev <v.ilchev@prosyst.bg>\r\nAlso-by: Ana Dimova <a.dimova@prosyst.bg>\r\n\r\nSigned-off-by: Marin Mitev <marin.mitev@gmail.com>","created_at":"2015-05-22T12:38:35Z","updated_at":"2015-06-11T10:38:36Z","closed_at":null,"merged_at":null,"merge_commit_sha":"29303432e480dcfc93d8995321bcc4ce413a1efb","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/eclipse/smarthome/pulls/317/commits","review_comments_url":"https://api.github.com/repos/eclipse/smarthome/pulls/317/comments","review_comment_url":"https://api.github.com/repos/eclipse/smarthome/pulls/comments{/number}","comments_url":"https://api.github.com/repos/eclipse/smarthome/issues/317/comments","statuses_url":"https://api.github.com/repos/eclipse/smarthome/statuses/4db006a1299091ee423e429017e56bd3f12230e1","head":{"label":"marinmitev:automation-component-impl","ref":"automation-component-impl","sha":"4db006a1299091ee423e429017e56bd3f12230e1","user":{"login":"marinmitev","id":10187512,"avatar_url":"https://avatars.githubusercontent.com/u/10187512?v=3","gravatar_id":"","url":"https://api.github.com/users/marinmitev","html_url":"https://github.com/marinmitev","followers_url":"https://api.github.com/users/marinmitev/followers","following_url":"https://api.github.com/users/marinmitev/following{/other_user}","gists_url":"https://api.github.com/users/marinmitev/gists{/gist_id}","starred_url":"https://api.github.com/users/marinmitev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/marinmitev/subscriptions","organizations_url":"https://api.github.com/users/marinmitev/orgs","repos_url":"https://api.github.com/users/marinmitev/repos","events_url":"https://api.github.com/users/marinmitev/events{/privacy}","received_events_url":"https://api.github.com/users/marinmitev/received_events","type":"User","site_admin":false},"repo":{"id":29968563,"name":"smarthome","full_name":"marinmitev/smarthome","owner":{"login":"marinmitev","id":10187512,"avatar_url":"https://avatars.githubusercontent.com/u/10187512?v=3","gravatar_id":"","url":"https://api.github.com/users/marinmitev","html_url":"https://github.com/marinmitev","followers_url":"https://api.github.com/users/marinmitev/followers","following_url":"https://api.github.com/users/marinmitev/following{/other_user}","gists_url":"https://api.github.com/users/marinmitev/gists{/gist_id}","starred_url":"https://api.github.com/users/marinmitev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/marinmitev/subscriptions","organizations_url":"https://api.github.com/users/marinmitev/orgs","repos_url":"https://api.github.com/users/marinmitev/repos","events_url":"https://api.github.com/users/marinmitev/events{/privacy}","received_events_url":"https://api.github.com/users/marinmitev/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/marinmitev/smarthome","description":"Eclipse SmartHome project","fork":true,"url":"https://api.github.com/repos/marinmitev/smarthome","forks_url":"https://api.github.com/repos/marinmitev/smarthome/forks","keys_url":"https://api.github.com/repos/marinmitev/smarthome/keys{/key_id}","collaborators_url":"https://api.github.com/repos/marinmitev/smarthome/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/marinmitev/smarthome/teams","hooks_url":"https://api.github.com/repos/marinmitev/smarthome/hooks","issue_events_url":"https://api.github.com/repos/marinmitev/smarthome/issues/events{/number}","events_url":"https://api.github.com/repos/marinmitev/smarthome/events","assignees_url":"https://api.github.com/repos/marinmitev/smarthome/assignees{/user}","branches_url":"https://api.github.com/repos/marinmitev/smarthome/branches{/branch}","tags_url":"https://api.github.com/repos/marinmitev/smarthome/tags","blobs_url":"https://api.github.com/repos/marinmitev/smarthome/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/marinmitev/smarthome/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/marinmitev/smarthome/git/refs{/sha}","trees_url":"https://api.github.com/repos/marinmitev/smarthome/git/trees{/sha}","statuses_url":"https://api.github.com/repos/marinmitev/smarthome/statuses/{sha}","languages_url":"https://api.github.com/repos/marinmitev/smarthome/languages","stargazers_url":"https://api.github.com/repos/marinmitev/smarthome/stargazers","contributors_url":"https://api.github.com/repos/marinmitev/smarthome/contributors","subscribers_url":"https://api.github.com/repos/marinmitev/smarthome/subscribers","subscription_url":"https://api.github.com/repos/marinmitev/smarthome/subscription","commits_url":"https://api.github.com/repos/marinmitev/smarthome/commits{/sha}","git_commits_url":"https://api.github.com/repos/marinmitev/smarthome/git/commits{/sha}","comments_url":"https://api.github.com/repos/marinmitev/smarthome/comments{/number}","issue_comment_url":"https://api.github.com/repos/marinmitev/smarthome/issues/comments{/number}","contents_url":"https://api.github.com/repos/marinmitev/smarthome/contents/{+path}","compare_url":"https://api.github.com/repos/marinmitev/smarthome/compare/{base}...{head}","merges_url":"https://api.github.com/repos/marinmitev/smarthome/merges","archive_url":"https://api.github.com/repos/marinmitev/smarthome/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/marinmitev/smarthome/downloads","issues_url":"https://api.github.com/repos/marinmitev/smarthome/issues{/number}","pulls_url":"https://api.github.com/repos/marinmitev/smarthome/pulls{/number}","milestones_url":"https://api.github.com/repos/marinmitev/smarthome/milestones{/number}","notifications_url":"https://api.github.com/repos/marinmitev/smarthome/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/marinmitev/smarthome/labels{/name}","releases_url":"https://api.github.com/repos/marinmitev/smarthome/releases{/id}","created_at":"2015-01-28T13:25:03Z","updated_at":"2015-05-25T14:08:43Z","pushed_at":"2015-06-08T12:48:07Z","git_url":"git://github.com/marinmitev/smarthome.git","ssh_url":"git@github.com:marinmitev/smarthome.git","clone_url":"https://github.com/marinmitev/smarthome.git","svn_url":"https://github.com/marinmitev/smarthome","homepage":null,"size":8056,"stargazers_count":2,"watchers_count":2,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":2,"default_branch":"master"}},"base":{"label":"eclipse:master","ref":"master","sha":"330e5034a90f7b1c4c6343ba4304d066b3f026f8","user":{"login":"eclipse","id":56974,"avatar_url":"https://avatars.githubusercontent.com/u/56974?v=3","gravatar_id":"","url":"https://api.github.com/users/eclipse","html_url":"https://github.com/eclipse","followers_url":"https://api.github.com/users/eclipse/followers","following_url":"https://api.github.com/users/eclipse/following{/other_user}","gists_url":"https://api.github.com/users/eclipse/gists{/gist_id}","starred_url":"https://api.github.com/users/eclipse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eclipse/subscriptions","organizations_url":"https://api.github.com/users/eclipse/orgs","repos_url":"https://api.github.com/users/eclipse/repos","events_url":"https://api.github.com/users/eclipse/events{/privacy}","received_events_url":"https://api.github.com/users/eclipse/received_events","type":"Organization","site_admin":false},"repo":{"id":15778981,"name":"smarthome","full_name":"eclipse/smarthome","owner":{"login":"eclipse","id":56974,"avatar_url":"https://avatars.githubusercontent.com/u/56974?v=3","gravatar_id":"","url":"https://api.github.com/users/eclipse","html_url":"https://github.com/eclipse","followers_url":"https://api.github.com/users/eclipse/followers","following_url":"https://api.github.com/users/eclipse/following{/other_user}","gists_url":"https://api.github.com/users/eclipse/gists{/gist_id}","starred_url":"https://api.github.com/users/eclipse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eclipse/subscriptions","organizations_url":"https://api.github.com/users/eclipse/orgs","repos_url":"https://api.github.com/users/eclipse/repos","events_url":"https://api.github.com/users/eclipse/events{/privacy}","received_events_url":"https://api.github.com/users/eclipse/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/eclipse/smarthome","description":"Eclipse SmartHome project","fork":false,"url":"https://api.github.com/repos/eclipse/smarthome","forks_url":"https://api.github.com/repos/eclipse/smarthome/forks","keys_url":"https://api.github.com/repos/eclipse/smarthome/keys{/key_id}","collaborators_url":"https://api.github.com/repos/eclipse/smarthome/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/eclipse/smarthome/teams","hooks_url":"https://api.github.com/repos/eclipse/smarthome/hooks","issue_events_url":"https://api.github.com/repos/eclipse/smarthome/issues/events{/number}","events_url":"https://api.github.com/repos/eclipse/smarthome/events","assignees_url":"https://api.github.com/repos/eclipse/smarthome/assignees{/user}","branches_url":"https://api.github.com/repos/eclipse/smarthome/branches{/branch}","tags_url":"https://api.github.com/repos/eclipse/smarthome/tags","blobs_url":"https://api.github.com/repos/eclipse/smarthome/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/eclipse/smarthome/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/eclipse/smarthome/git/refs{/sha}","trees_url":"https://api.github.com/repos/eclipse/smarthome/git/trees{/sha}","statuses_url":"https://api.github.com/repos/eclipse/smarthome/statuses/{sha}","languages_url":"https://api.github.com/repos/eclipse/smarthome/languages","stargazers_url":"https://api.github.com/repos/eclipse/smarthome/stargazers","contributors_url":"https://api.github.com/repos/eclipse/smarthome/contributors","subscribers_url":"https://api.github.com/repos/eclipse/smarthome/subscribers","subscription_url":"https://api.github.com/repos/eclipse/smarthome/subscription","commits_url":"https://api.github.com/repos/eclipse/smarthome/commits{/sha}","git_commits_url":"https://api.github.com/repos/eclipse/smarthome/git/commits{/sha}","comments_url":"https://api.github.com/repos/eclipse/smarthome/comments{/number}","issue_comment_url":"https://api.github.com/repos/eclipse/smarthome/issues/comments{/number}","contents_url":"https://api.github.com/repos/eclipse/smarthome/contents/{+path}","compare_url":"https://api.github.com/repos/eclipse/smarthome/compare/{base}...{head}","merges_url":"https://api.github.com/repos/eclipse/smarthome/merges","archive_url":"https://api.github.com/repos/eclipse/smarthome/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/eclipse/smarthome/downloads","issues_url":"https://api.github.com/repos/eclipse/smarthome/issues{/number}","pulls_url":"https://api.github.com/repos/eclipse/smarthome/pulls{/number}","milestones_url":"https://api.github.com/repos/eclipse/smarthome/milestones{/number}","notifications_url":"https://api.github.com/repos/eclipse/smarthome/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/eclipse/smarthome/labels{/name}","releases_url":"https://api.github.com/repos/eclipse/smarthome/releases{/id}","created_at":"2014-01-09T20:47:19Z","updated_at":"2015-06-10T17:05:58Z","pushed_at":"2015-06-10T15:24:59Z","git_url":"git://github.com/eclipse/smarthome.git","ssh_url":"git@github.com:eclipse/smarthome.git","clone_url":"https://github.com/eclipse/smarthome.git","svn_url":"https://github.com/eclipse/smarthome","homepage":null,"size":13827,"stargazers_count":150,"watchers_count":150,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":144,"mirror_url":null,"open_issues_count":9,"forks":144,"open_issues":9,"watchers":150,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/eclipse/smarthome/pulls/317"},"html":{"href":"https://github.com/eclipse/smarthome/pull/317"},"issue":{"href":"https://api.github.com/repos/eclipse/smarthome/issues/317"},"comments":{"href":"https://api.github.com/repos/eclipse/smarthome/issues/317/comments"},"review_comments":{"href":"https://api.github.com/repos/eclipse/smarthome/pulls/317/comments"},"review_comment":{"href":"https://api.github.com/repos/eclipse/smarthome/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/eclipse/smarthome/pulls/317/commits"},"statuses":{"href":"https://api.github.com/repos/eclipse/smarthome/statuses/4db006a1299091ee423e429017e56bd3f12230e1"}}}}