Skip to content
This repository

[Taxonomy] Allow plug-ins to introduce bootstrap components #208

Merged
merged 13 commits into from 9 months ago

1 participant

VWoeltjen
VWoeltjen
Collaborator

This pull request allows plugins to introduce their own bootstrap components (top-level components that show up inthe user environment.) Previously, this was not feasible for reasons identified in nasa/mct#207

Changes are:

  • Add "getBootstrapComponents" to ComponentProvider API. Plugins may use this method to expose top-level components to the system.
  • Add Bootstrap capability. Component types may expose this capability to control how and in what order they appear as bootstrap components. (Top-level components which do not implement this capability are still handled, albeit with a lesser degree of support for handling their sorting.)

    Wrote or re-wrote unit tests (Y/N): Y
    Ran entire suite of unit tests successfully (Y/N): Y
    Verified bug fix with the described replication steps or verified the implementation meets the requirement cited (Y/N): Y
    Code coverage requirements satisfied (new code=80%, changed code=at least as high as existing) (Y/N): Y
    Code review date and attendees: Self-review (team size = 1)
    Describe potential impact on other areas of the code: Component bootstrapping
    Describe any test prerequisites for this fix (e.g., restart the database): Run with plugin that injects its own bootstrap components
    For bugs marked "Regression - Yes", describe the cause of the regression: N/A
    Did you modify any pom.xml file? If yes, did you thoroughly document your changes and reasons? N

VWoeltjen added some commits
VWoeltjen VWoeltjen [Taxonomy] Add API for plugin-introduced bootstraps
Issue nasa/mct#207 describes the need
for allowing third-party plug-ins to
introduce their own bootstrap components.
This adds appropriate method signatures
to plug-in API to facilitate this. This
does not include any implementation for
the usage of this API.
d2f0de8
VWoeltjen VWoeltjen [Taxonomy] Use plugin bootstrap API
When bundles are refreshed, aggregate all
bootstrap components exposed by plugins,
filter out any which have been previously
written to the database, and persist.
d585682
VWoeltjen VWoeltjen [Taxonomy] Add Bootstrap capability definition
Adds a Bootstrap capability which
bootstrap components may support in
order to provide additional information,
such as ordering, related to such
components.
c508ada
VWoeltjen VWoeltjen [Taxonomy] Use Bootstrap capability
Use the Bootstrap capability to determine
if a component should appear as a global
or creator-specific bootstrap component,
when tagging bootstrap components exposed
by plugins.
c52e109
VWoeltjen VWoeltjen [Taxonomy] Use capability to find My Sandbox d2c0544
VWoeltjen VWoeltjen [Taxonomy] Sort bootstrap components e703693
VWoeltjen VWoeltjen [Taxonomy] Updated version requirements
Updated package versions required in
bundles to reflect increment in
package version due to introduction
of Bootstrap capability.
ec6c660
VWoeltjen VWoeltjen [Taxonomy] Support Bootstrap capability in Sandbox
Add Bootstrap capability to My Sandbox.
This identifies the sandbox as the
default destination for new components
to the platform, and provides indexing
information to ensure that My Sandbox
always appears at the last position
in the User Environment.
85c2069
VWoeltjen VWoeltjen [Taxonomy] Support Bootstrap capability in taxonomy comp
Add Bootstrap capability to
TelemetryDataTaxonomyComponent. These
are not always bootstraps, but when they
are bootstraps, they should be located
shortly before My Sandbox.
79e5173
VWoeltjen VWoeltjen [Taxonomy] Change comment to satisfy checkstyle 18bfd6e
VWoeltjen VWoeltjen [Taxonomy] Test bootstrap components b959bbc
VWoeltjen VWoeltjen [Taxonomy] Test bootstrap comparator c816be7
VWoeltjen VWoeltjen [Taxonomy] Test changes to registry
Verify that the external component registry
does probe plugins for bootstrap components,
and does deliver these components to
persistence.
c425bf0
VWoeltjen VWoeltjen merged commit f572c91 into from
VWoeltjen VWoeltjen referenced this pull request in nasa/MCT-Plugins
Closed

[Scenario] Allow activities to be tagged #39

VWoeltjen VWoeltjen referenced this pull request from a commit in VWoeltjen/MCT-Plugins
VWoeltjen VWoeltjen [Scenario] Move bootstrap components to provider
Move the introduction of the Scenario
plugin's bootstrap (top-level) components
from the Activator to the Provider in
order to utilize the new platform support
for this behavior provided by
nasa/mct#208
c177e0a
VWoeltjen VWoeltjen referenced this pull request in nasa/MCT-Plugins
Merged

[Scenario] Tag objects and tag repositories #87

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 13 unique commits by 1 author.

