Skip to content
Browse files

more unit tests of refresh and dependency correctness

git-svn-id: http://svn.trampolinesystems.com/springy/trunk@8565 7bcaa5c2-c9d6-0310-8dd4-ca458a8cac41
  • Loading branch information...
1 parent c92778e commit 2a51a9ffabe1d42daed7f4cfda15bb20222f293b @trampoline trampoline committed Sep 12, 2007
View
61 src/main/java/springy/context/AbstractSpringyApplicationContext.java
@@ -7,6 +7,9 @@
import org.springframework.core.io.Resource;
import org.springframework.core.io.ByteArrayResource;
+import java.util.List;
+import java.util.ArrayList;
+
/**
* AbstractSpringyApplicationContext
*/
@@ -79,32 +82,76 @@ public Object getBeanAndMarkDirty(String name) throws BeansException
throw new NoSuchBeanDefinitionException( name );
}
- synchronized private void refreshIfDirty()
+ /** refresh this context if it has been marked dirty, or it's dependencies have been refreshed
+ * @return true if the context was refreshed */
+ synchronized private boolean refreshIfNeeded( boolean dependencyRefreshed )
{
- if ( dirty )
+ if ( dirty || dependencyRefreshed )
{
refresh();
dirty = false;
+ return true;
+ }
+ else
+ {
+ return false;
}
}
- /** ascends the chain of contexts, refreshing any ApplicationCntexts containing beans
- * marked as dirty [ by a <code>getBeanAndDirty</code> call ]
+ /** descends the chain of contexts from the root, refreshing any ApplicationContexts containing beans
+ * marked as dirty [ by a <code>getBeanAndDirty</code> call ], and their dependent ApplicationContexts
*/
public void refreshAllDirtyContexts()
{
ApplicationContext context = this;
+ // get a list of the chain of ApplicationContexts
+ List<ApplicationContext> contextList = new ArrayList<ApplicationContext>();
while( context != null )
{
+ contextList.add( context );
+ context = context.getParent();
+ }
+
+ // go from root to leaf [i.e. reverse list order],
+ // looking for dirty contexts. once a dirty countext
+ // is found, refresh all contexts from there to [including] the leaf
+
+ boolean refresh = false;
+ for( int i = contextList.size() - 1 ; i>= 0 ; i-- )
+ {
+ context = contextList.get( i );
+
if ( context instanceof AbstractSpringyApplicationContext )
{
AbstractSpringyApplicationContext rsc = (AbstractSpringyApplicationContext)context;
- rsc.refreshIfDirty();
- }
+ refresh = refresh | rsc.refreshIfNeeded( refresh );
- context = context.getParent();
+ if ( refresh )
+ {
+ // System.err.println( "refreshing SpringyApplicationContext: " + rsc.getDisplayName() );
+ }
+ }
+ else if ( context instanceof AbstractRefreshableApplicationContext )
+ {
+ AbstractRefreshableApplicationContext rc = (AbstractRefreshableApplicationContext)context;
+ if ( refresh )
+ {
+ rc.refresh();
+ // System.err.println( "refreshing AbstractRefreshableApplicationContext: " + rc.getDisplayName() );
+ }
+ }
+ else
+ {
+ if ( refresh )
+ {
+ throw new IllegalStateException( "dependent ApplicationContext has been refreshed, so this ApplicationContext requires refresh, but doesn't support it: " + context.getDisplayName() );
+ }
+ }
}
+
+
+
}
}
View
5 src/main/java/springy/context/BSFSpringyContext.java
@@ -89,7 +89,8 @@ public BSFSpringyContext(BSFManager bsfManager, boolean refresh , Resource... co
this.bsfManager = bsfManager;
this.contextResource = thisContextResource( contextResources );
-
+ this.setDisplayName( contextResource.getDescription() );
+
if (refresh) {
refresh();
}
@@ -120,7 +121,7 @@ protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throw
String ctxt = IOHelper.inputStreamToString(contextResource.getInputStream());
bsfManager.eval("ruby", "(springy-parse-prepare-fragment)", 1, 1, springy);
- bsfManager.eval("ruby", contextResource.getFilename() , 1, 1, ctxt);
+ bsfManager.eval("ruby", contextResource.getDescription() , 1, 1, ctxt);
} catch (BSFException e) {
//JRubyHelper.printBsfException(e);
View
4 src/main/java/springy/context/RuntimeSpringyContext.java
@@ -80,6 +80,8 @@ public RuntimeSpringyContext(Ruby runtime, boolean refresh, Resource... contextR
this.runtime = runtime;
this.contextResource = thisContextResource( contextResources );
+ this.setDisplayName( contextResource.getDescription() );
+
if (refresh) {
refresh();
}
@@ -94,7 +96,7 @@ protected void loadBeanDefinitions(final DefaultListableBeanFactory beanFactory)
try {
runtime.evalScript(new StringReader(springy), "(springy-parse-prepare-fragment)");
- runtime.evalScript(new StringReader(ctxt), contextResource.getFilename() );
+ runtime.evalScript(new StringReader(ctxt), contextResource.getDescription() );
} catch (RaiseException rex) {
System.err.println(rex.getException().toString());
View
54 src/test/java/springy/RefreshContextTests.java
@@ -9,6 +9,7 @@
import springy.beans.Bean6;
import springy.beans.Bean1;
import springy.beans.Bean7;
+import springy.beans.Bean8;
/**
* RefreshContextTests
@@ -19,7 +20,7 @@
public RuntimeSpringyContext createContext() throws Exception {
return new RuntimeSpringyContext(Ruby.getDefaultInstance(),
new ClassPathResource( "springy/parent_context.rb" ),
- new ClassPathResource("springy/context.rb"));
+ new ClassPathResource("springy/child_context.rb"));
}
public void testContextChainCreation() throws Exception
@@ -72,6 +73,7 @@ public void MarkDirty() throws Exception
Assert.assertNotSame( bean , newBean );
Assert.assertEquals( 0 , newBean.getCount() );
}
+
public void testRefreshDirtyOnly() throws Exception
{
RuntimeSpringyContext ctx = createContext();
@@ -100,6 +102,33 @@ public void testRefreshDirtyOnly() throws Exception
}
+ public void testRefreshDependent() throws Exception
+ {
+ RuntimeSpringyContext ctx = createContext();
+
+ Bean6 parentBean = (Bean6) ctx.getBeanAndMarkDirty( "parent_bean" );
+ parentBean.incrCount();
+ parentBean = (Bean6) ctx.getBean( "parent_bean" );
+ Assert.assertEquals( parentBean.getCount() , 1 );
+
+ // change the state of a bean in the child context, without dirtying it
+ Bean6 childBean = (Bean6)ctx.getBean( "bean6" );
+ childBean.incrCount();
+ childBean = (Bean6) ctx.getBean( "bean6" );
+ Assert.assertEquals( childBean.getCount() , 1 );
+
+ ctx.refreshAllDirtyContexts();
+
+ // check that the bean from the parent context has been renewed
+ Bean6 newParentBean = (Bean6) ctx.getBean( "parent_bean" );
+ Assert.assertEquals( newParentBean.getCount() , 0 );
+
+ // check that the bean from the child context has also been renewed
+ Bean6 newChildBean = (Bean6) ctx.getBean( "bean6" );
+ Assert.assertEquals( newChildBean.getCount() , 0 );
+
+ }
+
public void testStaticBeanDispose() throws Exception
{
RuntimeSpringyContext ctx = createContext();
@@ -113,4 +142,27 @@ public void testStaticBeanDispose() throws Exception
Assert.assertEquals( newDisposerCount , disposerCount + 1 );
}
+
+ public void testDependentBean() throws Exception
+ {
+ RuntimeSpringyContext ctx = createContext();
+
+ Bean6 parent = (Bean6) ctx.getBeanAndMarkDirty( "parent_bean" );
+ parent.incrCount();
+ Assert.assertEquals( parent.getCount() , 1 );
+
+ Bean8 bean8 = (Bean8)ctx.getBean( "bean8" );
+ Assert.assertSame( bean8.getBean6() , parent );
+
+ ctx.refreshAllDirtyContexts();
+
+ Bean8 newBean8 = (Bean8)ctx.getBean( "bean8" );
+ Bean6 newParent = newBean8.getBean6();
+
+ Assert.assertNotSame( parent , newParent );
+ Assert.assertNotSame( bean8 , newBean8 );
+
+ Assert.assertEquals( newParent.getCount() , 0 );
+ }
+
}
View
1 src/test/java/springy/beans/Bean7.java
@@ -4,6 +4,7 @@
* Bean7
*/
public class Bean7
+ implements IBean
{
public static int disposerCount;
View
25 src/test/java/springy/beans/Bean8.java
@@ -0,0 +1,25 @@
+package springy.beans;
+
+/**
+ * Bean8
+ */
+public class Bean8
+ implements IBean
+{
+ private Bean6 bean6;
+
+ public Bean8(Bean6 bean6)
+ {
+ this.bean6 = bean6;
+ }
+
+ public Bean6 getBean6()
+ {
+ return bean6;
+ }
+
+ public void setBean6(Bean6 bean6)
+ {
+ this.bean6 = bean6;
+ }
+}
View
11 src/test/resources/springy/child_context.rb
@@ -0,0 +1,11 @@
+
+# just a disposer
+static_bean "springy.beans.Bean7" do |i,d|
+ d.disposerMethod
+end
+
+bean :bean6, "springy.beans.Bean6"
+
+bean :bean8, "springy.beans.Bean8" do |b|
+ b.new( :parent_bean )
+end
View
6 src/test/resources/springy/context.rb
@@ -82,4 +82,8 @@
b.set_before_init_called if b.respond_to?(:set_before_init_called)
end
-bean :bean6, "springy.beans.Bean6"
+bean :bean6, "springy.beans.Bean6"
+
+#bean :bean8, "springy.beans.Bean8" do |b|
+# b.new( :parent_bean )
+#end

0 comments on commit 2a51a9f

Please sign in to comment.
Something went wrong with that request. Please try again.