@Override public Set<Activity> getActivities(final PlaceRequest placeRequest) { return getActivities(placeRequest, true); }
@Override public Activity getActivity(PlaceRequest placeRequest, boolean secure) { return getActivity(Activity.class, placeRequest, secure); }
private Set<SyncBeanDef<Activity>> resolveByPath(final PathPlaceRequest place) { if (place == null) { return emptySet(); } final SyncBeanDef<Activity> result = activityBeansCache.getActivity(place.getIdentifier()); if (result != null) { return singleton(result); } return asSet(activityBeansCache.getActivity(place.getPath())); }
@Override public Set<Activity> getActivities(final PlaceRequest placeRequest, boolean secure) { final Collection<SyncBeanDef<Activity>> beans; if (placeRequest instanceof PathPlaceRequest) { beans = resolveByPath((PathPlaceRequest) placeRequest); } else { beans = resolveById(placeRequest.getIdentifier()); } final Set<Activity> activities = startIfNecessary(secure(beans, secure), placeRequest); if (placeRequest instanceof PathPlaceRequest) { resolvePathPlaceRequestIdentifier(placeRequest, activities); } return activities; }
@Test public void shouldNotGetConfusedAboutSplashScreensWithSamePlaceAsTheirScreen() throws Exception { List<SplashScreenActivity> splashScreenList = new ArrayList<SplashScreenActivity>(); SplashScreenActivity expectedSplashScreenActivity = makeEnabledSplashScreenThatIntercepts(kansas); when(expectedSplashScreenActivity.getPlace()).thenReturn(kansas); splashScreenList.add(expectedSplashScreenActivity); when(activityBeansCache.getSplashScreens()).thenReturn(splashScreenList); // this loads the regular kansas activity (not the splash screen) into the activityBeansCache activityManager.getActivity(kansas); SplashScreenActivity splashScreenActivity = activityManager.getSplashScreenInterceptor(kansas); // this must not get confused even though expectedSplashScreenActivity and kansasActivity both have the same PlaceRequest activityManager.destroyActivity(splashScreenActivity); verify(expectedSplashScreenActivity, times(1)).onShutdown(); assertFalse(activityManager.isStarted(expectedSplashScreenActivity)); // never try to destroy singleton beans! verify(iocManager, never()).destroyBean(expectedSplashScreenActivity); }
@Test public void shouldCallOnShutdownWhenDestroyingActivity() throws Exception { activityManager.getActivities(kansas); activityManager.destroyActivity(kansasActivity); verify(kansasActivity, times(1)).onShutdown(); verify(iocManager, times(1)).destroyBean(kansasActivity); }
/** * At the time this test was made, splash screens were handled as special cases because they're ApplicationScoped rather than Dependent. */ @Test public void shouldStopSplashScreensWhenDestroyed() throws Exception { List<SplashScreenActivity> splashScreenList = new ArrayList<SplashScreenActivity>(); SplashScreenActivity expectedSplashScreenActivity = makeEnabledSplashScreenThatIntercepts(kansas); splashScreenList.add(expectedSplashScreenActivity); when(activityBeansCache.getSplashScreens()).thenReturn(splashScreenList); SplashScreenActivity splashScreenActivity = activityManager.getSplashScreenInterceptor(kansas); activityManager.destroyActivity(splashScreenActivity); verify(expectedSplashScreenActivity, times(1)).onShutdown(); assertFalse(activityManager.isStarted(expectedSplashScreenActivity)); // never try to destroy singleton beans! verify(iocManager, never()).destroyBean(expectedSplashScreenActivity); }
@Test public void shouldNotAttemptToDestroyRuntimeRegisteredSingletonActivities() throws Exception { abstract class MyPerspectiveActivity implements PerspectiveActivity { } ; final String myPerspectiveId = "myPerspectiveId"; final MyPerspectiveActivity activity = mock(MyPerspectiveActivity.class); when(activity.getIdentifier()).thenReturn(myPerspectiveId); when(activity.getPlace()).thenReturn(new DefaultPlaceRequest(myPerspectiveId)); // note that we're telling the bean manager this bean is of concrete type PerspectiveActivity. // this mirrors what the JavaScript runtime plugin API does. SyncBeanDef<PerspectiveActivity> perspectiveActivityBean = makeSingletonBean(PerspectiveActivity.class, activity, myPerspectiveId); when(activityBeansCache.getActivity(myPerspectiveId)).thenReturn((SyncBeanDef) perspectiveActivityBean); Activity retrievedActivity = activityManager.getActivity(Activity.class, new DefaultPlaceRequest(myPerspectiveId)); activityManager.destroyActivity(retrievedActivity); // it's a singleton, so we should not try to destroy it. verify(iocManager, never()).destroyBean(activity); }
/** * At the time this test was made, splash screens were handled as special cases because they're ApplicationScoped rather than Dependent. */ @Test public void shouldThrowExceptionWhenDoubleDestroyingSplashScreen() throws Exception { List<SplashScreenActivity> splashScreenList = new ArrayList<SplashScreenActivity>(); SplashScreenActivity expectedSplashScreenActivity = makeEnabledSplashScreenThatIntercepts(kansas); splashScreenList.add(expectedSplashScreenActivity); when(activityBeansCache.getSplashScreens()).thenReturn(splashScreenList); SplashScreenActivity splashScreenActivity = activityManager.getSplashScreenInterceptor(kansas); activityManager.destroyActivity(splashScreenActivity); try { activityManager.destroyActivity(splashScreenActivity); fail("should have thrown exception on double destroy"); } catch (IllegalStateException e) { // expected } verify(expectedSplashScreenActivity, times(1)).onShutdown(); // never try to destroy singleton beans! verify(iocManager, never()).destroyBean(expectedSplashScreenActivity); }
@Test public void lookupShouldReturnNullWhenPlaceHasNoSplashScreen() throws Exception { SplashScreenActivity splashScreenActivity = activityManager.getSplashScreenInterceptor(kansas); assertNull(splashScreenActivity); }
private <T extends Activity> T startIfNecessary(T activity, PlaceRequest place) { if (activity == null) { return null; } try { if (!startedActivities.containsKey(activity)) { startedActivities.put(activity, place); if (activity.isDynamic() && place instanceof PathPlaceRequest) { activity.onStartup(ExternalPathPlaceRequest.create((PathPlaceRequest) place)); } else { activity.onStartup(place); } } return activity; } catch (Exception ex) { lifecycleErrorHandler.handle(activity, LifecyclePhase.STARTUP, ex); destroyActivity(activity); return null; } }
@Override public void destroyActivity(final Activity activity) { if (startedActivities.remove(activity) != null) { boolean isDependentScope = getBeanScope(activity) == Dependent.class; try { activity.onShutdown(); } catch (Exception ex) { lifecycleErrorHandler.handle(activity, LifecyclePhase.SHUTDOWN, ex); } if (isDependentScope) { iocManager.destroyBean(activity); } } else { throw new IllegalStateException("Activity " + activity + " is not currently in the started state"); } }
@Test public void shouldNotGetConfusedAboutSplashScreensWithSamePlaceAsTheirScreen() throws Exception { List<SplashScreenActivity> splashScreenList = new ArrayList<SplashScreenActivity>(); SplashScreenActivity expectedSplashScreenActivity = makeEnabledSplashScreenThatIntercepts(kansas); when(expectedSplashScreenActivity.getPlace()).thenReturn(kansas); splashScreenList.add(expectedSplashScreenActivity); when(activityBeansCache.getSplashScreens()).thenReturn(splashScreenList); // this loads the regular kansas activity (not the splash screen) into the activityBeansCache activityManager.getActivity(kansas); SplashScreenActivity splashScreenActivity = activityManager.getSplashScreenInterceptor(kansas); // this must not get confused even though expectedSplashScreenActivity and kansasActivity both have the same PlaceRequest activityManager.destroyActivity(splashScreenActivity); verify(expectedSplashScreenActivity, times(1)).onShutdown(); assertFalse(activityManager.isStarted(expectedSplashScreenActivity)); // never try to destroy singleton beans! verify(iocManager, never()).destroyBean(expectedSplashScreenActivity); }
@Test public void shouldCallOnShutdownWhenDestroyingActivity() throws Exception { activityManager.getActivities(kansas); activityManager.destroyActivity(kansasActivity); verify(kansasActivity, times(1)).onShutdown(); verify(iocManager, times(1)).destroyBean(kansasActivity); }
/** * At the time this test was made, splash screens were handled as special cases because they're ApplicationScoped rather than Dependent. */ @Test public void shouldStopSplashScreensWhenDestroyed() throws Exception { List<SplashScreenActivity> splashScreenList = new ArrayList<SplashScreenActivity>(); SplashScreenActivity expectedSplashScreenActivity = makeEnabledSplashScreenThatIntercepts(kansas); splashScreenList.add(expectedSplashScreenActivity); when(activityBeansCache.getSplashScreens()).thenReturn(splashScreenList); SplashScreenActivity splashScreenActivity = activityManager.getSplashScreenInterceptor(kansas); activityManager.destroyActivity(splashScreenActivity); verify(expectedSplashScreenActivity, times(1)).onShutdown(); assertFalse(activityManager.isStarted(expectedSplashScreenActivity)); // never try to destroy singleton beans! verify(iocManager, never()).destroyBean(expectedSplashScreenActivity); }
@Test public void shouldNotAttemptToDestroyRuntimeRegisteredSingletonActivities() throws Exception { abstract class MyPerspectiveActivity implements PerspectiveActivity { } ; final String myPerspectiveId = "myPerspectiveId"; final MyPerspectiveActivity activity = mock(MyPerspectiveActivity.class); when(activity.getIdentifier()).thenReturn(myPerspectiveId); when(activity.getPlace()).thenReturn(new DefaultPlaceRequest(myPerspectiveId)); // note that we're telling the bean manager this bean is of concrete type PerspectiveActivity. // this mirrors what the JavaScript runtime plugin API does. SyncBeanDef<PerspectiveActivity> perspectiveActivityBean = makeSingletonBean(PerspectiveActivity.class, activity, myPerspectiveId); when(activityBeansCache.getActivity(myPerspectiveId)).thenReturn((SyncBeanDef) perspectiveActivityBean); Activity retrievedActivity = activityManager.getActivity(Activity.class, new DefaultPlaceRequest(myPerspectiveId)); activityManager.destroyActivity(retrievedActivity); // it's a singleton, so we should not try to destroy it. verify(iocManager, never()).destroyBean(activity); }
/** * At the time this test was made, splash screens were handled as special cases because they're ApplicationScoped rather than Dependent. */ @Test public void shouldThrowExceptionWhenDoubleDestroyingSplashScreen() throws Exception { List<SplashScreenActivity> splashScreenList = new ArrayList<SplashScreenActivity>(); SplashScreenActivity expectedSplashScreenActivity = makeEnabledSplashScreenThatIntercepts(kansas); splashScreenList.add(expectedSplashScreenActivity); when(activityBeansCache.getSplashScreens()).thenReturn(splashScreenList); SplashScreenActivity splashScreenActivity = activityManager.getSplashScreenInterceptor(kansas); activityManager.destroyActivity(splashScreenActivity); try { activityManager.destroyActivity(splashScreenActivity); fail("should have thrown exception on double destroy"); } catch (IllegalStateException e) { // expected } verify(expectedSplashScreenActivity, times(1)).onShutdown(); // never try to destroy singleton beans! verify(iocManager, never()).destroyBean(expectedSplashScreenActivity); }
@Test public void lookupShouldReturnNullWhenPlaceHasNoSplashScreen() throws Exception { SplashScreenActivity splashScreenActivity = activityManager.getSplashScreenInterceptor(kansas); assertNull(splashScreenActivity); }
@Override public <T extends Activity> T getActivity(final Class<T> clazz, final PlaceRequest placeRequest, final boolean secure) { final Set<Activity> activities = getActivities(placeRequest, secure); if (activities.size() == 0) { return null; } final Activity activity = activities.iterator().next(); return (T) activity; }
@Test public void shouldThrowExceptionWhenDestroyingDestroyedActivity() throws Exception { activityManager.getActivities(kansas); activityManager.destroyActivity(kansasActivity); try { activityManager.destroyActivity(kansasActivity); fail("second destroy should have thrown an exception"); } catch (IllegalStateException e) { // expected } verify(kansasActivity, times(1)).onShutdown(); verify(iocManager, times(1)).destroyBean(kansasActivity); }