Oct 04, 2013
VWoeltjen VWoeltjen [Taxonomy] Add API for plugin-introduced bootstraps
Issue nasa/mct#207 describes the need
for allowing third-party plug-ins to
introduce their own bootstrap components.
This adds appropriate method signatures
to plug-in API to facilitate this. This
does not include any implementation for
the usage of this API.
d2f0de8
VWoeltjen VWoeltjen [Taxonomy] Use plugin bootstrap API
When bundles are refreshed, aggregate all
bootstrap components exposed by plugins,
filter out any which have been previously
written to the database, and persist.
d585682
VWoeltjen VWoeltjen [Taxonomy] Add Bootstrap capability definition
Adds a Bootstrap capability which
bootstrap components may support in
order to provide additional information,
such as ordering, related to such
components.
c508ada
VWoeltjen VWoeltjen [Taxonomy] Use Bootstrap capability
Use the Bootstrap capability to determine
if a component should appear as a global
or creator-specific bootstrap component,
when tagging bootstrap components exposed
by plugins.
c52e109
VWoeltjen VWoeltjen [Taxonomy] Use capability to find My Sandbox d2c0544
VWoeltjen VWoeltjen [Taxonomy] Sort bootstrap components e703693
VWoeltjen VWoeltjen [Taxonomy] Updated version requirements
Updated package versions required in
bundles to reflect increment in
package version due to introduction
of Bootstrap capability.
ec6c660
VWoeltjen VWoeltjen [Taxonomy] Support Bootstrap capability in Sandbox
Add Bootstrap capability to My Sandbox.
This identifies the sandbox as the
default destination for new components
to the platform, and provides indexing
information to ensure that My Sandbox
always appears at the last position
in the User Environment.
85c2069
VWoeltjen VWoeltjen [Taxonomy] Support Bootstrap capability in taxonomy comp
Add Bootstrap capability to
TelemetryDataTaxonomyComponent. These
are not always bootstraps, but when they
are bootstraps, they should be located
shortly before My Sandbox.
79e5173
VWoeltjen VWoeltjen [Taxonomy] Change comment to satisfy checkstyle 18bfd6e
VWoeltjen VWoeltjen [Taxonomy] Test bootstrap components b959bbc
VWoeltjen VWoeltjen [Taxonomy] Test bootstrap comparator c816be7
VWoeltjen VWoeltjen [Taxonomy] Test changes to registry
Verify that the external component registry
does probe plugins for bootstrap components,
and does deliver these components to
persistence.
c425bf0
This page is out of date. Refresh to see the latest.

Showing 14 changed files with 600 additions and 24 deletions. Show diff stats Hide diff stats

  1. +3 3 mctCoreTaxonomyProvider/META-INF/MANIFEST.MF
  2. +30 3 mctCoreTaxonomyProvider/src/main/java/gov/nasa/arc/mct/core/components/MineTaxonomyComponent.java
  3. +31 2 mctCoreTaxonomyProvider/src/main/java/gov/nasa/arc/mct/core/components/TelemetryDataTaxonomyComponent.java
  4. +51 0 mctCoreTaxonomyProvider/src/test/java/gov/nasa/arc/mct/core/components/MineTaxonomyComponentTest.java
  5. +53 0 mctCoreTaxonomyProvider/src/test/java/gov/nasa/arc/mct/core/components/TelemetryDataTaxonomyComponentTest.java
  6. +2 2 mctcore/META-INF/MANIFEST.MF
  7. +120 0 mctcore/src/main/java/gov/nasa/arc/mct/components/Bootstrap.java
  8. +37 1 mctcore/src/main/java/gov/nasa/arc/mct/registry/ExternalComponentRegistryImpl.java
  9. +9 1 mctcore/src/main/java/gov/nasa/arc/mct/services/component/AbstractComponentProvider.java
  10. +26 1 mctcore/src/main/java/gov/nasa/arc/mct/services/component/ComponentProvider.java
  11. +158 0 mctcore/src/test/java/gov/nasa/arc/mct/components/BootstrapTest.java
  12. +65 0 mctcore/src/test/java/gov/nasa/arc/mct/registry/TestExternalComponentRegistryImpl.java
  13. +3 3 platform/META-INF/MANIFEST.MF
  14. +12 8 platform/src/main/java/gov/nasa/arc/mct/platform/PlatformImpl.java
6 mctCoreTaxonomyProvider/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
2 2 Bundle-ManifestVersion: 2
3 3 Bundle-Name: MctCoreTaxonomyProvider
4 4 Bundle-SymbolicName: mctCoreTaxonomyProvider
5   -Bundle-Version: 1.1.0
  5 +Bundle-Version: 1.1.2
6 6 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
7 7 Import-Package: gov.nasa.arc.mct.components;version="1.1.0",
8 8 gov.nasa.arc.mct.components.collection;version="1.1.0",
@@ -13,8 +13,8 @@ Import-Package: gov.nasa.arc.mct.components;version="1.1.0",
13 13 gov.nasa.arc.mct.policy;version="1.1.0",
14 14 gov.nasa.arc.mct.roles;version="1.1.0",
15 15 gov.nasa.arc.mct.roles.events;version="1.1.0",
16   - gov.nasa.arc.mct.services.component;version="1.1.0",
17   - gov.nasa.arc.mct.services.internal.component;version="1.1.0",
  16 + gov.nasa.arc.mct.services.component;version="1.1.2",
  17 + gov.nasa.arc.mct.services.internal.component;version="1.1.1",
18 18 gov.nasa.arc.mct.util;version="1.1.0",
19 19 org.osgi.framework;version="1.4.0"
20 20 Service-Component: OSGI-INF/service.xml
33 mctCoreTaxonomyProvider/src/main/java/gov/nasa/arc/mct/core/components/MineTaxonomyComponent.java
@@ -29,11 +29,38 @@
29 29 */
30 30 package gov.nasa.arc.mct.core.components;
31 31
32   -import gov.nasa.arc.mct.components.AbstractComponent;
  32 +import gov.nasa.arc.mct.components.AbstractComponent;
  33 +import gov.nasa.arc.mct.components.Bootstrap;
