Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #208 from VWoeltjen/mct207

[Taxonomy] Allow plug-ins to introduce bootstrap components
  • Loading branch information...
commit f572c913970d4823e7af1984e9915f2d51fe1159 2 parents 2b9d182 + c425bf0
VWoeltjen VWoeltjen authored
6 mctCoreTaxonomyProvider/META-INF/MANIFEST.MF
View
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: MctCoreTaxonomyProvider
Bundle-SymbolicName: mctCoreTaxonomyProvider
-Bundle-Version: 1.1.0
+Bundle-Version: 1.1.2
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: gov.nasa.arc.mct.components;version="1.1.0",
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",
gov.nasa.arc.mct.policy;version="1.1.0",
gov.nasa.arc.mct.roles;version="1.1.0",
gov.nasa.arc.mct.roles.events;version="1.1.0",
- gov.nasa.arc.mct.services.component;version="1.1.0",
- gov.nasa.arc.mct.services.internal.component;version="1.1.0",
+ gov.nasa.arc.mct.services.component;version="1.1.2",
+ gov.nasa.arc.mct.services.internal.component;version="1.1.1",
gov.nasa.arc.mct.util;version="1.1.0",
org.osgi.framework;version="1.4.0"
Service-Component: OSGI-INF/service.xml
33 mctCoreTaxonomyProvider/src/main/java/gov/nasa/arc/mct/core/components/MineTaxonomyComponent.java
View
@@ -29,11 +29,38 @@
*/
package gov.nasa.arc.mct.core.components;
-import gov.nasa.arc.mct.components.AbstractComponent;
+import gov.nasa.arc.mct.components.AbstractComponent;
+import gov.nasa.arc.mct.components.Bootstrap;
-public class MineTaxonomyComponent extends AbstractComponent {
+public class MineTaxonomyComponent extends AbstractComponent implements Bootstrap {
public MineTaxonomyComponent() {
- }
+ }
+
+ @Override
+ protected <T> T handleGetCapability(Class<T> capability) {
+ return capability.isAssignableFrom(getClass()) ?
+ capability.cast(this) : super.handleGetCapability(capability);
+ }
+
+ @Override
+ public boolean isGlobal() {
+ return false;
+ }
+
+ @Override
+ public boolean isSandbox() {
+ return true;
+ }
+
+ @Override
+ public int categoryIndex() {
+ return Integer.MAX_VALUE; // Always should appear at bottom
+ }
+
+ @Override
+ public int componentIndex() {
+ return Integer.MAX_VALUE; // Always should appear at bottom
+ }
}
33 mctCoreTaxonomyProvider/src/main/java/gov/nasa/arc/mct/core/components/TelemetryDataTaxonomyComponent.java
View
@@ -29,9 +29,10 @@
*/
package gov.nasa.arc.mct.core.components;
-import gov.nasa.arc.mct.components.AbstractComponent;
+import gov.nasa.arc.mct.components.AbstractComponent;
+import gov.nasa.arc.mct.components.Bootstrap;
-public class TelemetryDataTaxonomyComponent extends AbstractComponent {
+public class TelemetryDataTaxonomyComponent extends AbstractComponent implements Bootstrap {
public TelemetryDataTaxonomyComponent() {
}
@@ -43,5 +44,33 @@ public TelemetryDataTaxonomyComponent() {
*/
public TelemetryDataTaxonomyComponent(String id) {
setId(id);
+ }
+
+ @Override
+ protected <T> T handleGetCapability(Class<T> capability) {
+ return capability.isAssignableFrom(getClass()) ?
+ capability.cast(this) : super.handleGetCapability(capability);
+ }
+
+ @Override
+ public boolean isGlobal() {
+ return true;
+ }
+
+ @Override
+ public boolean isSandbox() {
+ return false;
+ }
+
+ @Override
+ public int categoryIndex() {
+ return Integer.MAX_VALUE; // Always should appear at bottom
+ }
+
+ @Override
+ public int componentIndex() {
+ // "Somewhere in the middle"
+ // Use Component Id's hash code to keep position consistent.
+ return getComponentId().hashCode() & 0xFFFF;
}
}
51 mctCoreTaxonomyProvider/src/test/java/gov/nasa/arc/mct/core/components/MineTaxonomyComponentTest.java
View
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Mission Control Technologies, Copyright (c) 2009-2012, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * The MCT platform is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * MCT includes source code licensed under additional open source licenses. See
+ * the MCT Open Source Licenses file included with this distribution or the About
+ * MCT Licenses dialog available at runtime from the MCT Help menu for additional
+ * information.
+ *******************************************************************************/
+package gov.nasa.arc.mct.core.components;
+
+import gov.nasa.arc.mct.components.Bootstrap;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class MineTaxonomyComponentTest {
+
+ @Test
+ public void testBootstrap() {
+ // Test Bootstrap capability by getting one from the sandbox
+ MineTaxonomyComponent mySandbox = new MineTaxonomyComponent();
+ Bootstrap capability = mySandbox.getCapability(Bootstrap.class);
+
+ // Should support the bootstrap capability
+ Assert.assertNotNull(capability);
+
+ // Is a sandbox
+ Assert.assertTrue(capability.isSandbox());
+
+ // Is not globally accessible (one per user)
+ Assert.assertFalse(capability.isGlobal());
+
+ // Appears at the end of sorted list of bootstraps
+ Assert.assertEquals(capability.categoryIndex(), Integer.MAX_VALUE);
+ Assert.assertEquals(capability.componentIndex(), Integer.MAX_VALUE);
+ }
+
+}
53 ...eTaxonomyProvider/src/test/java/gov/nasa/arc/mct/core/components/TelemetryDataTaxonomyComponentTest.java
View
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Mission Control Technologies, Copyright (c) 2009-2012, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * The MCT platform is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * MCT includes source code licensed under additional open source licenses. See
+ * the MCT Open Source Licenses file included with this distribution or the About
+ * MCT Licenses dialog available at runtime from the MCT Help menu for additional
+ * information.
+ *******************************************************************************/
+package gov.nasa.arc.mct.core.components;
+
+import gov.nasa.arc.mct.components.Bootstrap;
+import gov.nasa.arc.mct.services.internal.component.ComponentInitializer;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class TelemetryDataTaxonomyComponentTest {
+
+ @Test
+ public void testBootstrap() {
+ // Test Bootstrap capability by getting one from the sandbox
+ TelemetryDataTaxonomyComponent component = new TelemetryDataTaxonomyComponent();
+ component.getCapability(ComponentInitializer.class).setId("id");
+ Bootstrap capability = component.getCapability(Bootstrap.class);
+
+ // Should support the bootstrap capability
+ Assert.assertNotNull(capability);
+
+ // Is not a sandbox
+ Assert.assertFalse(capability.isSandbox());
+
+ // Is globally accessible (for all users)
+ Assert.assertTrue(capability.isGlobal());
+
+ // Appears near the bottom, but not at the bottom
+ Assert.assertEquals(capability.categoryIndex(), Integer.MAX_VALUE);
+ Assert.assertTrue(capability.componentIndex() < Integer.MAX_VALUE);
+ }
+
+}
4 mctcore/META-INF/MANIFEST.MF
View
@@ -2,10 +2,10 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: MCT APIs
Bundle-SymbolicName: gov.nasa.arc.mct
-Bundle-Version: 1.1.1
+Bundle-Version: 1.1.2
Export-Package:
gov.nasa.arc.mct.services.adapter; version="1.1.0",
- gov.nasa.arc.mct.services.component; version="1.1.0",
+ gov.nasa.arc.mct.services.component; version="1.1.2",
gov.nasa.arc.mct.services.internal.component; version="1.1.1",
gov.nasa.arc.mct.components; version="1.1.0",
gov.nasa.arc.mct.components.collection;version="1.1.0",
120 mctcore/src/main/java/gov/nasa/arc/mct/components/Bootstrap.java
View
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Mission Control Technologies, Copyright (c) 2009-2012, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ * The MCT platform is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * MCT includes source code licensed under additional open source licenses. See
+ * the MCT Open Source Licenses file included with this distribution or the About
+ * MCT Licenses dialog available at runtime from the MCT Help menu for additional
+ * information.
+ *******************************************************************************/
+package gov.nasa.arc.mct.components;
+
+import java.util.Comparator;
+
+/**
+ * Bootstrap is a capability exhibited by bootstrap components.
+ * This capability assists in ordering and tagging bootstrap
+ * components.
+ *
+ * A bootstrap component is a "top-level" component which should
+ * appear in the User Environment for one or more users.
+ *
+ * @author vwoeltje
+ */
+public interface Bootstrap {
+ /**
+ * Identifies whether or not this bootstrap component
+ * should be a bootstrap for all users. If false, appears
+ * only for the user indicated as the component's creator.
+ * @return true if the component is a bootsrap for all users
+ */
+ public boolean isGlobal();
+
+ /**
+ * Used to identify My Sandbox. (More generally, the
+ * default destination for created objects.)
+ * @return true if the object is the user's sandbox
+ */
+ public boolean isSandbox();
+
+ /**
+ * Used for grouping bootstrap components, since these
+ * do not have strict order in the database. Bootstraps
+ * are sorted in ascending order by category index
+ * first, and component index second. Components
+ * introduced by the same plug-in should typically
+ * have the same category index and different component
+ * indexes, although this is not enforced.
+ *
+ * Bootstrap components provided by the platform will
+ * generally have a category of either
+ * Integer.MIN_VALUE or Integer.MAX_VALUE, depending on
+ * whether or not they should appear at the top or
+ * bottom of the User Environment's Browse area.
+ * Other plug-ins should typically define category
+ * indices somewhere between these two values.
+ *
+ * @return the index of the category
+ */
+ public int categoryIndex();
+
+ /**
+ * Used for grouping bootstrap components. Within any
+ * given category, bootstrap components are sorted
+ * by their component index in ascending order.
+ * Plug-ins which introduce bootstrap components
+ * may use different component indexes with the
+ * same category index in order to control ordering
+ * within an apparent group.
+ *
+ * @return the index of the component
+ */
+ public int componentIndex();
+
+ /**
+ * The sorting comparator for bootstrap components,
+ * using the category and component indexes.
+ */
+ public static final Comparator<AbstractComponent> COMPARATOR =
+ new Comparator<AbstractComponent>() {
+ @Override
+ public int compare(AbstractComponent compA, AbstractComponent compB) {
+ Bootstrap bootstrapA = compA.getCapability(Bootstrap.class);
+ Bootstrap bootstrapB = compB.getCapability(Bootstrap.class);
+
+ // First, consider the case where both components offer
+ // the capability.
+ if (bootstrapA != null && bootstrapB != null) {
+ int orderA = bootstrapA.categoryIndex();
+ int orderB = bootstrapB.categoryIndex();
+ // Use component index if both categories are the same
+ if (orderA == orderB) {
+ orderA = bootstrapA.componentIndex();
+ orderB = bootstrapB.componentIndex();
+ }
+ return Integer.valueOf(orderA).compareTo(Integer.valueOf(orderB));
+ }
+
+ // Move bootstrap-capable components later
+ if (bootstrapA != null && bootstrapB == null) {
+ return 1;
+ } else if (bootstrapA == null && bootstrapB != null) {
+ return -1;
+ }
+
+ // Neither has bootstrap capability, so just use timestamp
+ return compA.getCreationDate().compareTo(compB.getCreationDate());
+ }
+ };
+}
38 mctcore/src/main/java/gov/nasa/arc/mct/registry/ExternalComponentRegistryImpl.java
View
@@ -22,10 +22,12 @@
package gov.nasa.arc.mct.registry;
import gov.nasa.arc.mct.components.AbstractComponent;
+import gov.nasa.arc.mct.components.Bootstrap;
import gov.nasa.arc.mct.components.collection.CollectionComponent;
import gov.nasa.arc.mct.context.GlobalContext;
import gov.nasa.arc.mct.gui.MenuItemInfo;
import gov.nasa.arc.mct.platform.spi.DefaultComponentProvider;
+import gov.nasa.arc.mct.platform.spi.PersistenceProvider;
import gov.nasa.arc.mct.platform.spi.PlatformAccess;
import gov.nasa.arc.mct.policy.PolicyInfo;
import gov.nasa.arc.mct.services.component.ComponentProvider;
@@ -40,6 +42,7 @@
import gov.nasa.arc.mct.services.internal.component.CoreComponentRegistry;
import gov.nasa.arc.mct.util.logging.MCTLogger;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -331,6 +334,11 @@ public SearchProvider getSearchProvider() {
@Override
public <T> T getAsset(TypeInfo<?> objectType, Class<T> assetType) {
return provider.getAsset(objectType, assetType);
+ }
+
+ @Override
+ public Collection<AbstractComponent> getBootstrapComponents() {
+ return provider.getBootstrapComponents();
}
}
@@ -397,7 +405,35 @@ public void refreshComponents(List<ExtendedComponentProvider> providers) {
" from bundle: " + provider.getBundleSymbolicName(), e);
}
}
- }
+ }
+
+ refreshBootstrapComponents(providers);
+ }
+
+ private void refreshBootstrapComponents(List<ExtendedComponentProvider> providers) {
+ Collection<AbstractComponent> bootstraps = new ArrayList<AbstractComponent>();
+ Collection<AbstractComponent> userBootstraps = new ArrayList<AbstractComponent>();
+ Collection<AbstractComponent> adminBootstraps = new ArrayList<AbstractComponent>();
+
+ for (ComponentProvider provider : providers) {
+ for (AbstractComponent bootstrap : provider.getBootstrapComponents()) {
+ if (getComponent(bootstrap.getComponentId()) == null) {
+ Bootstrap capability = bootstrap.getCapability(Bootstrap.class);
+ boolean isGlobal = capability != null ?
+ capability.isGlobal() :
+ bootstrap.getCreator().equals("*");
+ bootstraps.add(bootstrap);
+ (isGlobal ? adminBootstraps : userBootstraps).add(bootstrap);
+ }
+ }
+ }
+
+ if (!bootstraps.isEmpty()) {
+ PersistenceProvider persistence = PlatformAccess.getPlatform().getPersistenceProvider();
+ persistence.persist(bootstraps);
+ persistence.tagComponents("bootstrap:admin", adminBootstraps);
+ persistence.tagComponents("bootstrap:creator", userBootstraps);
+ }
}
@Override
10 mctcore/src/main/java/gov/nasa/arc/mct/services/component/AbstractComponentProvider.java
View
@@ -21,6 +21,7 @@
*******************************************************************************/
package gov.nasa.arc.mct.services.component;
+import gov.nasa.arc.mct.components.AbstractComponent;
import gov.nasa.arc.mct.gui.MenuItemInfo;
import gov.nasa.arc.mct.policy.PolicyInfo;
@@ -73,5 +74,12 @@ public SearchProvider getSearchProvider() {
@Override
public <T> T getAsset(TypeInfo<?> type, Class<T> assetClass) {
return null;
- }
+ }
+
+ @Override
+ public Collection<AbstractComponent> getBootstrapComponents() {
+ return Collections.emptySet();
+ }
+
+
}
27 mctcore/src/main/java/gov/nasa/arc/mct/services/component/ComponentProvider.java
View
@@ -21,6 +21,7 @@
*******************************************************************************/
package gov.nasa.arc.mct.services.component;
+import gov.nasa.arc.mct.components.AbstractComponent;
import gov.nasa.arc.mct.gui.MenuItemInfo;
import gov.nasa.arc.mct.policy.PolicyInfo;
@@ -92,5 +93,29 @@
* @param assetClass the type of the requested asset
* @return an asset of the requested type (or null, if none is provided)
*/
- <T> T getAsset(TypeInfo<?> objectType, Class<T> assetClass);
+ <T> T getAsset(TypeInfo<?> objectType, Class<T> assetClass);
+
+ /**
+ * Get any bootstrap components (top-level objects seen in the User Environment)
+ * that should be seen. Plug-ins may wish to consult the platform to determine
+ * the current user here.
+ *
+ * Some of these objects may already exist in persistence from previous executions of MCT,
+ * so the platform will check for this and filter out any redundant values returned.
+ * In support of this behavior, plug-ins which utilize this feature should initialize
+ * the component IDs for all components returned here in a repeatable way.
+ *
+ * Component IDs may be initialized as:
+ * <code>component.getCapability(ComponentInitializer.class).setId(id)</code>
+ *
+ * The platform additionally infers whether a component should be visible to all users
+ * or visible only to a specific user. If the creator is * (the wildcard user), then
+ * it will be visible to all users; otherwise, it is user-specific.
+ *
+ * Component creators can be set as:
+ * <code>component.getCapability(ComponentInitializer.class).setCreator(id)</code>
+ *
+ * @return a collection of bootstrap components offered by this plug-in
+ */
+ Collection<AbstractComponent> getBootstrapComponents();
}
158 mctcore/src/test/java/gov/nasa/arc/mct/components/BootstrapTest.java
View
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Mission Control Technologies, Copyright (c) 2009-2012, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * The MCT platform is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * MCT includes source code licensed under additional open source licenses. See
+ * the MCT Open Source Licenses file included with this distribution or the About
+ * MCT Licenses dialog available at runtime from the MCT Help menu for additional
+ * information.
+ *******************************************************************************/
+package gov.nasa.arc.mct.components;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class BootstrapTest {
+
+ @Test (dataProvider = "comparatorTestCases")
+ public void testComparator(
+ Bootstrap bootstrapA, Bootstrap bootstrapB,
+ long creationA, long creationB,
+ int expectedSign) {
+ // Set up mocks
+ AbstractComponent a = Mockito.mock(AbstractComponent.class);
+ AbstractComponent b = Mockito.mock(AbstractComponent.class);
+ Mockito.when(a.handleGetCapability(Bootstrap.class))
+ .thenReturn(bootstrapA);
+ Mockito.when(b.handleGetCapability(Bootstrap.class))
+ .thenReturn(bootstrapB);
+ Mockito.when(a.getCreationDate()).thenReturn(new Date(creationA));
+ Mockito.when(b.getCreationDate()).thenReturn(new Date(creationB));
+
+ // Run the comparator
+ int actualSign = (int) (Math.signum(Bootstrap.COMPARATOR.compare(a, b)));
+
+ // Verify that sign is as expected
+ Assert.assertEquals(actualSign, expectedSign);
+ }
+
+ @DataProvider
+ public Object[][] comparatorTestCases() {
+ long times[] = { 100L, 1000000L };
+ int indexes[] = { Integer.MIN_VALUE/2, 0, Integer.MAX_VALUE/2 };
+
+ List<Object[]> cases = new ArrayList<Object[]>();
+
+ // Category should decide the difference, if it is different
+ for (long ta : times) {
+ for (long tb : times) {
+ for (int ia : indexes) {
+ for (int ib : indexes) {
+ for (int i : indexes) {
+ cases.add(new Object[] {
+ mockBootstrap(i, ia), mockBootstrap(i+100, ib),
+ ta, tb,
+ -1
+ });
+ cases.add(new Object[] {
+ mockBootstrap(i, ia), mockBootstrap(i-100, ib),
+ ta, tb,
+ 1
+ });
+ }
+ }
+ }
+ }
+ }
+
+ // Otherwise, should depend on component index
+ for (long ta : times) {
+ for (long tb : times) {
+ for (int i : indexes) {
+ for (int j : indexes) {
+ cases.add(new Object[] {
+ mockBootstrap(i, j), mockBootstrap(i, j+100),
+ ta, tb,
+ -1
+ });
+ cases.add(new Object[] {
+ mockBootstrap(i, j), mockBootstrap(i, j-100),
+ ta, tb,
+ 1
+ });
+ cases.add(new Object[] {
+ mockBootstrap(i, j), mockBootstrap(i, j),
+ ta, tb,
+ 0
+ });
+ }
+ }
+ }
+ }
+
+ // When Bootstrap capability is null, should be less
+ for (long ta : times) {
+ for (long tb : times) {
+ for (int i : indexes) {
+ cases.add(new Object[] {
+ null, mockBootstrap(i, i),
+ ta, tb,
+ -1
+ });
+ cases.add(new Object[] {
+ mockBootstrap(i, i), null,
+ ta, tb,
+ 1
+ });
+ }
+ }
+ }
+
+ // Finally, just use time stamp if neither has Bootstrap
+ for (long ta : times) {
+ for (long tb : times) {
+ cases.add(new Object[] {
+ null, null,
+ ta, tb,
+ (int) (Math.signum(ta-tb))
+ });
+ }
+ }
+
+
+ Object[][] c = new Object[cases.size()][];
+ for (int i = 0; i < cases.size(); i++) {
+ c[i] = cases.get(i);
+ }
+
+ return c;
+ }
+
+ private Bootstrap mockBootstrap(int categoryIndex, int componentIndex) {
+ Bootstrap mockBootstrap = Mockito.mock(Bootstrap.class);
+
+ Mockito.when(mockBootstrap.categoryIndex()).thenReturn(categoryIndex);
+ Mockito.when(mockBootstrap.componentIndex()).thenReturn(componentIndex);
+
+ return mockBootstrap;
+ }
+
+}
65 mctcore/src/test/java/gov/nasa/arc/mct/registry/TestExternalComponentRegistryImpl.java
View
@@ -22,6 +22,7 @@
package gov.nasa.arc.mct.registry;
import gov.nasa.arc.mct.components.AbstractComponent;
+import gov.nasa.arc.mct.components.Bootstrap;
import gov.nasa.arc.mct.gui.View;
import gov.nasa.arc.mct.platform.spi.PersistenceProvider;
import gov.nasa.arc.mct.platform.spi.Platform;
@@ -43,6 +44,7 @@
import java.util.Collections;
import java.util.List;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
@@ -359,5 +361,68 @@ public void testGetInstance() {
}
}
return caseList.toArray(new Object[caseList.size()][]);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testPluginBootstraps() {
+ final Bootstrap mockGlobal = Mockito.mock(Bootstrap.class);
+ final Bootstrap mockNonGlobal = Mockito.mock(Bootstrap.class);
+ Mockito.when(mockGlobal.isGlobal()).thenReturn(true);
+ Mockito.when(mockNonGlobal.isGlobal()).thenReturn(false);
+
+ class BootstrapComponent extends AbstractComponent {
+ private boolean global;
+
+ public BootstrapComponent(boolean global) {
+ this.global = global;
+ }
+
+ @Override
+ protected <T> T handleGetCapability(Class<T> capability) {
+ if (capability.isAssignableFrom(Bootstrap.class)) {
+ return capability.cast(global ? mockGlobal : mockNonGlobal);
+ }
+ return super.handleGetCapability(capability);
+ }
+
+ }
+
+ // First, do a run with no bootstrap components
+ ExtendedComponentProvider mockProvider = Mockito.mock(ExtendedComponentProvider.class);
+ Mockito.when(mockProvider.getBootstrapComponents()).thenReturn(Collections.<AbstractComponent>emptyList());
+
+ registry.refreshComponents(Arrays.asList(mockProvider));
+
+ // Verify that this method was probed
+ Mockito.verify(mockProvider).getBootstrapComponents();
+
+ // Verify that persistence was not invoked
+ Mockito.verifyNoMoreInteractions(mockPersistence);
+
+ // Now, do a run with two bootstraps components (one global, one local)
+ AbstractComponent global = new BootstrapComponent(true);
+ AbstractComponent local = new BootstrapComponent(false);
+ Mockito.when(mockProvider.getBootstrapComponents()).thenReturn(Arrays.asList(global, local));
+
+ registry.refreshComponents(Arrays.asList(mockProvider));
+
+ // Verify that persistence was invoked, including appropriate tagging
+ @SuppressWarnings("rawtypes")
+ ArgumentCaptor<Collection> captor =
+ ArgumentCaptor.forClass(Collection.class);
+
+ Mockito.verify(mockPersistence).persist(captor.capture());
+ Assert.assertEquals(captor.getValue().size(), 2);
+ Assert.assertTrue(captor.getValue().contains(global));
+ Assert.assertTrue(captor.getValue().contains(local));
+
+ Mockito.verify(mockPersistence).tagComponents(Mockito.eq("bootstrap:admin"), captor.capture());
+ Assert.assertEquals(captor.getValue().size(), 1);
+ Assert.assertTrue(captor.getValue().contains(global));
+
+ Mockito.verify(mockPersistence).tagComponents(Mockito.eq("bootstrap:creator"), captor.capture());
+ Assert.assertEquals(captor.getValue().size(), 1);
+ Assert.assertTrue(captor.getValue().contains(local));
}
}
6 platform/META-INF/MANIFEST.MF
View
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: MCT Platform
Bundle-SymbolicName: gov.nasa.arc.mct.mctplatform
-Bundle-Version: 1.1.0
+Bundle-Version: 1.1.2
Import-Package: gov.nasa.arc.mct.api.feed;version="1.1.0",
gov.nasa.arc.mct.api.persistence;version="1.1.0",
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",
gov.nasa.arc.mct.roles.events;version="1.1.0",
gov.nasa.arc.mct.services.activity;version="1.1.0",
gov.nasa.arc.mct.services.adapter;version="1.1.0",
- gov.nasa.arc.mct.services.component;version="1.1.0",
- gov.nasa.arc.mct.services.internal.component;version="1.1.0",
+ gov.nasa.arc.mct.services.component;version="1.1.2",
+ gov.nasa.arc.mct.services.internal.component;version="1.1.1",
gov.nasa.arc.mct.services.serviceLocator;version="1.1.0",
gov.nasa.arc.mct.util;version="1.1.0",
gov.nasa.arc.mct.util.exception;version="1.1.0",
20 platform/src/main/java/gov/nasa/arc/mct/platform/PlatformImpl.java
View
@@ -24,6 +24,7 @@
import gov.nasa.arc.mct.api.feed.FeedAggregator;
import gov.nasa.arc.mct.api.feed.FeedDataArchive;
import gov.nasa.arc.mct.components.AbstractComponent;
+import gov.nasa.arc.mct.components.Bootstrap;
import gov.nasa.arc.mct.context.GlobalContext;
import gov.nasa.arc.mct.gui.housing.MCTAbstractHousing;
import gov.nasa.arc.mct.gui.housing.registry.UserEnvironmentRegistry;
@@ -45,6 +46,7 @@
import gov.nasa.arc.mct.services.internal.component.User;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
@@ -64,7 +66,7 @@
private final RootComponent rootComponent = new RootComponent();
- private AbstractComponent mysanboxComponent; // initialized from the bootstrapping components loaded from the database
+ private AbstractComponent mySandbox; // initialized from the bootstrapping components loaded from the database
private String userDropboxesId;
private final AtomicReference<BundleContext> bundleContext = new AtomicReference<BundleContext>();
@@ -164,23 +166,25 @@ public AbstractComponent getRootComponent() {
public List<AbstractComponent> getBootstrapComponents() {
// Inject root and My Sandbox components to GlobalComponentRegistry
List<AbstractComponent> bootstrapComponents = getPersistenceProvider().getBootstrapComponents();
- for (AbstractComponent ac : bootstrapComponents) {
- // Should introduce a property indicating an AbstractComponent to be My Sandbox.
- // Assuming that there's only one My Sandbox among the bootstrap components.
- if ("gov.nasa.arc.mct.core.components.MineTaxonomyComponent".equals(ac.getComponentTypeID())) {
- mysanboxComponent = ac;
+ for (AbstractComponent ac : bootstrapComponents) {
+ // Check capability to determine if this is the sandbox
+ Bootstrap capability = ac.getCapability(Bootstrap.class);
+ if (capability != null && capability.isSandbox()) {
+ mySandbox = ac;
}
if ("/UserDropBoxes".equals(ac.getExternalKey())) {
userDropboxesId = ac.getComponentId();
}
- }
+ }
+ // Sort them, such that they are displayed in an appropriate order
+ Collections.sort(bootstrapComponents, Bootstrap.COMPARATOR);
return bootstrapComponents;
}
@Override
public AbstractComponent getMySandbox() {
- return getPersistenceProvider().getComponent(mysanboxComponent.getComponentId());
+ return getPersistenceProvider().getComponent(mySandbox.getComponentId());
}
Please sign in to comment.
Something went wrong with that request. Please try again.