diff -r d265f373c6e2 openide.awt/src/org/netbeans/modules/openide/awt/SavableRegistry.java --- a/openide.awt/src/org/netbeans/modules/openide/awt/SavableRegistry.java Mon May 23 17:33:20 2011 +0200 +++ b/openide.awt/src/org/netbeans/modules/openide/awt/SavableRegistry.java Mon May 23 17:59:59 2011 +0200 @@ -41,17 +41,19 @@ */ package org.netbeans.modules.openide.awt; +import java.io.IOException; +import org.netbeans.api.actions.Savable; import org.netbeans.spi.actions.AbstractSavable; +import org.openide.LifecycleManager; +import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.RequestProcessor; import org.openide.util.lookup.AbstractLookup; import org.openide.util.lookup.InstanceContent; +import org.openide.util.lookup.ServiceProvider; -/** - * - * @author Jaroslav Tulach - */ -public final class SavableRegistry { +@ServiceProvider(service=LifecycleManager.class) +public final class SavableRegistry extends LifecycleManager { private static final RequestProcessor RP = new RequestProcessor("Savable Registry"); private static final InstanceContent IC = new InstanceContent(RP); private static final Lookup LOOKUP = new AbstractLookup(IC); @@ -67,4 +69,19 @@ public static void unregister(AbstractSavable as) { IC.remove(as); } + + @Override + public void saveAll() { + for (Savable sa : getRegistry().lookupAll(Savable.class)) { + try { + sa.save(); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + } + + @Override + public void exit() { + } } diff -r d265f373c6e2 openide.awt/test/unit/src/org/netbeans/api/actions/SavableTest.java --- a/openide.awt/test/unit/src/org/netbeans/api/actions/SavableTest.java Mon May 23 17:33:20 2011 +0200 +++ b/openide.awt/test/unit/src/org/netbeans/api/actions/SavableTest.java Mon May 23 17:59:59 2011 +0200 @@ -45,6 +45,7 @@ import java.io.IOException; import org.netbeans.junit.NbTestCase; import org.netbeans.spi.actions.AbstractSavable; +import org.openide.LifecycleManager; import org.openide.util.Lookup.Result; import org.openide.util.LookupEvent; import org.openide.util.LookupListener; @@ -82,6 +83,22 @@ assertTrue("No other pending saves", Savable.REGISTRY.lookupAll(Savable.class).isEmpty()); } + public void testLifecycleSafe() throws IOException { + String id = "identity"; + DoSave savable = new DoSave(id, null, null); + assertNotNull("Savable created", savable); + + assertTrue( + "Is is among the list of savables that need save", + Savable.REGISTRY.lookupAll(Savable.class).contains(savable) + ); + + LifecycleManager.getDefault().saveAll(); + assertTrue("called", savable.save); + + assertTrue("No other pending saves", Savable.REGISTRY.lookupAll(Savable.class).isEmpty()); + } + public void testTwoSavablesForEqual() throws IOException { Object id = new Object(); diff -r d265f373c6e2 openide.util/src/org/openide/LifecycleManager.java --- a/openide.util/src/org/openide/LifecycleManager.java Mon May 23 17:33:20 2011 +0200 +++ b/openide.util/src/org/openide/LifecycleManager.java Mon May 23 17:59:59 2011 +0200 @@ -67,13 +67,7 @@ * @return the default instance (never null) */ public static LifecycleManager getDefault() { - LifecycleManager lm = Lookup.getDefault().lookup(LifecycleManager.class); - - if (lm == null) { - lm = new Trivial(); - } - - return lm; + return Proxy.INSTANCE; } /** Save all opened objects. @@ -96,16 +90,42 @@ throw new UnsupportedOperationException(); } - /** Fallback instance. */ - private static final class Trivial extends LifecycleManager { - public Trivial() { + private static final class Proxy extends LifecycleManager { + private static final Proxy INSTANCE = new Proxy(); + + private Proxy() { } + @Override public void exit() { + for (LifecycleManager lm : Lookup.getDefault().lookupAll(LifecycleManager.class)) { + lm.exit(); + } System.exit(0); } + @Override public void saveAll() { + for (LifecycleManager lm : Lookup.getDefault().lookupAll(LifecycleManager.class)) { + lm.saveAll(); + } + } + + @Override + public void markForRestart() throws UnsupportedOperationException { + UnsupportedOperationException thr = null; + for (LifecycleManager lm : Lookup.getDefault().lookupAll(LifecycleManager.class)) { + try { + lm.markForRestart(); + return; + } catch (UnsupportedOperationException ex) { + thr = ex; + } + } + if (thr == null) { + thr = new UnsupportedOperationException(); + } + throw thr; } } }