33 34
34   -public class MineTaxonomyComponent extends AbstractComponent {
  35 +public class MineTaxonomyComponent extends AbstractComponent implements Bootstrap {
35 36
36 37 public MineTaxonomyComponent() {
37   - }
  38 + }
  39 +
  40 + @Override
  41 + protected <T> T handleGetCapability(Class<T> capability) {
  42 + return capability.isAssignableFrom(getClass()) ?
  43 + capability.cast(this) : super.handleGetCapability(capability);
  44 + }
  45 +
  46 + @Override
  47 + public boolean isGlobal() {
  48 + return false;
  49 + }
  50 +
  51 + @Override
  52 + public boolean isSandbox() {
  53 + return true;
  54 + }
  55 +
  56 + @Override
  57 + public int categoryIndex() {
  58 + return Integer.MAX_VALUE; // Always should appear at bottom
  59 + }
  60 +
  61 + @Override
  62 + public int componentIndex() {
  63 + return Integer.MAX_VALUE; // Always should appear at bottom
  64 + }
38 65
39 66 }
33 mctCoreTaxonomyProvider/src/main/java/gov/nasa/arc/mct/core/components/TelemetryDataTaxonomyComponent.java
@@ -29,9 +29,10 @@
29 29 */
30 30 package gov.nasa.arc.mct.core.components;
31 31
32   -import gov.nasa.arc.mct.components.AbstractComponent;
  32 +import gov.nasa.arc.mct.components.AbstractComponent;
  33 +import gov.nasa.arc.mct.components.Bootstrap;
