Methods Summary |
---|
private static void | enumerateBindings(javax.naming.NamingEnumeration bindings, java.util.Properties properties)Scans each binding on JNDI context and determines if any binding is an
instance of SyncProvider, if so, add this to the registry and continue to
scan the current context using a re-entrant call to this method until all
bindings have been enumerated.
boolean syncProviderObj = false; // move to parameters ?
try {
Binding bd = null;
Object elementObj = null;
String element = null;
while (bindings.hasMore()) {
bd = (Binding)bindings.next();
element = bd.getName();
elementObj = bd.getObject();
if (!(ic.lookup(element) instanceof Context)) {
// skip directories/sub-contexts
if (ic.lookup(element) instanceof SyncProvider) {
syncProviderObj = true;
}
}
if (syncProviderObj) {
SyncProvider sync = (SyncProvider)elementObj;
properties.put(SyncFactory.ROWSET_SYNC_PROVIDER,
sync.getProviderID());
syncProviderObj = false; // reset
}
}
} catch (javax.naming.NotContextException e) {
bindings.next();
// Re-entrant call into method
enumerateBindings(bindings, properties);
}
|
public static javax.sql.rowset.spi.SyncProvider | getInstance(java.lang.String providerID)Returns the SyncProvider instance identified by providerID.
initMapIfNecessary(); // populate HashTable
initJNDIContext(); // check JNDI context for any additional bindings
ProviderImpl impl = (ProviderImpl)implementations.get(providerID);
if (impl == null) {
// Requested SyncProvider is unavailable. Return default provider.
return new com.sun.rowset.providers.RIOptimisticProvider();
}
// Attempt to invoke classname from registered SyncProvider list
Class c = null;
try {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
/**
* The SyncProvider implementation of the user will be in
* the classpath. We need to find the ClassLoader which loads
* this SyncFactory and try to laod the SyncProvider class from
* there.
**/
c = Class.forName(providerID, true, cl);
if (c != null) {
return (SyncProvider)c.newInstance();
} else {
return new com.sun.rowset.providers.RIOptimisticProvider();
}
} catch (IllegalAccessException e) {
throw new SyncFactoryException("IllegalAccessException: " + e.getMessage());
} catch (InstantiationException e) {
throw new SyncFactoryException("InstantiationException: " + e.getMessage());
} catch (ClassNotFoundException e) {
throw new SyncFactoryException("ClassNotFoundException: " + e.getMessage());
}
|
public static java.util.logging.Logger | getLogger()Returns the logging object for applications to retrieve
synchronization events posted by SyncProvider implementations.
// only one logger per session
if(rsLogger == null){
throw new SyncFactoryException("(SyncFactory) : No logger has been set");
}
return rsLogger;
|
private static java.lang.String[] | getPropertyNames(boolean append)Used by the parseProperties methods to disassemble each property tuple.
return getPropertyNames(append, null);
|
private static java.lang.String[] | getPropertyNames(boolean append, java.lang.String propertyIndex)Disassembles each property and its associated value. Also handles
overloaded property names that contain indexes.
String dot = ".";
String[] propertyNames =
new String[] {SyncFactory.ROWSET_SYNC_PROVIDER,
SyncFactory.ROWSET_SYNC_VENDOR,
SyncFactory.ROWSET_SYNC_PROVIDER_VERSION};
if (append) {
for (int i = 0; i < propertyNames.length; i++) {
propertyNames[i] = propertyNames[i] +
dot +
propertyIndex;
}
return propertyNames;
} else {
return propertyNames;
}
|
public static java.util.Enumeration | getRegisteredProviders()Returns an Enumeration of currently registered synchronization
providers. A RowSet implementation may use any provider in
the enumeration as its SyncProvider object.
At a minimum, the reference synchronization provider allowing
RowSet content data to be stored using a JDBC driver should be
possible.
initMapIfNecessary();
// return a collection of classnames
// of type SyncProvider
return implementations.elements();
|
public static javax.sql.rowset.spi.SyncFactory | getSyncFactory()Returns the SyncFactory singleton.
// This method uses the Singleton Design Pattern
// with Double-Checked Locking Pattern for
// 1. Creating single instance of the SyncFactory
// 2. Make the class thread safe, so that at one time
// only one thread enters the synchronized block
// to instantiate.
// if syncFactory object is already there
// don't go into synchronized block and return
// that object.
// else go into synchronized block
if(syncFactory == null){
synchronized(SyncFactory.class) {
if(syncFactory == null){
syncFactory = new SyncFactory();
} //end if
} //end synchronized block
} //end if
return syncFactory;
|
private static void | initJNDIContext()Controls JNDI context intialization.
if (jndiCtxEstablished && (ic != null) && (lazyJNDICtxRefresh == false)) {
try {
parseProperties(parseJNDIContext());
lazyJNDICtxRefresh = true; // touch JNDI namespace once.
} catch (NamingException e) {
e.printStackTrace();
throw new SyncFactoryException("SPI: NamingException: " + e.getExplanation());
} catch (Exception e) {
e.printStackTrace();
throw new SyncFactoryException("SPI: Exception: " + e.getMessage());
}
}
|
private static synchronized void | initMapIfNecessary()
// Local implementation class names and keys from Properties
// file, translate names into Class objects using Class.forName
// and store mappings
Properties properties = new Properties();
if (implementations == null) {
implementations = new Hashtable();
try {
// check if user is supplying his Synchronisation Provider
// Implementation if not use Sun's implementation.
// properties.load(new FileInputStream(ROWSET_PROPERTIES));
// The rowset.properties needs to be in jdk/jre/lib when
// integrated with jdk.
// else it should be picked from -D option from command line.
// -Drowset.properties will add to standard properties. Similar
// keys will over-write
/*
* Dependent on application
*/
String strRowsetProperties = System.getProperty("rowset.properties");
if ( strRowsetProperties != null) {
// Load user's implementation of SyncProvider
// here. -Drowset.properties=/abc/def/pqr.txt
ROWSET_PROPERTIES = strRowsetProperties;
properties.load(new FileInputStream(ROWSET_PROPERTIES));
parseProperties(properties);
}
/*
* Always available
*/
ROWSET_PROPERTIES = "javax" + strFileSep + "sql" +
strFileSep + "rowset" + strFileSep +
"rowset.properties";
// properties.load(
// ClassLoader.getSystemResourceAsStream(ROWSET_PROPERTIES));
ClassLoader cl = Thread.currentThread().getContextClassLoader();
properties.load(cl.getResourceAsStream(ROWSET_PROPERTIES));
parseProperties(properties);
// removed else, has properties should sum together
} catch (FileNotFoundException e) {
throw new SyncFactoryException("Cannot locate properties file: " + e);
} catch (IOException e) {
throw new SyncFactoryException("IOException: " + e);
}
/*
* Now deal with -Drowset.provider.classname
* load additional properties from -D command line
*/
properties.clear();
String providerImpls = System.getProperty(ROWSET_SYNC_PROVIDER);
if (providerImpls != null) {
int i = 0;
if (providerImpls.indexOf(colon) > 0) {
StringTokenizer tokenizer = new StringTokenizer(providerImpls, colon);
while (tokenizer.hasMoreElements()) {
properties.put(ROWSET_SYNC_PROVIDER + "." + i, tokenizer.nextToken());
i++;
}
} else {
properties.put(ROWSET_SYNC_PROVIDER, providerImpls);
}
parseProperties(properties);
}
}
|
private static java.util.Properties | parseJNDIContext()Parses the set JNDI Context and passes bindings to the enumerateBindings
method when complete.
NamingEnumeration bindings = ic.listBindings("");
Properties properties = new Properties();
// Hunt one level below context for available SyncProvider objects
enumerateBindings(bindings, properties);
return properties;
|
private static void | parseProperties(java.util.Properties p)Internal handler for all standard property parsing. Parses standard
ROWSET properties and stores lazy references into the the internal registry.
ProviderImpl impl = null;
String key = null;
String[] propertyNames = null;
for (Enumeration e = p.propertyNames(); e.hasMoreElements() ;) {
String str = (String)e.nextElement();
int w = str.length();
if (str.startsWith(SyncFactory.ROWSET_SYNC_PROVIDER)) {
impl = new ProviderImpl();
impl.setIndex(providerImplIndex++);
if (w == (SyncFactory.ROWSET_SYNC_PROVIDER).length()) {
// no property index has been set.
propertyNames = getPropertyNames(false);
} else {
// property index has been set.
propertyNames = getPropertyNames(true, str.substring(w-1));
}
key = p.getProperty(propertyNames[0]);
impl.setClassname(key);
impl.setVendor(p.getProperty(propertyNames[1]));
impl.setVersion(p.getProperty(propertyNames[2]));
implementations.put(key, impl);
}
}
|
public static synchronized void | registerProvider(java.lang.String providerID)Adds the the given synchronization provider to the factory register. Guidelines
are provided in the SyncProvider specification for the
required naming conventions for SyncProvider
implementations.
Synchronization providers bound to a JNDI context can be
registered by binding a SyncProvider instance to a JNDI namespace.
SyncProvider p = new MySyncProvider();
InitialContext ic = new InitialContext();
ic.bind ("jdbc/rowset/MySyncProvider", p);
Furthermore, an initial JNDI context should be set with the
SyncFactory using the setJNDIContext method.
The SyncFactory leverages this context to search for
available SyncProvider objects bound to the JNDI
context and its child nodes.
ProviderImpl impl = new ProviderImpl();
impl.setClassname(providerID);
initMapIfNecessary();
implementations.put(providerID, impl);
|
public static void | setJNDIContext(javax.naming.Context ctx)Sets the initial JNDI context from which SyncProvider implementations
can be retrieved from a JNDI namespace
if (ctx == null) {
throw new SyncFactoryException("Invalid JNDI context supplied");
}
ic = ctx;
jndiCtxEstablished = true;
|
public static void | setLogger(java.util.logging.Logger logger)Sets the logging object to be used by the SyncProvider
implementation provided by the SyncFactory . All
SyncProvider implementations can log their events to
this object and the application can retrieve a handle to this
object using the getLogger method.
rsLogger = logger;
|
public static void | setLogger(java.util.logging.Logger logger, java.util.logging.Level level)Sets the logging object that is used by SyncProvider
implementations provided by the SyncFactory SPI. All
SyncProvider implementations can log their events
to this object and the application can retrieve a handle to this
object using the getLogger method.
// singleton
rsLogger = logger;
rsLogger.setLevel(level);
|
private static void | showImpl(javax.sql.rowset.spi.ProviderImpl impl)Internal debug method that outputs the registry contents.
System.out.println("Provider implementation:");
System.out.println("Classname: " + impl.getClassname());
System.out.println("Vendor: " + impl.getVendor());
System.out.println("Version: " + impl.getVersion());
System.out.println("Impl index: " + impl.getIndex());
|
public static synchronized void | unregisterProvider(java.lang.String providerID)Removes the designated currently registered synchronization provider from the
Factory SPI register.
initMapIfNecessary();
if (implementations.containsKey(providerID)) {
implementations.remove(providerID);
}
|