195 * @see javax.sql.rowset.spi.SyncProvider |
195 * @see javax.sql.rowset.spi.SyncProvider |
196 * @see javax.sql.rowset.spi.SyncFactoryException |
196 * @see javax.sql.rowset.spi.SyncFactoryException |
197 */ |
197 */ |
198 public class SyncFactory { |
198 public class SyncFactory { |
199 |
199 |
200 /* |
|
201 * The variable that represents the singleton instance |
|
202 * of the <code>SyncFactory</code> class. |
|
203 */ |
|
204 private static SyncFactory syncFactory = null; |
|
205 |
|
206 /** |
200 /** |
207 * Creates a new <code>SyncFactory</code> object, which is the singleton |
201 * Creates a new <code>SyncFactory</code> object, which is the singleton |
208 * instance. |
202 * instance. |
209 * Having a private constructor guarantees that no more than |
203 * Having a private constructor guarantees that no more than |
210 * one <code>SyncProvider</code> object can exist at a time. |
204 * one <code>SyncProvider</code> object can exist at a time. |
313 * Returns the <code>SyncFactory</code> singleton. |
307 * Returns the <code>SyncFactory</code> singleton. |
314 * |
308 * |
315 * @return the <code>SyncFactory</code> instance |
309 * @return the <code>SyncFactory</code> instance |
316 */ |
310 */ |
317 public static SyncFactory getSyncFactory() { |
311 public static SyncFactory getSyncFactory() { |
318 |
312 /* |
319 // This method uses the Singleton Design Pattern |
313 * Using Initialization on Demand Holder idiom as |
320 // with Double-Checked Locking Pattern for |
314 * Effective Java 2nd Edition,ITEM 71, indicates it is more performant |
321 // 1. Creating single instance of the SyncFactory |
315 * than the Double-Check Locking idiom. |
322 // 2. Make the class thread safe, so that at one time |
316 */ |
323 // only one thread enters the synchronized block |
317 return SyncFactoryHolder.factory; |
324 // to instantiate. |
|
325 |
|
326 // if syncFactory object is already there |
|
327 // don't go into synchronized block and return |
|
328 // that object. |
|
329 // else go into synchronized block |
|
330 |
|
331 if (syncFactory == null) { |
|
332 synchronized (SyncFactory.class) { |
|
333 if (syncFactory == null) { |
|
334 syncFactory = new SyncFactory(); |
|
335 } //end if |
|
336 } //end synchronized block |
|
337 } //end if |
|
338 return syncFactory; |
|
339 } |
318 } |
340 |
319 |
341 /** |
320 /** |
342 * Removes the designated currently registered synchronization provider from the |
321 * Removes the designated currently registered synchronization provider from the |
343 * Factory SPI register. |
322 * Factory SPI register. |
661 // singleton |
640 // singleton |
662 SecurityManager sec = System.getSecurityManager(); |
641 SecurityManager sec = System.getSecurityManager(); |
663 if (sec != null) { |
642 if (sec != null) { |
664 sec.checkPermission(SET_SYNCFACTORY_PERMISSION); |
643 sec.checkPermission(SET_SYNCFACTORY_PERMISSION); |
665 } |
644 } |
|
645 |
|
646 if(logger == null){ |
|
647 throw new NullPointerException("You must provide a Logger"); |
|
648 } |
|
649 logger.setLevel(level); |
666 rsLogger = logger; |
650 rsLogger = logger; |
667 rsLogger.setLevel(level); |
|
668 } |
651 } |
669 |
652 |
670 /** |
653 /** |
671 * Returns the logging object for applications to retrieve |
654 * Returns the logging object for applications to retrieve |
672 * synchronization events posted by SyncProvider implementations. |
655 * synchronization events posted by SyncProvider implementations. |
673 * |
656 * |
674 * @throws SyncFactoryException if no logging object has been set. |
657 * @throws SyncFactoryException if no logging object has been set. |
675 */ |
658 */ |
676 public static Logger getLogger() throws SyncFactoryException { |
659 public static Logger getLogger() throws SyncFactoryException { |
|
660 |
|
661 Logger result = rsLogger; |
677 // only one logger per session |
662 // only one logger per session |
678 if (rsLogger == null) { |
663 if (result == null) { |
679 throw new SyncFactoryException("(SyncFactory) : No logger has been set"); |
664 throw new SyncFactoryException("(SyncFactory) : No logger has been set"); |
680 } |
665 } |
681 return rsLogger; |
666 |
|
667 return result; |
682 } |
668 } |
683 |
669 |
684 /** |
670 /** |
685 * Sets the initial JNDI context from which SyncProvider implementations |
671 * Sets the initial JNDI context from which SyncProvider implementations |
686 * can be retrieved from a JNDI namespace |
672 * can be retrieved from a JNDI namespace |
697 * @throws SyncFactoryException if the supplied JNDI context is null |
683 * @throws SyncFactoryException if the supplied JNDI context is null |
698 * @throws java.lang.SecurityException if a security manager exists and its |
684 * @throws java.lang.SecurityException if a security manager exists and its |
699 * {@code checkPermission} method denies calling {@code setJNDIContext} |
685 * {@code checkPermission} method denies calling {@code setJNDIContext} |
700 * @see SecurityManager#checkPermission |
686 * @see SecurityManager#checkPermission |
701 */ |
687 */ |
702 public static void setJNDIContext(javax.naming.Context ctx) |
688 public static synchronized void setJNDIContext(javax.naming.Context ctx) |
703 throws SyncFactoryException { |
689 throws SyncFactoryException { |
704 SecurityManager sec = System.getSecurityManager(); |
690 SecurityManager sec = System.getSecurityManager(); |
705 if (sec != null) { |
691 if (sec != null) { |
706 sec.checkPermission(SET_SYNCFACTORY_PERMISSION); |
692 sec.checkPermission(SET_SYNCFACTORY_PERMISSION); |
707 } |
693 } |
708 if (ctx == null) { |
694 if (ctx == null) { |
709 throw new SyncFactoryException("Invalid JNDI context supplied"); |
695 throw new SyncFactoryException("Invalid JNDI context supplied"); |
710 } |
696 } |
711 ic = ctx; |
697 ic = ctx; |
712 jndiCtxEstablished = true; |
698 } |
713 } |
699 |
714 |
700 /** |
715 /** |
701 * Controls JNDI context initialization. |
716 * Controls JNDI context intialization. |
|
717 * |
702 * |
718 * @throws SyncFactoryException if an error occurs parsing the JNDI context |
703 * @throws SyncFactoryException if an error occurs parsing the JNDI context |
719 */ |
704 */ |
720 private static void initJNDIContext() throws SyncFactoryException { |
705 private static synchronized void initJNDIContext() throws SyncFactoryException { |
721 |
706 |
722 if (jndiCtxEstablished && (ic != null) && (lazyJNDICtxRefresh == false)) { |
707 if ((ic != null) && (lazyJNDICtxRefresh == false)) { |
723 try { |
708 try { |
724 parseProperties(parseJNDIContext()); |
709 parseProperties(parseJNDIContext()); |
725 lazyJNDICtxRefresh = true; // touch JNDI namespace once. |
710 lazyJNDICtxRefresh = true; // touch JNDI namespace once. |
726 } catch (NamingException e) { |
711 } catch (NamingException e) { |
727 e.printStackTrace(); |
712 e.printStackTrace(); |
791 bindings.next(); |
776 bindings.next(); |
792 // Re-entrant call into method |
777 // Re-entrant call into method |
793 enumerateBindings(bindings, properties); |
778 enumerateBindings(bindings, properties); |
794 } |
779 } |
795 } |
780 } |
|
781 |
|
782 /** |
|
783 * Lazy initialization Holder class used by {@code getSyncFactory} |
|
784 */ |
|
785 private static class SyncFactoryHolder { |
|
786 static final SyncFactory factory = new SyncFactory(); |
|
787 } |
796 } |
788 } |
797 |
789 |
798 /** |
790 /** |
799 * Internal class that defines the lazy reference construct for each registered |
791 * Internal class that defines the lazy reference construct for each registered |
800 * SyncProvider implementation. |
792 * SyncProvider implementation. |