33 34
34   -public class TelemetryDataTaxonomyComponent extends AbstractComponent {
  35 +public class TelemetryDataTaxonomyComponent extends AbstractComponent implements Bootstrap {
35 36 public TelemetryDataTaxonomyComponent() {
36 37 }
37 38
@@ -43,5 +44,33 @@ public TelemetryDataTaxonomyComponent() {
43 44 */
44 45 public TelemetryDataTaxonomyComponent(String id) {
45 46 setId(id);
  47 + }
  48 +
  49 + @Override
  50 + protected <T> T handleGetCapability(Class<T> capability) {
  51 + return capability.isAssignableFrom(getClass()) ?
  52 + capability.cast(this) : super.handleGetCapability(capability);
  53 + }
  54 +
  55 + @Override
  56 + public boolean isGlobal() {
  57 + return true;
  58 + }
  59 +
  60 + @Override
  61 + public boolean isSandbox() {
  62 + return false;
  63 + }
  64 +
  65 + @Override
  66 + public int categoryIndex() {
  67 + return Integer.MAX_VALUE; // Always should appear at bottom
  68 + }
  69 +
  70 + @Override
  71 + public int componentIndex() {
  72 + // "Somewhere in the middle"
  73 + // Use Component Id's hash code to keep position consistent.
  74 + return getComponentId().hashCode() & 0xFFFF;
46 75 }
47 76 }
51 mctCoreTaxonomyProvider/src/test/java/gov/nasa/arc/mct/core/components/MineTaxonomyComponentTest.java
... ... @@ -0,0 +1,51 @@
  1 +/*******************************************************************************
  2 + * Mission Control Technologies, Copyright (c) 2009-2012, United States Government
  3 + * as represented by the Administrator of the National Aeronautics and Space
  4 + * Administration. All rights reserved.
  5 + *
  6 + * The MCT platform is licensed under the Apache License, Version 2.0 (the
  7 + * "License"); you may not use this file except in compliance with the License.
  8 + * You may obtain a copy of the License at
  9 + * http://www.apache.org/licenses/LICENSE-2.0.
  10 + *
  11 + * Unless required by applicable law or agreed to in writing, software
  12 + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  13 + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  14 + * License for the specific language governing permissions and limitations under
  15 + * the License.
  16 + *
  17 + * MCT includes source code licensed under additional open source licenses. See
  18 + * the MCT Open Source Licenses file included with this distribution or the About
  19 + * MCT Licenses dialog available at runtime from the MCT Help menu for additional
  20 + * information.
  21 + *******************************************************************************/
  22 +package gov.nasa.arc.mct.core.components;
  23 +
  24 +import gov.nasa.arc.mct.components.Bootstrap;
  25 +
  26 +import org.testng.Assert;
  27 +import org.testng.annotations.Test;
  28 +
  29 +public class MineTaxonomyComponentTest {
  30 +
  31 + @Test
  32 + public void testBootstrap() {
  33 + // Test Bootstrap capability by getting one from the sandbox
  34 + MineTaxonomyComponent mySandbox = new MineTaxonomyComponent();
  35 + Bootstrap capability = mySandbox.getCapability(Bootstrap.class);
  36 +
  37 + // Should support the bootstrap capability
  38 + Assert.assertNotNull(capability);
  39 +
  40 + // Is a sandbox
  41 + Assert.assertTrue(capability.isSandbox());
  42 +
  43 + // Is not globally accessible (one per user)
  44 + Assert.assertFalse(capability.isGlobal());
  45 +
  46 + // Appears at the end of sorted list of bootstraps
  47 + Assert.assertEquals(capability.categoryIndex(), Integer.MAX_VALUE);
  48 + Assert.assertEquals(capability.componentIndex(), Integer.MAX_VALUE);
  49 + }
  50 +
  51 +}
53 ...eTaxonomyProvider/src/test/java/gov/nasa/arc/mct/core/components/TelemetryDataTaxonomyComponentTest.java
... ... @@ -0,0 +1,53 @@
  1 +/*******************************************************************************
  2 + * Mission Control Technologies, Copyright (c) 2009-2012, United States Government
  3 + * as represented by the Administrator of the National Aeronautics and Space
  4 + * Administration. All rights reserved.
  5 + *
  6 + * The MCT platform is licensed under the Apache License, Version 2.0 (the
  7 + * "License"); you may not use this file except in compliance with the License.
  8 + * You may obtain a copy of the License at
  9 + * http://www.apache.org/licenses/LICENSE-2.0.
  10 + *
  11 + * Unless required by applicable law or agreed to in writing, software
  12 + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  13 + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  14 + * License for the specific language governing permissions and limitations under
  15 + * the License.
  16 + *
  17 + * MCT includes source code licensed under additional open source licenses. See
  18 + * the MCT Open Source Licenses file included with this distribution or the About
  19 + * MCT Licenses dialog available at runtime from the MCT Help menu for additional
  20 + * information.
  21 + *******************************************************************************/
  22 +package gov.nasa.arc.mct.core.components;
  23 +
  24 +import gov.nasa.arc.mct.components.Bootstrap;
  25 +import gov.nasa.arc.mct.services.internal.component.ComponentInitializer;
  26 +
  27 +import org.testng.Assert;
  28 +import org.testng.annotations.Test;
  29 +
  30 +public class TelemetryDataTaxonomyComponentTest {
  31 +
  32 + @Test
  33 + public void testBootstrap() {
  34 + // Test Bootstrap capability by getting one from the sandbox
  35 + TelemetryDataTaxonomyComponent component = new TelemetryDataTaxonomyComponent();
  36 + component.getCapability(ComponentInitializer.class).setId("id");
  37 + Bootstrap capability = component.getCapability(Bootstrap.class);
  38 +
  39 + // Should support the bootstrap capability
  40 + Assert.assertNotNull(capability);
  41 +
  42 + // Is not a sandbox
  43 + Assert.assertFalse(capability.isSandbox());
  44 +
  45 + // Is globally accessible (for all users)
  46 + Assert.assertTrue(capability.isGlobal());
  47 +
  48 + // Appears near the bottom, but not at the bottom
  49 + Assert.assertEquals(capability.categoryIndex(), Integer.MAX_VALUE);
  50 + Assert.assertTrue(capability.componentIndex() < Integer.MAX_VALUE);
  51 + }
  52 +
  53 +}
4 mctcore/META-INF/MANIFEST.MF
@@ -2,10 +2,10 @@ Manifest-Version: 1.0
2 2 Bundle-ManifestVersion: 2
3 3 Bundle-Name: MCT APIs
4 4 Bundle-SymbolicName: gov.nasa.arc.mct
5   -Bundle-Version: 1.1.1
  5 +Bundle-Version: 1.1.2
6 6 Export-Package:
7 7 gov.nasa.arc.mct.services.adapter; version="1.1.0",
8   - gov.nasa.arc.mct.services.component; version="1.1.0",
  8 + gov.nasa.arc.mct.services.component; version="1.1.2",
9 9 gov.nasa.arc.mct.services.internal.component; version="1.1.1",
10 10 gov.nasa.arc.mct.components; version="1.1.0",
11 11 gov.nasa.arc.mct.components.collection;version="1.1.0",
120 mctcore/src/main/java/gov/nasa/arc/mct/components/Bootstrap.java
... ... @@ -0,0 +1,120 @@
  1 +/*******************************************************************************
  2 + * Mission Control Technologies, Copyright (c) 2009-2012, United States Government
  3 + * as represented by the Administrator of the National Aeronautics and Space
  4 + * Administration. All rights reserved.
  5 + * The MCT platform is licensed under the Apache License, Version 2.0 (the
  6 + * "License"); you may not use this file except in compliance with the License.
  7 + * You may obtain a copy of the License at
  8 + * http://www.apache.org/licenses/LICENSE-2.0.
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12 + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13 + * License for the specific language governing permissions and limitations under
  14 + * the License.
  15 + *
  16 + * MCT includes source code licensed under additional open source licenses. See
  17 + * the MCT Open Source Licenses file included with this distribution or the About
  18 + * MCT Licenses dialog available at runtime from the MCT Help menu for additional
  19 + * information.
  20 + *******************************************************************************/
  21 +package gov.nasa.arc.mct.components;
  22 +
  23 +import java.util.Comparator;
  24 +
  25 +/**
  26 + * Bootstrap is a capability exhibited by bootstrap components.
  27 + * This capability assists in ordering and tagging bootstrap
  28 + * components.
  29 + *
  30 + * A bootstrap component is a "top-level" component which should
  31 + * appear in the User Environment for one or more users.
  32 + *
  33 + * @author vwoeltje
  34 + */
  35 +public interface Bootstrap {
  36 + /**
  37 + * Identifies whether or not this bootstrap component
  38 + * should be a bootstrap for all users. If false, appears
  39 + * only for the user indicated as the component's creator.
  40 + * @return true if the component is a bootsrap for all users
  41 + */
  42 + public boolean isGlobal();
  43 +
  44 + /**
  45 + * Used to identify My Sandbox. (More generally, the
  46 + * default destination for created objects.)
  47 + * @return true if the object is the user's sandbox
  48 + */
  49 + public boolean isSandbox();
  50 +
  51 + /**
  52 + * Used for grouping bootstrap components, since these
  53 + * do not have strict order in the database. Bootstraps
  54 + * are sorted in ascending order by category index
  55 + * first, and component index second. Components
  56 + * introduced by the same plug-in should typically
  57 + * have the same category index and different component
  58 + * indexes, although this is not enforced.
  59 + *
  60 + * Bootstrap components provided by the platform will
  61 + * generally have a category of either
  62 + * Integer.MIN_VALUE or Integer.MAX_VALUE, depending on
  63 + * whether or not they should appear at the top or
  64 + * bottom of the User Environment's Browse area.
  65 + * Other plug-ins should typically define category
  66 + * indices somewhere between these two values.
  67 + *
  68 + * @return the index of the category
  69 + */
  70 + public int categoryIndex();
  71 +
  72 + /**
  73 + * Used for grouping bootstrap components. Within any
  74 + * given category, bootstrap components are sorted
  75 + * by their component index in ascending order.
  76 + * Plug-ins which introduce bootstrap components
  77 + * may use different component indexes with the
  78 + * same category index in order to control ordering
  79 + * within an apparent group.
  80 + *
  81 + * @return the index of the component
  82 + */
  83 + public int componentIndex();
  84 +
  85 + /**
  86 + * The sorting comparator for bootstrap components,
  87 + * using the category and component indexes.
  88 + */
  89 + public static final Comparator<AbstractComponent> COMPARATOR =
  90 + new Comparator<AbstractComponent>() {
  91 + @Override
  92 + public int compare(AbstractComponent compA, AbstractComponent compB) {
  93 + Bootstrap bootstrapA = compA.getCapability(Bootstrap.class);
  94 + Bootstrap bootstrapB = compB.getCapability(Bootstrap.class);
  95 +
  96 + // First, consider the case where both components offer
  97 + // the capability.
  98 + if (bootstrapA != null && bootstrapB != null) {
  99 + int orderA = bootstrapA.categoryIndex();
  100 + int orderB = bootstrapB.categoryIndex();
  101 + // Use component index if both categories are the same
  102 + if (orderA == orderB) {
  103 + orderA = bootstrapA.componentIndex();
  104 + orderB = bootstrapB.componentIndex();
  105 + }
  106 + return Integer.valueOf(orderA).compareTo(Integer.valueOf(orderB));
  107 + }
  108 +
  109 + // Move bootstrap-capable components later
  110 + if (bootstrapA != null && bootstrapB == null) {
  111 + return 1;
  112 + } else if (bootstrapA == null && bootstrapB != null) {
  113 + return -1;
  114 + }
  115 +
  116 + // Neither has bootstrap capability, so just use timestamp
  117 + return compA.getCreationDate().compareTo(compB.getCreationDate());
  118 + }
  119 + };
  120 +}
38 mctcore/src/main/java/gov/nasa/arc/mct/registry/ExternalComponentRegistryImpl.java
@@ -22,10 +22,12 @@
22 22 package gov.nasa.arc.mct.registry;
23 23
24 24 import gov.nasa.arc.mct.components.AbstractComponent;
  25 +import gov.nasa.arc.mct.components.Bootstrap;
25 26 import gov.nasa.arc.mct.components.collection.CollectionComponent;
26 27 import gov.nasa.arc.mct.context.GlobalContext;
27 28 import gov.nasa.arc.mct.gui.MenuItemInfo;
28 29 import gov.nasa.arc.mct.platform.spi.DefaultComponentProvider;
  30 +import gov.nasa.arc.mct.platform.spi.PersistenceProvider;
29 31 import gov.nasa.arc.mct.platform.spi.PlatformAccess;
30 32 import gov.nasa.arc.mct.policy.PolicyInfo;
31 33 import gov.nasa.arc.mct.services.component.ComponentProvider;
@@ -40,6 +42,7 @@
40 42 import gov.nasa.arc.mct.services.internal.component.CoreComponentRegistry;
41 43 import gov.nasa.arc.mct.util.logging.MCTLogger;
42 44
  45 +import java.util.ArrayList;
43 46 import java.util.Arrays;
44 47 import java.util.Collection;
45 48 import java.util.Collections;
@@ -331,6 +334,11 @@ public SearchProvider getSearchProvider() {
331 334 @Override
332 335 public <T> T getAsset(TypeInfo<?> objectType, Class<T> assetType) {
333 336 return provider.getAsset(objectType, assetType);
  337 + }
  338 +
  339 + @Override
  340 + public Collection<AbstractComponent> getBootstrapComponents() {
  341 + return provider.getBootstrapComponents();
334 342 }
335 343
336 344 }
@@ -397,7 +405,35 @@ public void refreshComponents(List<ExtendedComponentProvider> providers) {
397 405 " from bundle: " + provider.getBundleSymbolicName(), e);
398 406 }
399 407 }
400   - }
  408 + }
  409 +
  410 + refreshBootstrapComponents(providers);
  411 + }
  412 +
  413 + private void refreshBootstrapComponents(List<ExtendedComponentProvider> providers) {
  414 + Collection<AbstractComponent> bootstraps = new ArrayList<AbstractComponent>();
  415 + Collection<AbstractComponent> userBootstraps = new ArrayList<AbstractComponent>();
  416 + Collection<AbstractComponent> adminBootstraps = new ArrayList<AbstractComponent>();
  417 +
  418 + for (ComponentProvider provider : providers) {
  419 + for (AbstractComponent bootstrap : provider.getBootstrapComponents()) {
  420 + if (getComponent(bootstrap.getComponentId()) == null) {
  421 + Bootstrap capability = bootstrap.getCapability(Bootstrap.class);
  422 + boolean isGlobal = capability != null ?
  423 + capability.isGlobal() :
  424 + bootstrap.getCreator().equals("*");
  425 + bootstraps.add(bootstrap);
  426 + (isGlobal ? adminBootstraps : userBootstraps).add(bootstrap);
  427 + }
  428 + }
  429 + }
  430 +
  431 + if (!bootstraps.isEmpty()) {
  432 + PersistenceProvider persistence = PlatformAccess.getPlatform().getPersistenceProvider();
  433 + persistence.persist(bootstraps);
  434 + persistence.tagComponents("bootstrap:admin", adminBootstraps);
  435 + persistence.tagComponents("bootstrap:creator", userBootstraps);
  436 + }
401 437 }
402 438
403 439 @Override
10 mctcore/src/main/java/gov/nasa/arc/mct/services/component/AbstractComponentProvider.java
@@ -21,6 +21,7 @@
21 21 *******************************************************************************/
22 22 package gov.nasa.arc.mct.services.component;
23 23
  24 +import gov.nasa.arc.mct.components.AbstractComponent;
