jdk/src/share/classes/javax/sql/rowset/spi/SyncFactory.java
changeset 7182 f3e89472692d
parent 6846 2cfd1dfb014b
child 7184 70b4f13c6f5d
equal deleted inserted replaced
7181:0f32e3c203b8 7182:f3e89472692d
   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.
   250      */
   244      */
   251     private static Context ic;
   245     private static Context ic;
   252     /**
   246     /**
   253      * The <code>Logger</code> object to be used by the <code>SyncFactory</code>.
   247      * The <code>Logger</code> object to be used by the <code>SyncFactory</code>.
   254      */
   248      */
   255     private static Logger rsLogger;
   249     private static volatile Logger rsLogger;
   256     /**
   250     /**
   257      *
   251      *
   258      */
   252      */
   259     private static Level rsLevel;
   253     private static Level rsLevel;
   260     /**
   254     /**
   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.
   433                 }
   412                 }
   434                 parseProperties(properties);
   413                 parseProperties(properties);
   435             }
   414             }
   436         }
   415         }
   437     }
   416     }
   438     /**
   417 
   439      * The internal boolean switch that indicates whether a JNDI
       
   440      * context has been established or not.
       
   441      */
       
   442     private static boolean jndiCtxEstablished = false;
       
   443     /**
   418     /**
   444      * The internal debug switch.
   419      * The internal debug switch.
   445      */
   420      */
   446     private static boolean debug = false;
   421     private static boolean debug = false;
   447     /**
   422     /**
   627 
   602 
   628         SecurityManager sec = System.getSecurityManager();
   603         SecurityManager sec = System.getSecurityManager();
   629         if (sec != null) {
   604         if (sec != null) {
   630             sec.checkPermission(SET_SYNCFACTORY_PERMISSION);
   605             sec.checkPermission(SET_SYNCFACTORY_PERMISSION);
   631         }
   606         }
       
   607 
       
   608         if(logger == null){
       
   609             throw new NullPointerException("You must provide a Logger");
       
   610         }
   632         rsLogger = logger;
   611         rsLogger = logger;
   633     }
   612     }
   634 
   613 
   635     /**
   614     /**
   636      * Sets the logging object that is used by <code>SyncProvider</code>
   615      * Sets the logging object that is used by <code>SyncProvider</code>
   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.