OptionsImpl implements IOptions, IShutdownListener { protected void propsFileUpdateNotify(Properties updatedProps, long sequence) { if(aggregator == null || aggregator.getPlatformServices() == null || !loadFromPropertiesFile) return; IPlatformServices platformServices = aggregator.getPlatformServices(); try { IServiceReference[] refs = platformServices.getServiceReferences(OptionsImpl.class.getName(), "(propsFileName=" + getPropsFile().getAbsolutePath().replace("\\", "\\\\") + ")"); if (refs != null) { for (IServiceReference ref : refs) { String name = ref.getProperty("name"); if (!registrationName.equals(name)) { OptionsImpl impl = (OptionsImpl)platformServices.getService(ref); if (impl != null) { try { impl.propertiesFileUpdated(updatedProps, sequence); } catch (Throwable ignore) {} finally { platformServices.ungetService(ref); } } } } } } catch (PlatformServicesException e) { if (log.isLoggable(Level.SEVERE)) { log.log(Level.SEVERE, e.getMessage(), e); } } } OptionsImpl(boolean loadFromPropertiesFile, IAggregator aggregator); @Override boolean isVerifyDeps(); @Override boolean isDisableRequireListExpansion(); @Override boolean isDevelopmentMode(); @Override boolean isDebugMode(); @Override boolean isSourceMapsEnabled(); @Override boolean isDisableHasFiltering(); @Override boolean isDisableHasPluginBranching(); @Override boolean isDisableModuleNameIdEncoding(); @Override String getCacheBust(); @Override String getCacheDirectory(); @Override int getDeleteDelay(); @Override void setOption(String name, boolean value); @Override synchronized void setOption(String name, String value); @Override String getOption(String name); @Override Map<String, String> getOptionsMap(); @Override String getName(); @Override Map<String, String> getDefaultOptionsMap(); String getPropsFilename(); File getPropsFile(); @Override void shutdown(IAggregator aggregator);  }
@Test public void testPropsFileUpdateNotify() throws Exception { final File propsFile = new File("test.properties"); final OptionsImpl options = new OptionsImpl(true, null) { @Override public File getPropsFile() { return propsFile; } @Override public void saveProps(Properties props) { } }; options.setOption("foo", "bar"); final int[] callCounts = new int[]{0, 0}; IAggregator mockAggregator = EasyMock.createNiceMock(IAggregator.class); IPlatformServices mockPlatformServices = EasyMock.createMock(IPlatformServices.class); IServiceReference[] mockServiceRefs = new IServiceReference[] { EasyMock.createMock(IServiceReference.class), EasyMock.createMock(IServiceReference.class) }; Whitebox.setInternalState(options, "aggregator", mockAggregator); Whitebox.setInternalState(options, "registrationName", "test"); EasyMock.expect(mockAggregator.getPlatformServices()).andReturn(mockPlatformServices).anyTimes(); EasyMock.expect(mockPlatformServices.getServiceReferences( OptionsImpl.class.getName(), "(propsFileName=" + propsFile.getAbsolutePath().replace("\\", "\\\\") + ")") ).andReturn(mockServiceRefs); EasyMock.expect(mockServiceRefs[0].getProperty("name")).andReturn("test"); EasyMock.expect(mockServiceRefs[1].getProperty("name")).andReturn("otherTest"); EasyMock.expect(mockPlatformServices.getService(mockServiceRefs[1])).andAnswer(new IAnswer<Object>() { @Override public Object answer() throws Throwable { return new OptionsImpl(false, null) { @Override public void propertiesFileUpdated(Properties props, long sequence) { callCounts[1]++; Assert.assertEquals("bar", props.get("foo")); Assert.assertEquals(1L, sequence); throw new RuntimeException(); } }; } }); EasyMock.expect(mockPlatformServices.ungetService(mockServiceRefs[1])).andReturn(true); EasyMock.replay(mockAggregator, mockPlatformServices, mockServiceRefs[0], mockServiceRefs[1]); options.propsFileUpdateNotify(options.getProps(), 1L); EasyMock.verify(mockAggregator, mockPlatformServices, mockServiceRefs[0], mockServiceRefs[1]); Assert.assertEquals(0, callCounts[0]); Assert.assertEquals(1, callCounts[1]); }