24 25 import gov.nasa.arc.mct.gui.MenuItemInfo;
25 26 import gov.nasa.arc.mct.policy.PolicyInfo;
26 27
@@ -73,5 +74,12 @@ public SearchProvider getSearchProvider() {
73 74 @Override
74 75 public <T> T getAsset(TypeInfo<?> type, Class<T> assetClass) {
75 76 return null;
76   - }
  77 + }
  78 +
  79 + @Override
  80 + public Collection<AbstractComponent> getBootstrapComponents() {
  81 + return Collections.emptySet();
  82 + }
  83 +
  84 +
77 85 }
27 mctcore/src/main/java/gov/nasa/arc/mct/services/component/ComponentProvider.java
@@ -21,6 +21,7 @@
21 21 *******************************************************************************/
22 22 package gov.nasa.arc.mct.services.component;
23 23
  24 +import gov.nasa.arc.mct.components.AbstractComponent;
24 25 import gov.nasa.arc.mct.gui.MenuItemInfo;
25 26 import gov.nasa.arc.mct.policy.PolicyInfo;
26 27
@@ -92,5 +93,29 @@
92 93 * @param assetClass the type of the requested asset
93 94 * @return an asset of the requested type (or null, if none is provided)
94 95 */
95   - <T> T getAsset(TypeInfo<?> objectType, Class<T> assetClass);
  96 + <T> T getAsset(TypeInfo<?> objectType, Class<T> assetClass);
  97 +
  98 + /**
  99 + * Get any bootstrap components (top-level objects seen in the User Environment)
  100 + * that should be seen. Plug-ins may wish to consult the platform to determine
  101 + * the current user here.
  102 + *
  103 + * Some of these objects may already exist in persistence from previous executions of MCT,
  104 + * so the platform will check for this and filter out any redundant values returned.
  105 + * In support of this behavior, plug-ins which utilize this feature should initialize
  106 + * the component IDs for all components returned here in a repeatable way.
  107 + *
  108 + * Component IDs may be initialized as:
  109 + * <code>component.getCapability(ComponentInitializer.class).setId(id)</code>
  110 + *
  111 + * The platform additionally infers whether a component should be visible to all users
  112 + * or visible only to a specific user. If the creator is * (the wildcard user), then
  113 + * it will be visible to all users; otherwise, it is user-specific.
  114 + *
  115 + * Component creators can be set as:
  116 + * <code>component.getCapability(ComponentInitializer.class).setCreator(id)</code>
  117 + *
  118 + * @return a collection of bootstrap components offered by this plug-in
  119 + */
  120 + Collection<AbstractComponent> getBootstrapComponents();
