Mercurial > hg > blitz_condensed
diff src/org/dancres/blitz/remote/LookupStorage.java @ 0:3dc0c5604566
Initial checkin of blitz 2.0 fcs - no installer yet.
author | Dan Creswell <dan.creswell@gmail.com> |
---|---|
date | Sat, 21 Mar 2009 11:00:06 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/org/dancres/blitz/remote/LookupStorage.java Sat Mar 21 11:00:06 2009 +0000 @@ -0,0 +1,201 @@ +package org.dancres.blitz.remote; + +import java.io.File; +import java.io.Serializable; +import java.io.IOException; +import java.io.FileOutputStream; +import java.io.ObjectOutputStream; +import java.io.FileInputStream; +import java.io.ObjectInputStream; + +import java.util.logging.Level; +import java.util.BitSet; + +import net.jini.core.entry.Entry; + +import net.jini.config.Configuration; +import net.jini.config.ConfigurationException; + +import net.jini.id.Uuid; + +import net.jini.core.lookup.ServiceID; + +import net.jini.discovery.DiscoveryManagement; + +import net.jini.lookup.JoinManager; + +import org.dancres.util.BytePacker; + +import org.dancres.blitz.config.ConfigurationFactory; + +import org.dancres.blitz.meta.Registry; +import org.dancres.blitz.meta.RegistryAccessor; +import org.dancres.blitz.meta.RegistryFactory; +import org.dancres.blitz.meta.Initializer; + +import org.dancres.blitz.disk.Disk; +import org.dancres.blitz.disk.DiskTxn; +import org.dancres.blitz.disk.Syncable; + +/** + This class is responsible for managing JoinManagement state saving to + and reloading from disk as required. + + @todo Need logging somewhere + */ +public class LookupStorage implements Syncable { + public static final byte INIT_ATTRS = 1; + public static final byte INIT_LOCATORS = 2; + public static final byte INIT_GROUPS = 4; + + private static final String JOIN_STATE = "BlitzJoinState"; + + private static byte[] JOIN_STATE_KEY = new byte[12]; + + static { + BytePacker myPacker = BytePacker.getMSBPacker(JOIN_STATE_KEY); + myPacker.putInt(0, 1); + } + + private LookupData theData; + + private Registry theRegistry; + + public LookupStorage() throws ConfigurationException { + } + + /** + * Load state from disk or create from scratch + * + * Warning: not thread-safe + */ + public void init(Configuration aConfig) throws ConfigurationException { + try { + theRegistry = + RegistryFactory.get(JOIN_STATE, new RegistryInit(aConfig)); + Disk.add(this); + + DiskTxn myTxn = DiskTxn.newTxn(); + + theData = (LookupData) + theRegistry.getAccessor().load(JOIN_STATE_KEY); + + myTxn.commit(); + + // Display recovered settings for user + theData.dump(); + } catch (Exception anE) { + BlitzServiceImpl.theLogger.log(Level.SEVERE, + "Exceptioned loading state", + anE); + throw new ConfigurationException("Failed to load join state", + anE); + } + } + + /** + * Recover previous state (if it's not already loaded) and then + * overwrite selected settings. Make sure to call saveState + * + * Warning: not thread-safe + */ + public void reinit(Configuration aConfig, byte aFlags) + throws ConfigurationException { + + if (theRegistry == null) + init(aConfig); + + if ((aFlags & INIT_ATTRS) != 0) { + theData.initAttrs(aConfig); + } + + if ((aFlags & INIT_LOCATORS) != 0) { + theData.initLocators(aConfig); + } + + if ((aFlags & INIT_GROUPS) != 0) { + theData.initGroups(aConfig); + } + } + + public void sync() throws Exception { + // Always in sync + } + + public void close() throws Exception { + theRegistry.close(); + } + + /** + Recover a DiscoveryManagement object pre-configured with settings. + */ + DiscoveryManagement getDiscMgt() throws ConfigurationException { + return theData.getLookupDiscovery(); + } + + /** + Each JINI service has a unique (well, not quite) id + */ + ServiceID getServiceID() { + return theData.getServiceID(); + } + + Uuid getUuid() { + return theData.getUuid(); + } + + /** + Recover any descriptive attributes to be advertised as part of the + registration. + */ + Entry[] getAttributes() throws IOException { + return theData.getAttributes(); + } + + synchronized void sync(JoinManager aMgr) throws IOException { + theData.update(aMgr); + saveState(); + theData.dump(); + } + + public synchronized void saveState() throws IOException { + DiskTxn myTxn = DiskTxn.newTxn(); + + theRegistry.getAccessor().save(JOIN_STATE_KEY, theData); + + myTxn.commit(); + } + + private class RegistryInit implements Initializer { + private boolean wasExecuted; + + private Configuration theConfig; + + RegistryInit(Configuration aConfig) { + theConfig = aConfig; + } + + public void execute(RegistryAccessor anAccessor) throws IOException { + + LookupData myData = new LookupData(); + + try { + myData.init(theConfig); + } catch (ConfigurationException aCE) { + BlitzServiceImpl.theLogger.log(Level.SEVERE, + "Exceptioned init'ing state", + aCE); + throw new IOException("Failed to init state"); + } catch (Throwable aT) { + BlitzServiceImpl.theLogger.log(Level.SEVERE, + "Exceptioned init'ing state", + aT); + throw new IOException("Failed to init state"); + } + + myData.dump(); + + anAccessor.save(JOIN_STATE_KEY, myData); + } + } +}