diff options
Diffstat (limited to 'plugins')
30 files changed, 1226 insertions, 16 deletions
diff --git a/plugins/org.eclipse.osee.account.rest.client/src/org/eclipse/osee/account/rest/client/AccountClient.java b/plugins/org.eclipse.osee.account.rest.client/src/org/eclipse/osee/account/rest/client/AccountClient.java index bf6d20dfe60..bb5969a83ce 100644 --- a/plugins/org.eclipse.osee.account.rest.client/src/org/eclipse/osee/account/rest/client/AccountClient.java +++ b/plugins/org.eclipse.osee.account.rest.client/src/org/eclipse/osee/account/rest/client/AccountClient.java @@ -19,6 +19,7 @@ import org.eclipse.osee.account.rest.model.AccountInput; import org.eclipse.osee.account.rest.model.AccountPreferencesData; import org.eclipse.osee.account.rest.model.AccountSessionData; import org.eclipse.osee.account.rest.model.AccountSessionDetailsData; +import org.eclipse.osee.account.rest.model.AccountWebPreferences; import org.eclipse.osee.framework.jdk.core.type.ResultSet; /** @@ -65,4 +66,6 @@ public interface AccountClient { ResultSet<UnsubscribeInfo> getUnsubscribeUris(Long accountId, Collection<String> groupNames); + AccountWebPreferences getAccountWebPreferencesByUniqueField(Long accountId); + } diff --git a/plugins/org.eclipse.osee.account.rest.client/src/org/eclipse/osee/account/rest/client/internal/AccountClientImpl.java b/plugins/org.eclipse.osee.account.rest.client/src/org/eclipse/osee/account/rest/client/internal/AccountClientImpl.java index f6192e60777..7e5033efc1a 100644 --- a/plugins/org.eclipse.osee.account.rest.client/src/org/eclipse/osee/account/rest/client/internal/AccountClientImpl.java +++ b/plugins/org.eclipse.osee.account.rest.client/src/org/eclipse/osee/account/rest/client/internal/AccountClientImpl.java @@ -38,6 +38,7 @@ import org.eclipse.osee.account.rest.model.AccountPreferencesData; import org.eclipse.osee.account.rest.model.AccountPreferencesInput; import org.eclipse.osee.account.rest.model.AccountSessionData; import org.eclipse.osee.account.rest.model.AccountSessionDetailsData; +import org.eclipse.osee.account.rest.model.AccountWebPreferences; import org.eclipse.osee.account.rest.model.SubscriptionData; import org.eclipse.osee.framework.core.data.OseeClient; import org.eclipse.osee.framework.jdk.core.type.ResultSet; @@ -173,6 +174,17 @@ public class AccountClientImpl implements AccountClient { } @Override + public AccountWebPreferences getAccountWebPreferencesByUniqueField(Long accountId) { + URI uri = UriBuilder.fromUri(baseUri).path(ACCOUNTS).path(ACCOUNT_PREFERENCES).path(ACCOUNT_ID_TEMPLATE).build( + accountId); + try { + return newTarget(uri).request(MediaType.APPLICATION_JSON_TYPE).get(AccountWebPreferences.class); + } catch (Exception ex) { + throw JaxRsExceptions.asOseeException(ex); + } + } + + @Override public boolean setAccountActive(Long accountId, boolean active) { URI uri = UriBuilder.fromUri(baseUri).path(ACCOUNTS).path(ACCOUNT_ID_TEMPLATE).path(ACCOUNT_ACTIVE).build(accountId); diff --git a/plugins/org.eclipse.osee.account.rest.model/src/org/eclipse/osee/account/rest/model/AccountWebPreferences.java b/plugins/org.eclipse.osee.account.rest.model/src/org/eclipse/osee/account/rest/model/AccountWebPreferences.java index b09094e7bef..f01a67d219f 100644 --- a/plugins/org.eclipse.osee.account.rest.model/src/org/eclipse/osee/account/rest/model/AccountWebPreferences.java +++ b/plugins/org.eclipse.osee.account.rest.model/src/org/eclipse/osee/account/rest/model/AccountWebPreferences.java @@ -13,6 +13,7 @@ package org.eclipse.osee.account.rest.model; import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -21,7 +22,7 @@ import org.json.JSONObject; */ public class AccountWebPreferences { - Map<String, Link> linksMap; + Map<String, Link> linksMap = new HashMap<String, Link>(); public AccountWebPreferences() { @@ -31,16 +32,11 @@ public class AccountWebPreferences { for (String team : teamToPreferences.keySet()) { initPreferences(teamToPreferences.get(team), team); } - } private void initPreferences(String string, String team) { try { JSONObject jObject = new JSONObject(string); - - if (linksMap == null) { - linksMap = new HashMap<String, Link>(); - } JSONObject linkJsonObject = jObject.getJSONObject("links"); @SuppressWarnings("unchecked") Iterator<String> keys = linkJsonObject.keys(); @@ -54,6 +50,12 @@ public class AccountWebPreferences { if (linkJObject.has("url")) { link.setUrl(linkJObject.getString("url")); } + if (linkJObject.has("tags")) { + JSONArray array = linkJObject.getJSONArray("tags"); + for (int x = 0; x < array.length(); x++) { + link.getTags().add(array.getString(x)); + } + } link.setTeam(team); link.setId(linkJObject.getString("id")); linksMap.put(next, link); diff --git a/plugins/org.eclipse.osee.account.rest.model/src/org/eclipse/osee/account/rest/model/Link.java b/plugins/org.eclipse.osee.account.rest.model/src/org/eclipse/osee/account/rest/model/Link.java index 7f500b6cd2b..abec1f4d635 100644 --- a/plugins/org.eclipse.osee.account.rest.model/src/org/eclipse/osee/account/rest/model/Link.java +++ b/plugins/org.eclipse.osee.account.rest.model/src/org/eclipse/osee/account/rest/model/Link.java @@ -10,6 +10,9 @@ *******************************************************************************/ package org.eclipse.osee.account.rest.model; +import java.util.ArrayList; +import java.util.List; + /** * @author Angel Avila */ @@ -18,10 +21,7 @@ public class Link { String url; String id; String team; - - public Link() { - - } + List<String> tags = new ArrayList<String>(); public void setId(String id) { this.id = id; @@ -54,4 +54,12 @@ public class Link { public String getTeam() { return team; } + + public List<String> getTags() { + return tags; + } + + public void setTags(List<String> tags) { + this.tags = tags; + } } diff --git a/plugins/org.eclipse.osee.account.rest.test/src/org/eclipse/osee/account/rest/internal/AccountResourceTest.java b/plugins/org.eclipse.osee.account.rest.test/src/org/eclipse/osee/account/rest/internal/AccountResourceTest.java index 5a041b52c67..8da724baf54 100644 --- a/plugins/org.eclipse.osee.account.rest.test/src/org/eclipse/osee/account/rest/internal/AccountResourceTest.java +++ b/plugins/org.eclipse.osee.account.rest.test/src/org/eclipse/osee/account/rest/internal/AccountResourceTest.java @@ -37,7 +37,6 @@ import org.mockito.Mock; */ public class AccountResourceTest { - private static final String NEW_USERNAME = "helloWorld"; private static final ArtifactId ACCOUNT_ID = TokenFactory.createArtifactId(93253L); //@formatter:off diff --git a/plugins/org.eclipse.osee.account.rest.test/src/org/eclipse/osee/account/rest/internal/AccountsResourceTest.java b/plugins/org.eclipse.osee.account.rest.test/src/org/eclipse/osee/account/rest/internal/AccountsResourceTest.java index 6a5fffb7e88..65477472b22 100644 --- a/plugins/org.eclipse.osee.account.rest.test/src/org/eclipse/osee/account/rest/internal/AccountsResourceTest.java +++ b/plugins/org.eclipse.osee.account.rest.test/src/org/eclipse/osee/account/rest/internal/AccountsResourceTest.java @@ -19,8 +19,6 @@ import java.util.ArrayList; import java.util.List; import org.eclipse.osee.account.rest.model.AccountInfoData; import org.eclipse.osee.account.rest.model.AccountInput; -import org.eclipse.osee.framework.core.data.ArtifactId; -import org.eclipse.osee.framework.core.data.TokenFactory; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; @@ -33,7 +31,6 @@ import org.mockito.Mock; public class AccountsResourceTest { private static final String NEW_USERNAME = "helloWorld"; - private static final ArtifactId ACCOUNT_ID = TokenFactory.createArtifactId(93253L); //@formatter:off @Mock private AccountOps accountOps; diff --git a/plugins/org.eclipse.osee.ats.client.integration.tests/META-INF/MANIFEST.MF b/plugins/org.eclipse.osee.ats.client.integration.tests/META-INF/MANIFEST.MF index 4ccf9c5eb73..f80a26a6ad1 100644 --- a/plugins/org.eclipse.osee.ats.client.integration.tests/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.osee.ats.client.integration.tests/META-INF/MANIFEST.MF @@ -23,6 +23,7 @@ Import-Package: com.google.common.collect, org.eclipse.nebula.widgets.xviewer.customize, org.eclipse.nebula.widgets.xviewer.customize.dialog, org.eclipse.nebula.widgets.xviewer.util, + org.eclipse.osee.account.rest.model, org.eclipse.osee.ats, org.eclipse.osee.ats.access, org.eclipse.osee.ats.actions, @@ -114,6 +115,7 @@ Import-Package: com.google.common.collect, org.eclipse.osee.framework.ui.skynet.artifact, org.eclipse.osee.framework.ui.skynet.artifact.massEditor, org.eclipse.osee.framework.ui.skynet.blam, + org.eclipse.osee.framework.ui.skynet.links, org.eclipse.osee.framework.ui.skynet.render, org.eclipse.osee.framework.ui.skynet.results, org.eclipse.osee.framework.ui.skynet.results.html, diff --git a/plugins/org.eclipse.osee.ats.client.integration.tests/src/org/eclipse/osee/ats/client/integration/AtsClientIntegrationTestSuite.java b/plugins/org.eclipse.osee.ats.client.integration.tests/src/org/eclipse/osee/ats/client/integration/AtsClientIntegrationTestSuite.java index 88624a6dc7d..0feb8132a30 100644 --- a/plugins/org.eclipse.osee.ats.client.integration.tests/src/org/eclipse/osee/ats/client/integration/AtsClientIntegrationTestSuite.java +++ b/plugins/org.eclipse.osee.ats.client.integration.tests/src/org/eclipse/osee/ats/client/integration/AtsClientIntegrationTestSuite.java @@ -15,6 +15,7 @@ import org.eclipse.osee.ats.client.integration.tests.DemoDbPopulateSuite; import org.eclipse.osee.ats.client.integration.tests.DirtyArtifactCacheTest; import org.eclipse.osee.ats.client.integration.tests.framework.ClientResourceTest; import org.eclipse.osee.ats.client.integration.tests.framework.skynet.core.artifact.SkyentCoreArtifact_Suite; +import org.eclipse.osee.ats.client.integration.tests.framework.ui.skynet.FrameworkUiSkynetTest_Suite; import org.eclipse.osee.ats.client.integration.tests.framework.ui.skynet.dialog.FrameworkUiSkynetTest_Dialog_Suite; import org.eclipse.osee.ats.client.integration.tests.util.DbInitTest; import org.junit.runner.RunWith; @@ -30,6 +31,7 @@ import org.junit.runners.Suite; ClientResourceTest.class, AtsTest_AllAts_Suite.class, SkyentCoreArtifact_Suite.class, + FrameworkUiSkynetTest_Suite.class, FrameworkUiSkynetTest_Dialog_Suite.class, DirtyArtifactCacheTest.class}) public class AtsClientIntegrationTestSuite { diff --git a/plugins/org.eclipse.osee.ats.client.integration.tests/src/org/eclipse/osee/ats/client/integration/tests/framework/ui/skynet/FrameworkUiSkynetTest_Suite.java b/plugins/org.eclipse.osee.ats.client.integration.tests/src/org/eclipse/osee/ats/client/integration/tests/framework/ui/skynet/FrameworkUiSkynetTest_Suite.java new file mode 100644 index 00000000000..0bb100654b3 --- /dev/null +++ b/plugins/org.eclipse.osee.ats.client.integration.tests/src/org/eclipse/osee/ats/client/integration/tests/framework/ui/skynet/FrameworkUiSkynetTest_Suite.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2016 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.ats.client.integration.tests.framework.ui.skynet; + +import org.eclipse.osee.ats.client.integration.tests.util.DemoTestUtil; +import org.eclipse.osee.framework.jdk.core.util.OseeProperties; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * @author Donald G. Dunne + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ // + LinkUtilTest.class, // +}) +public class FrameworkUiSkynetTest_Suite { + + @BeforeClass + public static void setUp() throws Exception { + OseeProperties.setIsInTest(true); + System.out.println("\n\nBegin " + FrameworkUiSkynetTest_Suite.class.getSimpleName()); + DemoTestUtil.setUpTest(); + } + + @AfterClass + public static void tearDown() throws Exception { + System.out.println("End " + FrameworkUiSkynetTest_Suite.class.getSimpleName()); + } +} diff --git a/plugins/org.eclipse.osee.ats.client.integration.tests/src/org/eclipse/osee/ats/client/integration/tests/framework/ui/skynet/LinkUtilTest.java b/plugins/org.eclipse.osee.ats.client.integration.tests/src/org/eclipse/osee/ats/client/integration/tests/framework/ui/skynet/LinkUtilTest.java new file mode 100644 index 00000000000..9d480eabe6d --- /dev/null +++ b/plugins/org.eclipse.osee.ats.client.integration.tests/src/org/eclipse/osee/ats/client/integration/tests/framework/ui/skynet/LinkUtilTest.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2016 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.ats.client.integration.tests.framework.ui.skynet; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import java.util.Arrays; +import org.eclipse.osee.account.rest.model.AccountWebPreferences; +import org.eclipse.osee.account.rest.model.Link; +import org.eclipse.osee.framework.ui.skynet.links.LinkUtil; +import org.junit.Test; + +/** + * @author Donald G. Dunne + */ +public class LinkUtilTest { + + @Test + public void test() throws Exception { + for (Boolean global : Arrays.asList(false, true)) { + AccountWebPreferences data = LinkUtil.getAccountsPreferencesData(global); + assertNotNull(data); + assertTrue(data.getLinks().isEmpty()); + + Link link = new Link(); + link.setId("my.id"); + link.setName("Test URL"); + link.setUrl("http://www.test.com"); + data.getLinks().put(link.getId(), link); + + LinkUtil.saveWebPreferences(data, global); + + data = LinkUtil.getAccountsPreferencesData(global); + assertNotNull(data); + assertEquals(1, data.getLinks().size()); + Link link2 = data.getLinks().get("my.id"); + assertEquals("my.id", link2.getId()); + assertEquals("Test URL", link2.getName()); + assertEquals("http://www.test.com", link2.getUrl()); + + link2.setName("Test URL2"); + link2.setUrl("http://www.test2.com"); + LinkUtil.addUpdateLink(link2, global); + data = LinkUtil.getAccountsPreferencesData(global); + assertNotNull(data); + assertEquals(1, data.getLinks().size()); + Link link3 = data.getLinks().get("my.id"); + assertEquals("my.id", link3.getId()); + assertEquals("Test URL2", link3.getName()); + assertEquals("http://www.test2.com", link3.getUrl()); + + LinkUtil.deleteLink(link2, global); + + data = LinkUtil.getAccountsPreferencesData(global); + assertNotNull(data); + assertTrue(data.getLinks().isEmpty()); + + } + } +} diff --git a/plugins/org.eclipse.osee.ats/META-INF/MANIFEST.MF b/plugins/org.eclipse.osee.ats/META-INF/MANIFEST.MF index 5f62e704715..2b5b4d0eeea 100644 --- a/plugins/org.eclipse.osee.ats/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.osee.ats/META-INF/MANIFEST.MF @@ -184,6 +184,7 @@ Import-Package: com.google.common.cache, org.eclipse.osee.framework.ui.skynet.dialogs, org.eclipse.osee.framework.ui.skynet.explorer, org.eclipse.osee.framework.ui.skynet.group, + org.eclipse.osee.framework.ui.skynet.links, org.eclipse.osee.framework.ui.skynet.notify, org.eclipse.osee.framework.ui.skynet.render, org.eclipse.osee.framework.ui.skynet.render.compare, diff --git a/plugins/org.eclipse.osee.ats/OSGI-INF/navigate.view.links.topic.handler.xml b/plugins/org.eclipse.osee.ats/OSGI-INF/navigate.view.links.topic.handler.xml new file mode 100644 index 00000000000..a10e743f1cb --- /dev/null +++ b/plugins/org.eclipse.osee.ats/OSGI-INF/navigate.view.links.topic.handler.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true"> +<implementation class="org.eclipse.osee.ats.navigate.NavigateViewLinksTopicEventHandler"/> +<service> + <provide interface="org.osgi.service.event.EventHandler"/> +</service> +<property name="event.topics" type="String" value="framework/web/prefs/modified/links/*"/> +</scr:component> diff --git a/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/navigate/NavigateView.java b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/navigate/NavigateView.java index e647440eac5..bdef0bf915e 100644 --- a/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/navigate/NavigateView.java +++ b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/navigate/NavigateView.java @@ -59,6 +59,7 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IMemento; import org.eclipse.ui.IViewSite; @@ -306,4 +307,30 @@ public class NavigateView extends ViewPart implements IXNavigateEventListener { } } + public XNavigateItem getItem(long topLinkId, boolean recurseChildren) { + for (TreeItem treeItem : xNavComp.getFilteredTree().getViewer().getTree().getItems()) { + XNavigateItem treeNavItem = (XNavigateItem) treeItem.getData(); + XNavigateItem foundItem = getItem(treeNavItem, topLinkId, recurseChildren); + if (foundItem != null) { + return foundItem; + } + } + return null; + } + + public XNavigateItem getItem(XNavigateItem item, long topLinkId, boolean recurseChildren) { + if (item.getId() == topLinkId) { + return item; + } + if (recurseChildren) { + for (XNavigateItem child : item.getChildren()) { + XNavigateItem found = getItem(child, topLinkId, recurseChildren); + if (found != null) { + return found; + } + } + } + return null; + } + }
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/navigate/NavigateViewLinksTopicEventHandler.java b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/navigate/NavigateViewLinksTopicEventHandler.java new file mode 100644 index 00000000000..58885dd75f7 --- /dev/null +++ b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/navigate/NavigateViewLinksTopicEventHandler.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2016 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.ats.navigate; + +import java.util.logging.Level; +import org.eclipse.osee.framework.logging.OseeLog; +import org.eclipse.osee.framework.ui.plugin.xnavigate.XNavigateItem; +import org.eclipse.osee.framework.ui.skynet.links.LinksNavigateViewItems; +import org.eclipse.osee.framework.ui.skynet.util.FrameworkEvents; +import org.eclipse.osee.framework.ui.swt.Displays; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventHandler; + +/** + * Handler for {@link FrameworkEvents.PERSONAL_WEB_PREFERENCES}</br> + * Handler for {@link FrameworkEvents.GLOBAL_WEB_PREFERENCES} + * + * @author Donald G. Dunne + */ +public class NavigateViewLinksTopicEventHandler implements EventHandler { + + public static final long TOP_LINK_ID = 4561556789L; + + @Override + public void handleEvent(Event event) { + try { + Displays.ensureInDisplayThread(new Runnable() { + + @Override + public void run() { + XNavigateItem linkItem = NavigateView.getNavigateView().getItem(TOP_LINK_ID, true); + LinksNavigateViewItems.reloadLinks(linkItem); + NavigateView.getNavigateView().refresh(linkItem); + } + }); + } catch (Exception ex) { + OseeLog.log(NavigateViewLinksTopicEventHandler.class, Level.SEVERE, ex); + } + } + + @Override + public String toString() { + return String.format("%s for %s / %s", getClass(), FrameworkEvents.GLOBAL_WEB_PREFERENCES, + FrameworkEvents.PERSONAL_WEB_PREFERENCES); + } +} diff --git a/plugins/org.eclipse.osee.framework.ui.plugin/src/org/eclipse/osee/framework/ui/plugin/xnavigate/IXNavigateMenuItem.java b/plugins/org.eclipse.osee.framework.ui.plugin/src/org/eclipse/osee/framework/ui/plugin/xnavigate/IXNavigateMenuItem.java new file mode 100644 index 00000000000..655d8b1ab02 --- /dev/null +++ b/plugins/org.eclipse.osee.framework.ui.plugin/src/org/eclipse/osee/framework/ui/plugin/xnavigate/IXNavigateMenuItem.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2016 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.framework.ui.plugin.xnavigate; + +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.TreeItem; + +/** + * Implement this interface to give a chance to add MenuItems to the menu when item is right-clicked. + * + * @author Donald G. Dunne + */ +public interface IXNavigateMenuItem { + + void addMenuItems(Menu menu, TreeItem selectedTreeItem); + +} diff --git a/plugins/org.eclipse.osee.framework.ui.plugin/src/org/eclipse/osee/framework/ui/plugin/xnavigate/XNavigateComposite.java b/plugins/org.eclipse.osee.framework.ui.plugin/src/org/eclipse/osee/framework/ui/plugin/xnavigate/XNavigateComposite.java index 73adf884721..a7415bee40d 100644 --- a/plugins/org.eclipse.osee.framework.ui.plugin/src/org/eclipse/osee/framework/ui/plugin/xnavigate/XNavigateComposite.java +++ b/plugins/org.eclipse.osee.framework.ui.plugin/src/org/eclipse/osee/framework/ui/plugin/xnavigate/XNavigateComposite.java @@ -12,9 +12,14 @@ package org.eclipse.osee.framework.ui.plugin.xnavigate; import java.util.List; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.osee.activity.api.Activity; import org.eclipse.osee.activity.api.ActivityLog; import org.eclipse.osee.framework.jdk.core.type.OseeCoreException; @@ -39,10 +44,13 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.dialogs.FilteredTree; /** @@ -118,6 +126,42 @@ public class XNavigateComposite extends Composite { } } }); + + MenuManager menuManager = new MenuManager(); + menuManager.setRemoveAllWhenShown(true); + menuManager.addMenuListener(new IMenuListener() { + @Override + public void menuAboutToShow(IMenuManager manager) { + MenuManager menuManager = (MenuManager) manager; + menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + } + }); + + addMenu(filteredTree.getViewer()); + } + + private void addMenu(TreeViewer treeViewer) { + final Menu menu = new Menu(treeViewer.getTree().getShell(), SWT.POP_UP); + treeViewer.getTree().setMenu(menu); + menu.addListener(SWT.Show, new Listener() { + @Override + public void handleEvent(Event event) { + MenuItem[] menuItems = menu.getItems(); + for (int i = 0; i < menuItems.length; i++) { + menuItems[i].dispose(); + } + TreeItem[] treeItems = treeViewer.getTree().getSelection(); + final TreeItem selectedTreeItem = treeItems[0]; + if (selectedTreeItem.getData() instanceof XNavigateItem) { + XNavigateItem navItem = (XNavigateItem) selectedTreeItem.getData(); + for (IXNavigateMenuItem menuItem : navItem.getMenuItems()) { + menuItem.addMenuItems(menu, selectedTreeItem); + } + } + } + + }); + } protected void disposeTooltip() { diff --git a/plugins/org.eclipse.osee.framework.ui.plugin/src/org/eclipse/osee/framework/ui/plugin/xnavigate/XNavigateItem.java b/plugins/org.eclipse.osee.framework.ui.plugin/src/org/eclipse/osee/framework/ui/plugin/xnavigate/XNavigateItem.java index 2e24943e93e..0308c53254f 100644 --- a/plugins/org.eclipse.osee.framework.ui.plugin/src/org/eclipse/osee/framework/ui/plugin/xnavigate/XNavigateItem.java +++ b/plugins/org.eclipse.osee.framework.ui.plugin/src/org/eclipse/osee/framework/ui/plugin/xnavigate/XNavigateItem.java @@ -12,6 +12,7 @@ package org.eclipse.osee.framework.ui.plugin.xnavigate; import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedList; import java.util.List; import org.eclipse.osee.framework.ui.plugin.xnavigate.XNavigateComposite.TableLoadOption; import org.eclipse.osee.framework.ui.swt.ImageManager; @@ -27,6 +28,9 @@ public class XNavigateItem { private String name; private XNavigateItem parent; private final KeyedImage oseeImage; + private List<IXNavigateMenuItem> menuItems; + private Object data; + private long id = 0L; public XNavigateItem(XNavigateItem parent, String name, KeyedImage oseeImage) { this.parent = parent; @@ -103,4 +107,37 @@ public class XNavigateItem { public String toString() { return getName(); } + + public List<IXNavigateMenuItem> getMenuItems() { + if (menuItems == null) { + return Collections.emptyList(); + } + return menuItems; + } + + /** + * Add Menu creation listener to supply custom menu options when right-click on item. + */ + public void addMenuItem(IXNavigateMenuItem listener) { + if (menuItems == null) { + menuItems = new LinkedList<>(); + } + menuItems.add(listener); + } + + public Object getData() { + return data; + } + + public void setData(Object data) { + this.data = data; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } }
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.framework.ui.plugin/src/org/eclipse/osee/framework/ui/plugin/xnavigate/XNavigateUrlItem.java b/plugins/org.eclipse.osee.framework.ui.plugin/src/org/eclipse/osee/framework/ui/plugin/xnavigate/XNavigateUrlItem.java index d31f1de7ecc..f0ee9aaa297 100644 --- a/plugins/org.eclipse.osee.framework.ui.plugin/src/org/eclipse/osee/framework/ui/plugin/xnavigate/XNavigateUrlItem.java +++ b/plugins/org.eclipse.osee.framework.ui.plugin/src/org/eclipse/osee/framework/ui/plugin/xnavigate/XNavigateUrlItem.java @@ -32,7 +32,7 @@ public class XNavigateUrlItem extends XNavigateItemAction { /** * Creates a navigation item that will open the given url either internal or external to Eclipse. - * + * * @param name to use as display name * @param url to open * @param external true to open in system browser; false to open inside Eclipse @@ -61,4 +61,5 @@ public class XNavigateUrlItem extends XNavigateItemAction { } } } + } diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/META-INF/MANIFEST.MF b/plugins/org.eclipse.osee.framework.ui.skynet/META-INF/MANIFEST.MF index 286586f222d..617f1de9835 100644 --- a/plugins/org.eclipse.osee.framework.ui.skynet/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.osee.framework.ui.skynet/META-INF/MANIFEST.MF @@ -221,6 +221,7 @@ Export-Package: org.eclipse.osee.framework.ui.skynet, org.eclipse.osee.framework.ui.skynet.group, org.eclipse.osee.framework.ui.skynet.handler, org.eclipse.osee.framework.ui.skynet.internal, + org.eclipse.osee.framework.ui.skynet.links, org.eclipse.osee.framework.ui.skynet.listener, org.eclipse.osee.framework.ui.skynet.menu, org.eclipse.osee.framework.ui.skynet.mergeWizard, diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/images/link.gif b/plugins/org.eclipse.osee.framework.ui.skynet/images/link.gif Binary files differnew file mode 100644 index 00000000000..5fd9c94946c --- /dev/null +++ b/plugins/org.eclipse.osee.framework.ui.skynet/images/link.gif diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/plugin.xml b/plugins/org.eclipse.osee.framework.ui.skynet/plugin.xml index 608751e3556..63af1ba1349 100644 --- a/plugins/org.eclipse.osee.framework.ui.skynet/plugin.xml +++ b/plugins/org.eclipse.osee.framework.ui.skynet/plugin.xml @@ -1470,6 +1470,9 @@ <XCommonNavigateItem classname="org.eclipse.osee.framework.ui.skynet.user.perspective.UserNavigateViewItems"> </XCommonNavigateItem> + <XCommonNavigateItem + classname="org.eclipse.osee.framework.ui.skynet.links.LinksNavigateViewItems"> + </XCommonNavigateItem> </extension> <extension point="org.eclipse.ui.perspectives"> diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/FrameworkImage.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/FrameworkImage.java index cc06eb44e78..91256d6a937 100644 --- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/FrameworkImage.java +++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/FrameworkImage.java @@ -120,6 +120,7 @@ public enum FrameworkImage implements KeyedImage { LEFT_ARROW_1("leftarrow1.png"), LEFT_ARROW_N("leftarrowN.png"), LINE_MATCH("line_match.gif"), + LINK("link.gif"), LOAD("load.gif"), LOCKED("lock.gif"), LOCK_LOCKED("lock_locked.gif"), diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/links/AddNewLinkNavigateItem.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/links/AddNewLinkNavigateItem.java new file mode 100644 index 00000000000..0d6ec4d8f9b --- /dev/null +++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/links/AddNewLinkNavigateItem.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2016 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.framework.ui.skynet.links; + +import org.eclipse.jface.window.Window; +import org.eclipse.osee.account.rest.model.Link; +import org.eclipse.osee.framework.ui.plugin.xnavigate.XNavigateComposite.TableLoadOption; +import org.eclipse.osee.framework.ui.plugin.xnavigate.XNavigateItem; +import org.eclipse.osee.framework.ui.skynet.FrameworkImage; + +/** + * @author Donald G. Dunne + */ +public class AddNewLinkNavigateItem extends XNavigateItem { + + public AddNewLinkNavigateItem(XNavigateItem parent) { + super(parent, "Add New Link", FrameworkImage.GREEN_PLUS); + } + + @Override + public void run(TableLoadOption... tableLoadOptions) throws Exception { + EditLinkDialog dialog = new EditLinkDialog(); + if (dialog.open() == Window.OK) { + Link link = new Link(); + LinkUtil.upateLinkFromDialog(dialog, link); + } + } + +} diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/links/EditLinkDialog.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/links/EditLinkDialog.java new file mode 100644 index 00000000000..7ef9966ca9e --- /dev/null +++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/links/EditLinkDialog.java @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright (c) 2016 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.framework.ui.skynet.links; + +import org.eclipse.osee.account.rest.model.Link; +import org.eclipse.osee.framework.jdk.core.util.Collections; +import org.eclipse.osee.framework.jdk.core.util.Strings; +import org.eclipse.osee.framework.ui.skynet.widgets.XText; +import org.eclipse.osee.framework.ui.skynet.widgets.dialog.EntryCheckDialog; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Listener; + +/** + * @author Donald G. Dunne + */ +public class EditLinkDialog extends EntryCheckDialog { + + private XText urlTextWidget, tagTextWidget; + private String nameText, urlText = "", tagText = ""; + private final String label2; + private Listener okListener; + private Link link; + + public EditLinkDialog(Link link) { + this(); + this.link = link; + urlText = link.getUrl(); + tagText = Collections.toString(", ", link.getTags()); + nameText = link.getName(); + setEntry(nameText); + } + + public EditLinkDialog() { + super("Enter Link", "Create/Update New Link", "Share with others"); + super.setLabel("Link Name"); + super.setTextHeight(100); + this.label2 = "URL"; + } + + @Override + protected void createExtendedArea(Composite parent) { + text.getLabelWidget().addMouseListener(new MouseAdapter() { + + @Override + public void mouseUp(MouseEvent e) { + if (e.button == 3) { + text.setText("Google"); + urlTextWidget.setText("http://www.google.com"); + tagTextWidget.setText("Search"); + } + } + + }); + + urlTextWidget = new XText(label2); + urlTextWidget.setFillHorizontally(true); + if (isFillVertically()) { + urlTextWidget.setFillVertically(true); + urlTextWidget.setHeight(100); + text.setHeight(100); + urlTextWidget.setFont(getFont()); + } + urlTextWidget.set(urlText); + urlTextWidget.createWidgets(parent, 1); + + urlTextWidget.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + handleModified(); + urlText = urlTextWidget.get(); + } + }); + + tagTextWidget = new XText("Enter Search Tags"); + tagTextWidget.setFillHorizontally(true); + if (isFillVertically()) { + tagTextWidget.setFillVertically(true); + tagTextWidget.setHeight(100); + text.setHeight(100); + tagTextWidget.setFont(getFont()); + } + tagTextWidget.set(tagText); + tagTextWidget.createWidgets(parent, 1); + + tagTextWidget.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + handleModified(); + tagText = tagTextWidget.get(); + } + }); + + super.createExtendedArea(parent); + } + + public String getUrl() { + return urlText; + } + + public String getTags() { + return tagText; + } + + public void setUrl(String url) { + if (urlTextWidget != null) { + urlTextWidget.set(url); + } + this.urlText = url; + } + + public void setTags(String tags) { + if (urlTextWidget != null) { + urlTextWidget.set(tags); + } + this.urlText = tags; + } + + public void setOkListener(Listener okListener) { + this.okListener = okListener; + } + + @Override + protected void buttonPressed(int buttonId) { + super.buttonPressed(buttonId); + if (buttonId == 0 && okListener != null) { + okListener.handleEvent(null); + } + } + + @Override + public boolean isEntryValid() { + if (!super.isEntryValid()) { + return false; + } + if (!Strings.isValid(getEntry())) { + setErrorString("Enter Link Name"); + return false; + } + if (!Strings.isValid(getUrl())) { + setErrorString("Must Enter URL"); + return false; + } + return true; + } + + @Override + protected Control createButtonBar(Composite parent) { + Control control = super.createButtonBar(parent); + handleModified(); + return control; + } + + public Link getLink() { + return link; + } + + public void setLink(Link link) { + this.link = link; + } + +} diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/links/EditLinksNavigateItem.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/links/EditLinksNavigateItem.java new file mode 100644 index 00000000000..7241d87d07c --- /dev/null +++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/links/EditLinksNavigateItem.java @@ -0,0 +1,175 @@ +/******************************************************************************* + * Copyright (c) 2016 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.framework.ui.skynet.links; + +import java.io.File; +import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.nio.file.StandardWatchEventKinds; +import java.nio.file.WatchEvent; +import java.nio.file.WatchKey; +import java.nio.file.WatchService; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.Level; +import org.codehaus.jackson.map.ObjectMapper; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.osee.account.rest.model.AccountWebPreferences; +import org.eclipse.osee.account.rest.model.Link; +import org.eclipse.osee.framework.jdk.core.util.Conditions; +import org.eclipse.osee.framework.jdk.core.util.Lib; +import org.eclipse.osee.framework.logging.OseeLog; +import org.eclipse.osee.framework.plugin.core.util.Jobs; +import org.eclipse.osee.framework.skynet.core.UserManager; +import org.eclipse.osee.framework.skynet.core.artifact.Artifact; +import org.eclipse.osee.framework.ui.plugin.xnavigate.XNavigateComposite.TableLoadOption; +import org.eclipse.osee.framework.ui.plugin.xnavigate.XNavigateItem; +import org.eclipse.osee.framework.ui.skynet.FrameworkImage; +import org.eclipse.osee.framework.ui.skynet.internal.Activator; +import org.eclipse.swt.program.Program; + +/** + * @author Donald G. Dunne + */ +public class EditLinksNavigateItem extends XNavigateItem implements FileChangedListener { + + private static String LINKS_FILENAME = "OSSE_%s_Links.txt"; + private static final List<FileChangedListener> listeners = new LinkedList<>(); + private final boolean global; + private boolean addedListener = false; + + public EditLinksNavigateItem(XNavigateItem parent, boolean global) { + super(parent, "Edit " + (global ? "Global" : "Personal") + " Links", FrameworkImage.EDIT); + this.global = global; + } + + @Override + public void run(TableLoadOption... tableLoadOptions) throws Exception { + AccountWebPreferences webPrefs = + LinkUtil.getAccountsPreferencesData(LinkUtil.getStoreArtifact(global).getArtId()); + + StringBuilder sb = new StringBuilder( + "OSEE " + (global ? "Global" : "Personal") + " Links " + UserManager.getUser().toStringWithId() + "\n\n"); + sb.append("// Move items up and down to change order.\n// Change names, urls and tags without changing id.\n// " // + + "Delete line to remove.\n// Copy existing link and clear id for new link.\n// Save to Update\n" // + + "// Example: {\"name\":\"Google\",\"url\":\"http://www.google.com\",\"id\":\"AOd9poc8Kz02K3K7xfwA\",\"team\":\"Joe Smith\",\"tags\":[]}\n\n"); + ObjectMapper mapper = new ObjectMapper(); + for (Link link : webPrefs.getLinks().values()) { + sb.append(mapper.writeValueAsString(link) + "\n"); + } + File outFile = getLinksFile(); + Lib.writeStringToFile(sb.toString(), outFile); + Program.launch(outFile.getAbsolutePath()); + + if (!addedListener) { + listeners.add(this); + addedListener = true; + } + startFileWatcher(); + } + + private File getLinksFile() { + File outFile = new File(System.getProperty("user.home") + "/" + getFilename(global)); + return outFile; + } + + private String getFilename(boolean global) { + return String.format(LINKS_FILENAME, (global ? "Global" : "Personal")); + } + + private static final AtomicBoolean startedWatcher = new AtomicBoolean(false); + + private static void startFileWatcher() { + if (startedWatcher.get()) { + return; + } + startedWatcher.set(true); + + Job job = new Job("Links File Watcher") { + + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + final Path dir = new File(System.getProperty("user.home")).toPath(); + final WatchService watcher = FileSystems.getDefault().newWatchService(); + + WatchKey key = dir.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY); + for (;;) { + + // pend for change to the home directory + try { + key = watcher.take(); + } catch (InterruptedException ex) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, ex.getLocalizedMessage(), ex); + } + + for (WatchEvent<?> event : key.pollEvents()) { + + @SuppressWarnings("unchecked") + WatchEvent<Path> ev = (WatchEvent<Path>) event; + Path filename = ev.context(); + + for (FileChangedListener listener : listeners) { + listener.fileChanged(filename.toString()); + } + } + + // Reset the key + boolean valid = key.reset(); + if (!valid) { + break; + } + } + return Status.OK_STATUS; + } catch (IOException ex) { + OseeLog.log(EditLinksNavigateItem.class, Level.SEVERE, ex); + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, ex.getLocalizedMessage(), ex); + } + } + }; + Jobs.startJob(job); + } + + @Override + public void fileChanged(String filename) { + if (filename.endsWith(getFilename(global))) { + System.err.println("file changed: " + getFilename(global)); + storeChangeAndContinue(); + } + } + + private void storeChangeAndContinue() { + try { + File outFile = getLinksFile(); + String fileToString = Lib.fileToString(outFile); + ObjectMapper mapper = new ObjectMapper(); + AccountWebPreferences newWebPrefs = new AccountWebPreferences(); + for (String line : fileToString.split("\n")) { + if (line.startsWith("{")) { + Link link = mapper.readValue(line, Link.class); + newWebPrefs.getLinks().put(link.getId(), link); + } + } + Artifact useArtifact = LinkUtil.getStoreArtifact(global); + Conditions.checkNotNull(useArtifact, + "Could not find " + (global ? "Global" : "Personal") + " store artifact."); + LinkUtil.saveWebPreferences(newWebPrefs, global, useArtifact); + } catch (Exception ex) { + OseeLog.log(EditLinksNavigateItem.class, Level.SEVERE, ex); + } + } + +} diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/links/FileChangedListener.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/links/FileChangedListener.java new file mode 100644 index 00000000000..035c339c23c --- /dev/null +++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/links/FileChangedListener.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2016 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.framework.ui.skynet.links; + +/** + * @author Donald G. Dunne + */ +public interface FileChangedListener { + public void fileChanged(String filename); +} diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/links/LinkUtil.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/links/LinkUtil.java new file mode 100644 index 00000000000..974817bea6d --- /dev/null +++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/links/LinkUtil.java @@ -0,0 +1,196 @@ +/******************************************************************************* + * Copyright (c) 2016 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.framework.ui.skynet.links; + +import java.util.Map; +import java.util.Map.Entry; +import org.codehaus.jackson.map.ObjectMapper; +import org.eclipse.osee.account.rest.client.AccountClient; +import org.eclipse.osee.account.rest.model.AccountWebPreferences; +import org.eclipse.osee.account.rest.model.Link; +import org.eclipse.osee.framework.core.enums.CoreAttributeTypes; +import org.eclipse.osee.framework.core.enums.CoreBranches; +import org.eclipse.osee.framework.core.enums.SystemUser; +import org.eclipse.osee.framework.core.event.EventType; +import org.eclipse.osee.framework.jdk.core.util.Collections; +import org.eclipse.osee.framework.jdk.core.util.Conditions; +import org.eclipse.osee.framework.jdk.core.util.GUID; +import org.eclipse.osee.framework.skynet.core.User; +import org.eclipse.osee.framework.skynet.core.UserManager; +import org.eclipse.osee.framework.skynet.core.artifact.Artifact; +import org.eclipse.osee.framework.skynet.core.artifact.search.ArtifactQuery; +import org.eclipse.osee.framework.skynet.core.event.OseeEventManager; +import org.eclipse.osee.framework.skynet.core.event.model.TopicEvent; +import org.eclipse.osee.framework.ui.skynet.internal.ServiceUtil; +import org.eclipse.osee.framework.ui.skynet.util.FrameworkEvents; + +/** + * @author Donald G. Dunne + */ +public class LinkUtil { + + private LinkUtil() { + // Utility class + } + + public static AccountWebPreferences getAccountsPreferencesData(boolean global) throws Exception { + return getAccountsPreferencesData(getStoreArtifact(global).getArtId()); + } + + public static AccountWebPreferences getAccountsPreferencesData(int accountId) throws Exception { + AccountClient client = ServiceUtil.getAccountClient(); + return client.getAccountWebPreferencesByUniqueField(Long.valueOf(accountId)); + } + + /** + * Delete single link from user or global links and store + */ + public static void deleteLink(String accountId, Link deleteLink) throws Exception { + Artifact golbalArtifact = getStoreArtifact(true); + Conditions.checkNotNull(golbalArtifact, "Guest accountId: " + SystemUser.Anonymous.getUuid()); + deleteLink(deleteLink, true, golbalArtifact); + + Artifact userArt = ArtifactQuery.getArtifactFromId(new Integer(accountId), CoreBranches.COMMON); + Conditions.checkNotNull(userArt, "User Artifact accountId: " + accountId); + deleteLink(deleteLink, false, userArt); + } + + public static void deleteLink(Link deleteLink, boolean global) throws Exception { + deleteLink(deleteLink, global, getStoreArtifact(global)); + } + + public static void deleteLink(Link deleteLink, boolean global, Artifact useArtifact) throws Exception { + String webPrefStr = useArtifact.getSoleAttributeValue(CoreAttributeTypes.WebPreferences, "{}"); + AccountWebPreferences webPrefs = new AccountWebPreferences(webPrefStr, useArtifact.getName()); + Link remove = webPrefs.getLinks().remove(deleteLink.getId()); + if (remove != null) { + saveWebPrefsToArtifactAndKickEvent(global, useArtifact, webPrefs); + } + } + + public static void addUpdateLink(Link link, boolean global) throws Exception { + addUpdateLink(getStoreArtifact(global).getArtId(), link, global); + } + + /** + * Update existing link in shared/global web preferences and store + */ + public static void addUpdateLink(int accountId, Link link, boolean global) throws Exception { + Artifact useArtifact = getStoreArtifact(global); + Conditions.checkNotNull(useArtifact, "Could not find store artifact for accountId: " + accountId); + + String webPrefStr = useArtifact.getSoleAttributeValue(CoreAttributeTypes.WebPreferences, null); + if (webPrefStr != null) { + AccountWebPreferences webPrefs = new AccountWebPreferences(webPrefStr, useArtifact.getName()); + boolean found = false; + for (Entry<String, Link> stored : webPrefs.getLinks().entrySet()) { + if (stored.getKey().equals(link.getId())) { + setLinkFromLink(link, stored.getValue()); + found = true; + break; + } + } + if (!found) { + webPrefs.getLinks().put(link.getId(), link); + } + saveWebPrefsToArtifactAndKickEvent(global, useArtifact, webPrefs); + } + } + + public static Artifact getStoreArtifact(boolean global) { + if (global) { + return ArtifactQuery.getArtifactFromId(SystemUser.Anonymous.getUuid(), CoreBranches.COMMON); + } + return LinkUtil.getPersonalLinksArtifact(); + } + + public static void saveWebPreferences(AccountWebPreferences webPrefs, boolean global) throws Exception { + saveWebPreferences(webPrefs, global, getStoreArtifact(global)); + } + + public static void saveWebPreferences(AccountWebPreferences webPrefs, boolean global, Artifact useArtifact) throws Exception { + saveWebPrefsToArtifactAndKickEvent(global, useArtifact, webPrefs); + } + + public static boolean setLinkFromLink(Link fromLink, Link toLink) { + boolean changed = false; + if (!toLink.getName().equals(fromLink.getName())) { + toLink.setName(fromLink.getName()); + changed = true; + } + if (!Collections.isEqual(fromLink.getTags(), toLink.getTags())) { + toLink.setTags(fromLink.getTags()); + changed = true; + } + if (!toLink.getTeam().equals(fromLink.getTeam())) { + toLink.setTeam(fromLink.getTeam()); + changed = true; + } + if (!toLink.getUrl().equals(fromLink.getUrl())) { + toLink.setUrl(fromLink.getUrl()); + changed = true; + } + return changed; + } + + private static void saveWebPrefsToArtifactAndKickEvent(boolean global, Artifact useArtifact, AccountWebPreferences webPrefs) throws Exception { + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(webPrefs); + useArtifact.setSoleAttributeValue(CoreAttributeTypes.WebPreferences, json); + useArtifact.persist("Add web preferences links to " + useArtifact.toStringWithId()); + + TopicEvent event = + new TopicEvent((global ? FrameworkEvents.GLOBAL_WEB_PREFERENCES : FrameworkEvents.PERSONAL_WEB_PREFERENCES), + "links", webPrefs.getLinks().toString(), (global ? EventType.LocalAndRemote : EventType.LocalOnly)); + OseeEventManager.kickTopicEvent(LinkUtil.class, event); + } + + public static Link getExistingLink(Link link, AccountWebPreferences webPrefs) { + return getExistingLink(link, webPrefs.getLinks()); + } + + public static Link getExistingLink(Link link, Map<String, Link> links) { + for (Link existingLink : links.values()) { + if (existingLink.getId().equals(link.getId())) { + return existingLink; + } + } + return null; + } + + public static void upateLinkFromDialog(EditLinkDialog dialog, Link link) throws Exception { + link.setName(dialog.getEntry()); + link.setUrl(dialog.getUrl()); + boolean global = dialog.isChecked(); + for (String tag : dialog.getTags().split(",")) { + tag = tag.replaceAll(" ", ""); + link.getTags().add(tag); + } + int accountId = 0; + if (link.getId() == null) { + link.setId(GUID.create()); + } + if (global) { + accountId = SystemUser.Anonymous.getUuid().intValue(); + link.setTeam("Guest"); + } else { + User user = UserManager.getUser(); + accountId = user.getUuid().intValue(); + link.setTeam(user.getName()); + } + LinkUtil.addUpdateLink(accountId, link, global); + } + + public static Artifact getPersonalLinksArtifact() { + return ArtifactQuery.getArtifactFromId(UserManager.getUser().getArtId(), CoreBranches.COMMON); + } + +} diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/links/LinksNavigateViewItems.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/links/LinksNavigateViewItems.java new file mode 100644 index 00000000000..8601c45c64e --- /dev/null +++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/links/LinksNavigateViewItems.java @@ -0,0 +1,246 @@ +/******************************************************************************* + * Copyright (c) 2016 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.framework.ui.skynet.links; + +import java.net.URL; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.logging.Level; +import org.eclipse.jface.window.Window; +import org.eclipse.osee.account.rest.model.AccountWebPreferences; +import org.eclipse.osee.account.rest.model.Link; +import org.eclipse.osee.framework.jdk.core.type.OseeCoreException; +import org.eclipse.osee.framework.jdk.core.util.Collections; +import org.eclipse.osee.framework.logging.OseeLevel; +import org.eclipse.osee.framework.logging.OseeLog; +import org.eclipse.osee.framework.skynet.core.UserManager; +import org.eclipse.osee.framework.ui.plugin.xnavigate.IXNavigateCommonItem; +import org.eclipse.osee.framework.ui.plugin.xnavigate.IXNavigateMenuItem; +import org.eclipse.osee.framework.ui.plugin.xnavigate.XNavigateCommonItems; +import org.eclipse.osee.framework.ui.plugin.xnavigate.XNavigateItem; +import org.eclipse.osee.framework.ui.plugin.xnavigate.XNavigateUrlItem; +import org.eclipse.osee.framework.ui.plugin.xnavigate.XNavigateViewItems; +import org.eclipse.osee.framework.ui.skynet.FrameworkImage; +import org.eclipse.osee.framework.ui.skynet.internal.Activator; +import org.eclipse.osee.framework.ui.skynet.util.DbConnectionUtility; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.browser.IWebBrowser; +import org.eclipse.ui.browser.IWorkbenchBrowserSupport; + +/** + * @author Donald G. Dunne + */ +public class LinksNavigateViewItems implements XNavigateViewItems, IXNavigateCommonItem { + + private final static LinksNavigateViewItems instance = new LinksNavigateViewItems(); + public static final long TOP_LINK_ID = 4561556789L; + private final List<XNavigateItem> items = new CopyOnWriteArrayList<>(); + private boolean ensurePopulatedRanOnce = false; + + public static LinksNavigateViewItems getInstance() { + return instance; + } + + @Override + public List<XNavigateItem> getSearchNavigateItems() { + ensurePopulated(); + return items; + } + + private synchronized void ensurePopulated() { + if (!ensurePopulatedRanOnce) { + if (DbConnectionUtility.areOSEEServicesAvailable().isFalse()) { + return; + } + this.ensurePopulatedRanOnce = true; + + try { + addOseeLinksSectionChildren(null, items); + + XNavigateCommonItems.addCommonNavigateItems(items, Arrays.asList(getSectionId())); + } catch (OseeCoreException ex) { + OseeLog.log(Activator.class, Level.SEVERE, ex); + } + } + } + + public static void addOseeLinksSectionChildren(XNavigateItem parentItem, List<XNavigateItem> resultItems) throws OseeCoreException { + new AddNewLinkNavigateItem(parentItem); + new EditLinksNavigateItem(parentItem, false); + new EditLinksNavigateItem(parentItem, true); + try { + AccountWebPreferences data = LinkUtil.getAccountsPreferencesData(false); + for (Link link : data.getLinks().values()) { + XNavigateUrlItem urlItem = new XNavigateUrlItem(parentItem, link.getName() + getTagsStr(link, false), + link.getUrl(), true, FrameworkImage.LINK); + urlItem.addMenuItem(editListener); + urlItem.setData(link); + resultItems.add(urlItem); + } + + data = LinkUtil.getAccountsPreferencesData(true); + for (Link link : data.getLinks().values()) { + XNavigateUrlItem urlItem = new XNavigateUrlItem(parentItem, link.getName() + getTagsStr(link, true), + link.getUrl(), true, FrameworkImage.LINK); + urlItem.setData(link); + urlItem.addMenuItem(editListener); + resultItems.add(urlItem); + } + } catch (Exception ex) { + OseeLog.log(Activator.class, Level.SEVERE, ex); + } + } + + private static final IXNavigateMenuItem editListener = new IXNavigateMenuItem() { + + @Override + public void addMenuItems(final Menu menu, final TreeItem selectedTreeItem) { + if (((XNavigateUrlItem) selectedTreeItem.getData()).getData() instanceof Link) { + openExternallyMenuItem(menu, selectedTreeItem); + openInternallyMenuItem(menu, selectedTreeItem); + new MenuItem(menu, SWT.SEPARATOR); + addEditMenuItem(menu, selectedTreeItem); + addDeleteMenuItem(menu, selectedTreeItem); + } + } + + private void openExternallyMenuItem(final Menu menu, final TreeItem selectedTreeItem) { + final XNavigateItem navItem = (XNavigateItem) selectedTreeItem.getData(); + final Link link = (Link) navItem.getData(); + MenuItem menuItem = new MenuItem(menu, SWT.PUSH); + menuItem.setText(String.format("Open Externally")); + menuItem.setToolTipText(link.getUrl()); + menuItem.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + super.widgetSelected(e); + Program.launch(((Link) navItem.getData()).getUrl()); + } + }); + } + + private void openInternallyMenuItem(final Menu menu, final TreeItem selectedTreeItem) { + final XNavigateItem navItem = (XNavigateItem) selectedTreeItem.getData(); + final Link link = (Link) navItem.getData(); + MenuItem menuItem = new MenuItem(menu, SWT.PUSH); + menuItem.setText(String.format("Open Internally")); + menuItem.setToolTipText(link.getUrl()); + menuItem.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + super.widgetSelected(e); + IWorkbenchBrowserSupport browserSupport = PlatformUI.getWorkbench().getBrowserSupport(); + try { + IWebBrowser browser = + browserSupport.createBrowser(SWT.None, "osee.links." + link.getId(), link.getName(), ""); + browser.openURL(new URL(link.getUrl())); + } catch (Exception ex) { + OseeLog.log(LinksNavigateViewItems.class, OseeLevel.SEVERE_POPUP, ex); + } + } + }); + } + + private void addEditMenuItem(final Menu menu, final TreeItem selectedTreeItem) { + final XNavigateItem navItem = (XNavigateItem) selectedTreeItem.getData(); + Link link = (Link) navItem.getData(); + if (link != null) { + MenuItem menuItem = new MenuItem(menu, SWT.PUSH); + menuItem.setText(String.format("Edit [%s]", link.getName())); + menuItem.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + super.widgetSelected(e); + handleEditMenuItemSelected(navItem, selectedTreeItem); + } + }); + } + } + + private void addDeleteMenuItem(final Menu menu, final TreeItem selectedTreeItem) { + final XNavigateItem navItem = (XNavigateItem) selectedTreeItem.getData(); + Link link = (Link) navItem.getData(); + if (link != null) { + MenuItem menuItem = new MenuItem(menu, SWT.PUSH); + menuItem.setText(String.format("Delete [%s]", link.getName())); + menuItem.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + super.widgetSelected(e); + try { + LinkUtil.deleteLink(String.valueOf(UserManager.getUser().getArtId()), link); + } catch (Exception ex) { + OseeLog.log(LinksNavigateViewItems.class, OseeLevel.SEVERE_POPUP, ex); + } + } + }); + } + } + + public void handleEditMenuItemSelected(XNavigateItem urlItem, TreeItem selectedTreeItem) { + Link link = (Link) urlItem.getData(); + if (link != null) { + EditLinkDialog dialog = new EditLinkDialog(link); + if (dialog.open() == Window.OK) { + try { + LinkUtil.upateLinkFromDialog(dialog, link); + } catch (Exception ex) { + OseeLog.log(LinksNavigateViewItems.class, OseeLevel.SEVERE_POPUP, ex); + } + } + } + } + + }; + + private static String getTagsStr(Link link, boolean global) { + if (!link.getTags().isEmpty()) { + return " (" + Collections.toString(", ", link.getTags()) + (global ? ", global" : "") + ")"; + } + return ""; + } + + @Override + public void createCommonSection(List<XNavigateItem> items, List<String> excludeSectionIds) { + try { + XNavigateItem linkItem = new XNavigateItem(null, "Links", FrameworkImage.LINK); + linkItem.setId(TOP_LINK_ID); + addOseeLinksSectionChildren(linkItem, new LinkedList<>()); + items.add(linkItem); + } catch (OseeCoreException ex) { + OseeLog.log(Activator.class, Level.SEVERE, "Can't create OSEE Links section", ex); + } + } + + @Override + public String getSectionId() { + return "Links"; + } + + public static void reloadLinks(XNavigateItem linkItem) { + linkItem.getChildren().clear(); + addOseeLinksSectionChildren(linkItem, new LinkedList<>()); + } + +} diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/util/FrameworkEvents.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/util/FrameworkEvents.java new file mode 100644 index 00000000000..9f8e716abdc --- /dev/null +++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/util/FrameworkEvents.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2016 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.framework.ui.skynet.util; + +/** + * @author Donald G. Dunne + */ +public class FrameworkEvents { + + public static final String PERSONAL_WEB_PREFERENCES = "framework/web/prefs/modified/links/personal"; + public static final String GLOBAL_WEB_PREFERENCES = "framework/web/prefs/modified/links/global"; + public static final String FRAMEWORK_LINK_EDIT = "framework/link/edit"; + + private FrameworkEvents() { + // utility class + } + +} diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/dialog/EntryCheckDialog.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/dialog/EntryCheckDialog.java index d22a4772431..6fbc1a2e97f 100644 --- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/dialog/EntryCheckDialog.java +++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/dialog/EntryCheckDialog.java @@ -45,7 +45,7 @@ public class EntryCheckDialog extends EntryDialog { text.setFocus(); text.setDisplayLabel(false); text.set(checked); - text.createWidgets(parent, 2); + text.createWidgets(parent, 1); SelectionListener selectionListener = new SelectionAdapter() { |