96 121 }
158 mctcore/src/test/java/gov/nasa/arc/mct/components/BootstrapTest.java
... ... @@ -0,0 +1,158 @@
  1 +/*******************************************************************************
  2 + * Mission Control Technologies, Copyright (c) 2009-2012, United States Government
  3 + * as represented by the Administrator of the National Aeronautics and Space
  4 + * Administration. All rights reserved.
  5 + *
  6 + * The MCT platform is licensed under the Apache License, Version 2.0 (the
  7 + * "License"); you may not use this file except in compliance with the License.
  8 + * You may obtain a copy of the License at
  9 + * http://www.apache.org/licenses/LICENSE-2.0.
  10 + *
  11 + * Unless required by applicable law or agreed to in writing, software
  12 + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  13 + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  14 + * License for the specific language governing permissions and limitations under
  15 + * the License.
  16 + *
  17 + * MCT includes source code licensed under additional open source licenses. See
  18 + * the MCT Open Source Licenses file included with this distribution or the About
  19 + * MCT Licenses dialog available at runtime from the MCT Help menu for additional
  20 + * information.
  21 + *******************************************************************************/
  22 +package gov.nasa.arc.mct.components;
  23 +
  24 +import java.util.ArrayList;
  25 +import java.util.Date;
  26 +import java.util.List;
  27 +
  28 +import org.mockito.Mockito;
  29 +import org.testng.Assert;
  30 +import org.testng.annotations.DataProvider;
  31 +import org.testng.annotations.Test;
  32 +
  33 +public class BootstrapTest {
  34 +
  35 + @Test (dataProvider = "comparatorTestCases")
  36 + public void testComparator(
  37 + Bootstrap bootstrapA, Bootstrap bootstrapB,
  38 + long creationA, long creationB,
  39 + int expectedSign) {
  40 + // Set up mocks
  41 + AbstractComponent a = Mockito.mock(AbstractComponent.class);
  42 + AbstractComponent b = Mockito.mock(AbstractComponent.class);
  43 + Mockito.when(a.handleGetCapability(Bootstrap.class))
  44 + .thenReturn(bootstrapA);
  45 + Mockito.when(b.handleGetCapability(Bootstrap.class))
  46 + .thenReturn(bootstrapB);
  47 + Mockito.when(a.getCreationDate()).thenReturn(new Date(creationA));
  48 + Mockito.when(b.getCreationDate()).thenReturn(new Date(creationB));
  49 +
  50 + // Run the comparator
  51 + int actualSign = (int) (Math.signum(Bootstrap.COMPARATOR.compare(a, b)));
  52 +
  53 + // Verify that sign is as expected
  54 + Assert.assertEquals(actualSign, expectedSign);
  55 + }
  56 +
  57 + @DataProvider
  58 + public Object[][] comparatorTestCases() {
  59 + long times[] = { 100L, 1000000L };
  60 + int indexes[] = { Integer.MIN_VALUE/2, 0, Integer.MAX_VALUE/2 };
  61 +
  62 + List<Object[]> cases = new ArrayList<Object[]>();
  63 +
  64 + // Category should decide the difference, if it is different
  65 + for (long ta : times) {
  66 + for (long tb : times) {
  67 + for (int ia : indexes) {
  68 + for (int ib : indexes) {
  69 + for (int i : indexes) {
  70 + cases.add(new Object[] {
  71 + mockBootstrap(i, ia), mockBootstrap(i+100, ib),
  72 + ta, tb,
  73 + -1
  74 + });
  75 + cases.add(new Object[] {
  76 + mockBootstrap(i, ia), mockBootstrap(i-100, ib),
  77 + ta, tb,
  78 + 1
  79 + });
  80 + }
  81 + }
  82 + }
  83 + }
  84 + }
  85 +
  86 + // Otherwise, should depend on component index
  87 + for (long ta : times) {
  88 + for (long tb : times) {
  89 + for (int i : indexes) {
  90 + for (int j : indexes) {
  91 + cases.add(new Object[] {
  92 + mockBootstrap(i, j), mockBootstrap(i, j+100),
  93 + ta, tb,
  94 + -1
  95 + });
  96 + cases.add(new Object[] {
  97 + mockBootstrap(i, j), mockBootstrap(i, j-100),
  98 + ta, tb,
  99 + 1
  100 + });
  101 + cases.add(new Object[] {
  102 + mockBootstrap(i, j), mockBootstrap(i, j),
  103 + ta, tb,
  104 + 0
  105 + });
  106 + }
  107 + }
  108 + }
  109 + }
  110 +
  111 + // When Bootstrap capability is null, should be less
  112 + for (long ta : times) {
  113 + for (long tb : times) {
  114 + for (int i : indexes) {
  115 + cases.add(new Object[] {
  116 + null, mockBootstrap(i, i),
  117 + ta, tb,
  118 + -1
  119 + });
  120 + cases.add(new Object[] {
  121 + mockBootstrap(i, i), null,
  122 + ta, tb,
  123 + 1
  124 + });
  125 + }
  126 + }
  127 + }
  128 +
  129 + // Finally, just use time stamp if neither has Bootstrap
  130 + for (long ta : times) {
  131 + for (long tb : times) {
  132 + cases.add(new Object[] {
  133 + null, null,
  134 + ta, tb,
  135 + (int) (Math.signum(ta-tb))
  136 + });
  137 + }
  138 + }
  139 +
  140 +
  141 + Object[][] c = new Object[cases.size()][];
  142 + for (int i = 0; i < cases.size(); i++) {
  143 + c[i] = cases.get(i);
  144 + }
  145 +
  146 + return c;
  147 + }
  148 +
  149 + private Bootstrap mockBootstrap(int categoryIndex, int componentIndex) {
  150 + Bootstrap mockBootstrap = Mockito.mock(Bootstrap.class);
  151 +
  152 + Mockito.when(mockBootstrap.categoryIndex()).thenReturn(categoryIndex);
  153 + Mockito.when(mockBootstrap.componentIndex()).thenReturn(componentIndex);
  154 +
  155 + return mockBootstrap;
  156 + }
  157 +
  158 +}
65 mctcore/src/test/java/gov/nasa/arc/mct/registry/TestExternalComponentRegistryImpl.java
@@ -22,6 +22,7 @@
22 22 package gov.nasa.arc.mct.registry;
23 23
24 24 import gov.nasa.arc.mct.components.AbstractComponent;
  25 +import gov.nasa.arc.mct.components.Bootstrap;
25 26 import gov.nasa.arc.mct.gui.View;
26 27 import gov.nasa.arc.mct.platform.spi.PersistenceProvider;
27 28 import gov.nasa.arc.mct.platform.spi.Platform;
@@ -43,6 +44,7 @@
43 44 import java.util.Collections;
44 45 import java.util.List;
45 46
  47 +import org.mockito.ArgumentCaptor;
46 48 import org.mockito.Mockito;
47 49 import org.testng.Assert;
48 50 import org.testng.annotations.BeforeMethod;
@@ -359,5 +361,68 @@ public void testGetInstance() {
359 361 }
360 362 }
361 363 return caseList.toArray(new Object[caseList.size()][]);
  364 + }
  365 +
  366 + @SuppressWarnings("unchecked")
  367 + @Test
  368 + public void testPluginBootstraps() {
  369 + final Bootstrap mockGlobal = Mockito.mock(Bootstrap.class);
  370 + final Bootstrap mockNonGlobal = Mockito.mock(Bootstrap.class);
  371 + Mockito.when(mockGlobal.isGlobal()).thenReturn(true);
  372 + Mockito.when(mockNonGlobal.isGlobal()).thenReturn(false);
  373 +
  374 + class BootstrapComponent extends AbstractComponent {
  375 + private boolean global;
  376 +
  377 + public BootstrapComponent(boolean global) {
  378 + this.global = global;
  379 + }
  380 +
  381 + @Override
  382 + protected <T> T handleGetCapability(Class<T> capability) {
  383 + if (capability.isAssignableFrom(Bootstrap.class)) {
  384 + return capability.cast(global ? mockGlobal : mockNonGlobal);
  385 + }
  386 + return super.handleGetCapability(capability);
  387 + }
  388 +
  389 + }
  390 +
  391 + // First, do a run with no bootstrap components
  392 + ExtendedComponentProvider mockProvider = Mockito.mock(ExtendedComponentProvider.class);
  393 + Mockito.when(mockProvider.getBootstrapComponents()).thenReturn(Collections.<AbstractComponent>emptyList());
  394 +
  395 + registry.refreshComponents(Arrays.asList(mockProvider));
  396 +
  397 + // Verify that this method was probed
  398 + Mockito.verify(mockProvider).getBootstrapComponents();
  399 +
  400 + // Verify that persistence was not invoked
  401 + Mockito.verifyNoMoreInteractions(mockPersistence);
  402 +
  403 + // Now, do a run with two bootstraps components (one global, one local)
  404 + AbstractComponent global = new BootstrapComponent(true);
  405 + AbstractComponent local = new BootstrapComponent(false);
  406 + Mockito.when(mockProvider.getBootstrapComponents()).thenReturn(Arrays.asList(global, local));
  407 +
  408 + registry.refreshComponents(Arrays.asList(mockProvider));
  409 +
  410 + // Verify that persistence was invoked, including appropriate tagging
  411 + @SuppressWarnings("rawtypes")
  412 + ArgumentCaptor<Collection> captor =
  413 + ArgumentCaptor.forClass(Collection.class);
  414 +
  415 + Mockito.verify(mockPersistence).persist(captor.capture());
  416 + Assert.assertEquals(captor.getValue().size(), 2);
  417 + Assert.assertTrue(captor.getValue().contains(global));
  418 + Assert.assertTrue(captor.getValue().contains(local));
  419 +
  420 + Mockito.verify(mockPersistence).tagComponents(Mockito.eq("bootstrap:admin"), captor.capture());
  421 + Assert.assertEquals(captor.getValue().size(), 1);
  422 + Assert.assertTrue(captor.getValue().contains(global));
  423 +
  424 + Mockito.verify(mockPersistence).tagComponents(Mockito.eq("bootstrap:creator"), captor.capture());
  425 + Assert.assertEquals(captor.getValue().size(), 1);
  426 + Assert.assertTrue(captor.getValue().contains(local));
362 427 }
363 428 }
6 platform/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
2 2 Bundle-ManifestVersion: 2
3 3 Bundle-Name: MCT Platform
4 4 Bundle-SymbolicName: gov.nasa.arc.mct.mctplatform
5   -Bundle-Version: 1.1.0
  5 +Bundle-Version: 1.1.2
6 6 Import-Package: gov.nasa.arc.mct.api.feed;version="1.1.0",
7 7 gov.nasa.arc.mct.api.persistence;version="1.1.0",
8 8 gov.nasa.arc.mct.components;version="1.1.0",
@@ -17,8 +17,8 @@ Import-Package: gov.nasa.arc.mct.api.feed;version="1.1.0",
17 17 gov.nasa.arc.mct.roles.events;version="1.1.0",
18 18 gov.nasa.arc.mct.services.activity;version="1.1.0",
19 19 gov.nasa.arc.mct.services.adapter;version="1.1.0",
20   - gov.nasa.arc.mct.services.component;version="1.1.0",
21   - gov.nasa.arc.mct.services.internal.component;version="1.1.0",
  20 + gov.nasa.arc.mct.services.component;version="1.1.2",
  21 + gov.nasa.arc.mct.services.internal.component;version="1.1.1",
22 22 gov.nasa.arc.mct.services.serviceLocator;version="1.1.0",
23 23 gov.nasa.arc.mct.util;version="1.1.0",
24 24 gov.nasa.arc.mct.util.exception;version="1.1.0",
20 platform/src/main/java/gov/nasa/arc/mct/platform/PlatformImpl.java
@@ -24,6 +24,7 @@
24 24 import gov.nasa.arc.mct.api.feed.FeedAggregator;
25 25 import gov.nasa.arc.mct.api.feed.FeedDataArchive;
26 26 import gov.nasa.arc.mct.components.AbstractComponent;
  27 +import gov.nasa.arc.mct.components.Bootstrap;
27 28 import gov.nasa.arc.mct.context.GlobalContext;
28 29 import gov.nasa.arc.mct.gui.housing.MCTAbstractHousing;
29 30 import gov.nasa.arc.mct.gui.housing.registry.UserEnvironmentRegistry;
@@ -45,6 +46,7 @@
45 46 import gov.nasa.arc.mct.services.internal.component.User;
46 47
47 48 import java.util.Collection;
  49 +import java.util.Collections;
48 50 import java.util.List;
49 51 import java.util.concurrent.atomic.AtomicReference;
50 52
@@ -64,7 +66,7 @@
64 66
65 67 private final RootComponent rootComponent = new RootComponent();
66 68
67   - private AbstractComponent mysanboxComponent; // initialized from the bootstrapping components loaded from the database
  69 + private AbstractComponent mySandbox; // initialized from the bootstrapping components loaded from the database
68 70 private String userDropboxesId;
69 71 private final AtomicReference<BundleContext> bundleContext = new AtomicReference<BundleContext>();
70 72
@@ -164,23 +166,25 @@ public AbstractComponent getRootComponent() {
164 166 public List<AbstractComponent> getBootstrapComponents() {
165 167 // Inject root and My Sandbox components to GlobalComponentRegistry
166 168 List<AbstractComponent> bootstrapComponents = getPersistenceProvider().getBootstrapComponents();
167   - for (AbstractComponent ac : bootstrapComponents) {
168   - // Should introduce a property indicating an AbstractComponent to be My Sandbox.
169   - // Assuming that there's only one My Sandbox among the bootstrap components.
170   - if ("gov.nasa.arc.mct.core.components.MineTaxonomyComponent".equals(ac.getComponentTypeID())) {
171   - mysanboxComponent = ac;
  169 + for (AbstractComponent ac : bootstrapComponents) {
  170 + // Check capability to determine if this is the sandbox
  171 + Bootstrap capability = ac.getCapability(Bootstrap.class);
  172 + if (capability != null && capability.isSandbox()) {
  173 + mySandbox = ac;
172 174 }
173 175 if ("/UserDropBoxes".equals(ac.getExternalKey())) {
174 176 userDropboxesId = ac.getComponentId();
175 177 }
176   - }
  178 + }
  179 + // Sort them, such that they are displayed in an appropriate order
  180 + Collections.sort(bootstrapComponents, Bootstrap.COMPARATOR);
177 181 return bootstrapComponents;
178 182 }
179 183
180 184
181 185 @Override
182 186 public AbstractComponent getMySandbox() {
183   - return getPersistenceProvider().getComponent(mysanboxComponent.getComponentId());
  187 + return getPersistenceProvider().getComponent(mySandbox.getComponentId());
184 188 }
185 189
186 190

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.