001    /*
002     * CDDL HEADER START
003     *
004     * The contents of this file are subject to the terms of the
005     * Common Development and Distribution License, Version 1.0 only
006     * (the "License").  You may not use this file except in compliance
007     * with the License.
008     *
009     * You can obtain a copy of the license at
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.types;
028    
029    
030    
031    import java.io.File;
032    import java.util.Enumeration;
033    import java.util.HashMap;
034    import java.util.Map;
035    import java.util.Properties;
036    
037    import org.opends.server.api.ConfigHandler;
038    import org.opends.server.core.DirectoryServer;
039    import org.opends.server.extensions.ConfigFileHandler;
040    
041    import static org.opends.server.config.ConfigConstants.*;
042    import static org.opends.messages.CoreMessages.*;
043    import static org.opends.server.util.ServerConstants.*;
044    
045    
046    
047    /**
048     * This class provides a set of properties that may control various
049     * aspects of the server environment.  Note that these properties may
050     * only be altered before the Directory Server is started.  Any
051     * attempt to change an environment configuration property while the
052     * server is running will be rejected.
053     */
054    @org.opends.server.types.PublicAPI(
055         stability=org.opends.server.types.StabilityLevel.VOLATILE,
056         mayInstantiate=true,
057         mayExtend=false,
058         mayInvoke=true)
059    public final class DirectoryEnvironmentConfig
060    {
061      // The set of properties for the environment config.
062      private final HashMap<String,String> configProperties;
063    
064    
065    
066      /**
067       * Creates a new directory environment configuration initialized
068       * from the system properties defined in the JVM.
069       */
070      public DirectoryEnvironmentConfig()
071      {
072        this(System.getProperties());
073      }
074    
075    
076    
077      /**
078       * Creates a new directory environment configuration initialized
079       * with a copy of the provided set of properties.
080       *
081       * @param  properties  The properties to use when initializing this
082       *                     environment configuration, or {@code null}
083       *                     to use an empty set of properties.
084       */
085      public DirectoryEnvironmentConfig(Properties properties)
086      {
087        configProperties = new HashMap<String,String>();
088        if (properties != null)
089        {
090          Enumeration propertyNames = properties.propertyNames();
091          while (propertyNames.hasMoreElements())
092          {
093            Object o = propertyNames.nextElement();
094            configProperties.put(String.valueOf(o),
095                                 String.valueOf(properties.get(o)));
096          }
097        }
098      }
099    
100    
101    
102      /**
103       * Creates a new directory environment configuration initialized
104       * with a copy of the provided set of properties.
105       *
106       * @param  properties  The properties to use when initializing this
107       *                     environment configuration, or {@code null}
108       *                     to use an empty set of properties.
109       */
110      public DirectoryEnvironmentConfig(Map<String,String> properties)
111      {
112        if (properties == null)
113        {
114          configProperties = new HashMap<String,String>();
115        }
116        else
117        {
118          configProperties = new HashMap<String,String>(properties);
119        }
120      }
121    
122    
123    
124      /**
125       * Retrieves the property with the specified name.  The check will
126       * first be made in the local config properties, but if no value is
127       * found then the JVM system properties will be checked.
128       *
129       * @param  name  The name of the property to retrieve.
130       *
131       * @return  The property with the specified name, or {@code null} if
132       *          no such property is defined.
133       */
134      public String getProperty(String name)
135      {
136        String value = configProperties.get(name);
137        if (value == null)
138        {
139          value = System.getProperty(name);
140        }
141    
142        return value;
143      }
144    
145    
146    
147      /**
148       * Specifies a property with the given name and value.  If a
149       * property is already defined with the given name, then its value
150       * will be replaced with the provided value, or the property will be
151       * removed if the given value is {@code null}.
152       *
153       * @param  name   The name of the property to set.
154       * @param  value  The value of the property to set, or {@code null}
155       *                if the property is to be removed.
156       *
157       * @return  The previous value held for the property, or
158       *          {@code null} if it was not previously set.
159       *
160       * @throws  InitializationException  If the Directory Server is
161       *                                   already running.
162       */
163      public String setProperty(String name, String value)
164             throws InitializationException
165      {
166        if (DirectoryServer.isRunning())
167        {
168          throw new InitializationException(
169                  ERR_DIRCFG_SERVER_ALREADY_RUNNING.get());
170        }
171    
172        if (value == null)
173        {
174          return configProperties.remove(name);
175        }
176        else
177        {
178          return configProperties.put(name, value);
179        }
180      }
181    
182    
183    
184      /**
185       * Retrieves the directory that should be considered the server
186       * root.  The determination will first be based on the properties
187       * defined in this config object.  If no value is found there, then
188       * the JVM system properties will be checked, followed by an
189       * environment variable.
190       *
191       * @return  The directory that should be considered the server root,
192       *          or {@code null} if it is not defined.
193       */
194      public File getServerRoot()
195      {
196        String serverRootPath = getProperty(PROPERTY_SERVER_ROOT);
197        if (serverRootPath == null)
198        {
199          serverRootPath = System.getenv(ENV_VAR_INSTANCE_ROOT);
200        }
201    
202        if (serverRootPath == null)
203        {
204          return null;
205        }
206        else
207        {
208          return new File(serverRootPath);
209        }
210      }
211    
212    
213    
214      /**
215       * Specifies the directory that should be considered the server
216       * root.  Any relative path used in the server should be considered
217       * relative to the server root.
218       *
219       * @param  serverRoot  The directory that should be considered the
220       *                     server root.
221       *
222       * @return  The previous server root, or {@code null} if there was
223       *          none.
224       *
225       * @throws  InitializationException  If the Directory Server is
226       *                                   already running or there is a
227       *                                   problem with the provided
228       *                                   server root.
229       */
230      public File setServerRoot(File serverRoot)
231             throws InitializationException
232      {
233        if (DirectoryServer.isRunning())
234        {
235          throw new InitializationException(
236                  ERR_DIRCFG_SERVER_ALREADY_RUNNING.get());
237        }
238    
239        if ((! serverRoot.exists()) || (! serverRoot.isDirectory()))
240        {
241          throw new InitializationException(
242                  ERR_DIRCFG_INVALID_SERVER_ROOT.get(
243                          serverRoot.getAbsolutePath()));
244        }
245    
246        String serverRootPath;
247        try
248        {
249          serverRootPath = serverRoot.getCanonicalPath();
250        }
251        catch (Exception e)
252        {
253          serverRootPath = serverRoot.getAbsolutePath();
254        }
255    
256        String oldRootPath = setProperty(PROPERTY_SERVER_ROOT,
257                                         serverRootPath);
258        if (oldRootPath == null)
259        {
260          return null;
261        }
262        else
263        {
264          return new File(oldRootPath);
265        }
266      }
267    
268    
269      /**
270       * Retrieves the configuration file that should be used to
271       * initialize the Directory Server config handler.  If no default
272       * configuration file is specified, then the server will attempt to
273       * use "config/config.ldif" below the server root if it exists.
274       *
275       * @return  The configuration file that should be used to initialize
276       *          the Directory Server config handler, or {@code null} if
277       *          no configuration file is defined.
278       */
279      public File getConfigFile()
280      {
281        String configFilePath = getProperty(PROPERTY_CONFIG_FILE);
282        if (configFilePath == null)
283        {
284          File serverRoot = getServerRoot();
285          if (serverRoot != null)
286          {
287            File configDir = new File(serverRoot, CONFIG_DIR_NAME);
288            File configFile = new File(configDir, CONFIG_FILE_NAME);
289            if (configFile.exists())
290            {
291              return configFile;
292            }
293          }
294    
295          return null;
296        }
297        else
298        {
299          return new File(configFilePath);
300        }
301      }
302    
303    
304    
305      /**
306       * Specifies the configuration file that should be used to
307       * initialize the Directory Server config handler.
308       *
309       * @param  configFile  The configuration file that should be used to
310       *                     initialize the Directory Server config
311       *                     handler.
312       *
313       * @return  The previously-defined configuration file, or
314       *          {@code null} if none was defined.
315       *
316       * @throws  InitializationException  If the Directory Server is
317       *                                   already running or there is a
318       *                                   problem with the provided
319       *                                   configuration file.
320       */
321      public File setConfigFile(File configFile)
322             throws InitializationException
323      {
324        if (DirectoryServer.isRunning())
325        {
326          throw new InitializationException(
327                  ERR_DIRCFG_SERVER_ALREADY_RUNNING.get());
328        }
329    
330        if ((! configFile.exists()) || (! configFile.isFile()))
331        {
332          throw new InitializationException(
333                  ERR_DIRCFG_INVALID_CONFIG_FILE.get(
334                          configFile.getAbsolutePath()));
335        }
336    
337        String configFilePath;
338        try
339        {
340          configFilePath = configFile.getCanonicalPath();
341        }
342        catch (Exception e)
343        {
344          configFilePath = configFile.getAbsolutePath();
345        }
346    
347        String oldConfigFilePath = setProperty(PROPERTY_CONFIG_FILE,
348                                               configFilePath);
349        if (oldConfigFilePath == null)
350        {
351          return null;
352        }
353        else
354        {
355          return new File(oldConfigFilePath);
356        }
357      }
358    
359    
360    
361      /**
362       * Retrieves the class that provides the Directory Server
363       * configuration handler implementation.  If no config handler class
364       * is defined, or if a problem occurs while attempting to determine
365       * the config handler class, then a default class of
366       * org.opends.server.extensions.ConfigFileHandler will be returned.
367       *
368       * @return  The class that provides the Directory Server
369       *          configuration handler implementation.
370       */
371      public Class getConfigClass()
372      {
373        String className = getProperty(PROPERTY_CONFIG_CLASS);
374        if (className == null)
375        {
376          return ConfigFileHandler.class;
377        }
378        else
379        {
380          try
381          {
382            return Class.forName(className);
383          }
384          catch (Exception e)
385          {
386            return ConfigFileHandler.class;
387          }
388        }
389      }
390    
391    
392    
393      /**
394       * Specifies the class that provides the Directory Server
395       * configuration handler implementation.  The class must be a
396       * subclass of the org.opends.server.api.ConfigHandler superclass.
397       *
398       * @param  configClass  The class that proviedes the Directory
399       *                      Server configuration handler implementation.
400       *
401       * @return  The class that was previously configured to provide the
402       *          Directory Server configuration handler implementation,
403       *          or {@code null} if none was defined.
404       *
405       * @throws  InitializationException  If the Directory Server is
406       *                                   already running or there is a
407       *                                   problem with the provided
408       *                                   config handler class.
409       */
410      public Class setConfigClass(Class configClass)
411             throws InitializationException
412      {
413        if (DirectoryServer.isRunning())
414        {
415          throw new InitializationException(
416                  ERR_DIRCFG_SERVER_ALREADY_RUNNING.get());
417        }
418    
419        if (! (ConfigHandler.class.isAssignableFrom(configClass)))
420        {
421          throw new InitializationException(
422                  ERR_DIRCFG_INVALID_CONFIG_CLASS.get(
423                          configClass.getName()));
424        }
425    
426        String oldClassName = setProperty(PROPERTY_CONFIG_CLASS,
427                                          configClass.getName());
428        if (oldClassName == null)
429        {
430          return null;
431        }
432        else
433        {
434          try
435          {
436            return Class.forName(oldClassName);
437          }
438          catch (Exception e)
439          {
440            return null;
441          }
442        }
443      }
444    
445    
446    
447      /**
448       * Indicates whether the Directory Server should attempt to start
449       * with the "last known good" configuration rather than the current
450       * active configuration file.  Note that if there is no "last known
451       * good" configuration file available, then the server should try to
452       * start using the current, active configuration file.  If no
453       * explicit value is defined, then a default result of {@code false}
454       * will be returned.
455       *
456       * @return  {@code true} if the Directory Server should attempt to
457       *          start using the "last known good" configuration, or
458       *          {@code false} if it should try to start using the
459       *          active configuration.
460       */
461      public boolean useLastKnownGoodConfiguration()
462      {
463        String useLastKnownGoodStr =
464             getProperty(PROPERTY_USE_LAST_KNOWN_GOOD_CONFIG);
465        if (useLastKnownGoodStr == null)
466        {
467          return false;
468        }
469    
470        return useLastKnownGoodStr.equalsIgnoreCase("true");
471      }
472    
473    
474    
475      /**
476       * Specifies whether the Directory Server should attempt to start
477       * using the last known good configuration rather than the
478       * current active configuration.
479       *
480       * @param  useLastKnownGoodConfiguration  Indicates whether the
481       *                                        Directory Server should
482       *                                        attempt to start using the
483       *                                        last known good
484       *                                        configuration.
485       *
486       * @return  The previous setting for this configuration option.  If
487       *          no previous value was specified, then {@code false} will
488       *          be returned.
489       *
490       * @throws  InitializationException  If the Directory Server is
491       *                                   already running.
492       */
493      public boolean setUseLastKnownGoodConfiguration(
494                          boolean useLastKnownGoodConfiguration)
495             throws InitializationException
496      {
497        if (DirectoryServer.isRunning())
498        {
499          throw new InitializationException(
500                  ERR_DIRCFG_SERVER_ALREADY_RUNNING.get());
501        }
502    
503        String oldUseLastKnownGoodStr =
504             setProperty(PROPERTY_USE_LAST_KNOWN_GOOD_CONFIG,
505                         String.valueOf(useLastKnownGoodConfiguration));
506        if (oldUseLastKnownGoodStr == null)
507        {
508          return false;
509        }
510        else
511        {
512          return oldUseLastKnownGoodStr.equalsIgnoreCase("true");
513        }
514      }
515    
516    
517    
518      /**
519       * Indicates whether the Directory Server should maintain an archive
520       * of previous configurations.  If no explicit value is defined,
521       * then a default result of {@code true} will be returned.
522       *
523       * @return  {@code true} if the Directory Server should maintain an
524       *          archive of previous configurations, or {@code false} if
525       *          not.
526       */
527      public boolean maintainConfigArchive()
528      {
529        String maintainArchiveStr =
530             getProperty(PROPERTY_MAINTAIN_CONFIG_ARCHIVE);
531        if (maintainArchiveStr == null)
532        {
533          return true;
534        }
535    
536        return (! maintainArchiveStr.equalsIgnoreCase("false"));
537      }
538    
539    
540    
541      /**
542       * Specifies whether the Directory Server should maintain an archive
543       * of previous configurations.
544       *
545       * @param  maintainConfigArchive  Indicates whether the Directory
546       *                                Server should maintain an archive
547       *                                of previous configurations.
548       *
549       * @return  The previous setting for this configuration option.  If
550       *          no previous value was specified, then {@code true} will
551       *          be returned.
552       *
553       * @throws  InitializationException  If the Directory Server is
554       *                                   already running.
555       */
556      public boolean setMaintainConfigArchive(
557                          boolean maintainConfigArchive)
558             throws InitializationException
559      {
560        if (DirectoryServer.isRunning())
561        {
562          throw new InitializationException(
563                  ERR_DIRCFG_SERVER_ALREADY_RUNNING.get());
564        }
565    
566        String oldMaintainStr =
567             setProperty(PROPERTY_MAINTAIN_CONFIG_ARCHIVE,
568                         String.valueOf(maintainConfigArchive));
569        if (oldMaintainStr == null)
570        {
571          return true;
572        }
573        else
574        {
575          return (! oldMaintainStr.equalsIgnoreCase("false"));
576        }
577      }
578    
579    
580    
581      /**
582       * Retrieves the maximum number of archived configurations that the
583       * Directory Server should maintain.  If no value is defined, then a
584       * value of zero will be returned.
585       *
586       * @return  The maximum number of archived configurations that the
587       *          Directory Server should maintain, or zero if there
588       *          should not be any limit.
589       */
590      public int getMaxConfigArchiveSize()
591      {
592        String maxSizeStr =
593             getProperty(PROPERTY_MAX_CONFIG_ARCHIVE_SIZE);
594        if (maxSizeStr == null)
595        {
596          return 0;
597        }
598    
599        try
600        {
601          int maxSize = Integer.parseInt(maxSizeStr);
602          if (maxSize > 0)
603          {
604            return maxSize;
605          }
606          else
607          {
608            return 0;
609          }
610        }
611        catch (Exception e)
612        {
613          return 0;
614        }
615      }
616    
617    
618    
619      /**
620       * Specifies the maximum number of archived configurations that the
621       * Directory Server should maintain.  A value that is less than or
622       * equal to zero may be used to indicate that there should not be
623       * any limit to the number of archived configurations.
624       *
625       * @param  maxConfigArchiveSize  The maximum number of archived
626       *                               configurations that the Directory
627       *                               Server should maintain.
628       *
629       * @return  The previous setting for this configuration option.  If
630       *          no previous value was specified, then zero will be
631       *          returned.
632       *
633       * @throws  InitializationException  If the Directory Server is
634       *                                   already running.
635       */
636      public int setMaxConfigArchiveSize(int maxConfigArchiveSize)
637             throws InitializationException
638      {
639        if (DirectoryServer.isRunning())
640        {
641          throw new InitializationException(
642                  ERR_DIRCFG_SERVER_ALREADY_RUNNING.get());
643        }
644    
645        if (maxConfigArchiveSize < 0)
646        {
647          maxConfigArchiveSize = 0;
648        }
649    
650        String oldMaxSizeStr =
651             setProperty(PROPERTY_MAX_CONFIG_ARCHIVE_SIZE,
652                         String.valueOf(maxConfigArchiveSize));
653        if (oldMaxSizeStr == null)
654        {
655          return 0;
656        }
657        else
658        {
659          try
660          {
661            int oldMaxSize = Integer.parseInt(oldMaxSizeStr);
662            if (oldMaxSize > 0)
663            {
664              return oldMaxSize;
665            }
666            else
667            {
668              return 0;
669            }
670          }
671          catch (Exception e)
672          {
673            return 0;
674          }
675        }
676      }
677    
678    
679    
680      /**
681       * Retrieves the directory that contains the server schema
682       * configuration files.  If no value is defined, but a default
683       * directory of "config/schema" exists below the server root, then
684       * that will be returned.
685       *
686       * @return  The directory that contains the server schema
687       *          configuration files, or {@code null} if none is defined.
688       */
689      public File getSchemaDirectory()
690      {
691        String schemaDirectoryPath =
692             getProperty(PROPERTY_SCHEMA_DIRECTORY);
693        if (schemaDirectoryPath == null)
694        {
695          File serverRoot = getServerRoot();
696          if (serverRoot != null)
697          {
698            File schemaDir = new File(serverRoot.getAbsolutePath() +
699                                      File.separator + PATH_SCHEMA_DIR);
700            if (schemaDir.exists() && schemaDir.isDirectory())
701            {
702              return schemaDir;
703            }
704          }
705    
706          return null;
707        }
708        else
709        {
710          return new File(schemaDirectoryPath);
711        }
712      }
713    
714    
715    
716      /**
717       * Specifies the directory that should contain the server schema
718       * configuration files.  It must exist and must be a directory.
719       *
720       * @param  schemaDirectory  The directory that should contain the
721       *                          server schema configuration files.
722       *
723       * @return  The previously-defined schema configuration directory,
724       *          or {@code null} if none was defined.
725       *
726       * @throws  InitializationException  If the Directory Server is
727       *                                   already running or there is a
728       *                                   problem with the provided
729       *                                   schema directory.
730       */
731      public File setSchemaDirectory(File schemaDirectory)
732             throws InitializationException
733      {
734        if (DirectoryServer.isRunning())
735        {
736          throw new InitializationException(
737                  ERR_DIRCFG_SERVER_ALREADY_RUNNING.get());
738        }
739    
740        if ((! schemaDirectory.exists()) ||
741            (! schemaDirectory.isDirectory()))
742        {
743          throw new InitializationException(
744                  ERR_DIRCFG_INVALID_SCHEMA_DIRECTORY.get(
745                          schemaDirectory.getAbsolutePath()));
746        }
747    
748        String schemaDirectoryPath;
749        try
750        {
751          schemaDirectoryPath = schemaDirectory.getCanonicalPath();
752        }
753        catch (Exception e)
754        {
755          schemaDirectoryPath = schemaDirectory.getAbsolutePath();
756        }
757    
758        String oldSchemaDir = setProperty(PROPERTY_SCHEMA_DIRECTORY,
759                                         schemaDirectoryPath);
760        if (oldSchemaDir == null)
761        {
762          return null;
763        }
764        else
765        {
766          return new File(oldSchemaDir);
767        }
768      }
769    
770    
771    
772      /**
773       * Retrieves the directory that should be used to hold the server
774       * lock files.  If no value is defined, then the server will attempt
775       * to use a default directory of "locks" below the server root.
776       *
777       * @return  The directory that should be used to hold the server
778       *          lock files, or {@code null} if it cannot be determined.
779       */
780      public File getLockDirectory()
781      {
782        String lockFilePath = getProperty(PROPERTY_LOCK_DIRECTORY);
783        if (lockFilePath == null)
784        {
785          File serverRoot = getServerRoot();
786          if (serverRoot == null)
787          {
788            return null;
789          }
790          else
791          {
792            return new File(serverRoot, LOCKS_DIRECTORY);
793          }
794        }
795        else
796        {
797          return new File(lockFilePath);
798        }
799      }
800    
801    
802    
803      /**
804       * Specifies the directory that should be used to hold the server
805       * lock files.  If the specified path already exists, then it must
806       * be a directory and its contents must be writable by the server.
807       * If it does not exist, then its parent directory must exist and
808       * the server should have permission to create a new subdirectory in
809       * it.
810       *
811       * @param  lockDirectory  The directory that should be used to hold
812       *                        the server lock files.
813       *
814       * @return  The previously-defined lock directory, or {@code null}
815       *          if none was defined.
816       *
817       * @throws  InitializationException  If the Directory Server is
818       *                                   already running or there is a
819       *                                   problem with the provided lock
820       *                                   directory.
821       */
822      public File setLockDirectory(File lockDirectory)
823             throws InitializationException
824      {
825        if (DirectoryServer.isRunning())
826        {
827          throw new InitializationException(
828                  ERR_DIRCFG_SERVER_ALREADY_RUNNING.get());
829        }
830    
831        if (lockDirectory.exists())
832        {
833          if (! lockDirectory.isDirectory())
834          {
835            throw new InitializationException(
836                    ERR_DIRCFG_INVALID_LOCK_DIRECTORY.get(
837                            lockDirectory.getAbsolutePath()));
838          }
839        }
840        else
841        {
842          File parentFile = lockDirectory.getParentFile();
843          if (! (parentFile.exists() && parentFile.isDirectory()))
844          {
845            throw new InitializationException(
846                    ERR_DIRCFG_INVALID_LOCK_DIRECTORY.get(
847                            lockDirectory.getAbsolutePath()));
848          }
849        }
850    
851        String lockDirectoryPath;
852        try
853        {
854          lockDirectoryPath = lockDirectory.getCanonicalPath();
855        }
856        catch (Exception e)
857        {
858          lockDirectoryPath = lockDirectory.getAbsolutePath();
859        }
860    
861        String oldLockDir = setProperty(PROPERTY_LOCK_DIRECTORY,
862                                        lockDirectoryPath);
863        if (oldLockDir == null)
864        {
865          return null;
866        }
867        else
868        {
869          return new File(oldLockDir);
870        }
871      }
872    
873    
874    
875      /**
876       * Indicates whether the Directory Server startup process should
877       * skip the connection handler creation and initialization phases.
878       *
879       * @return  {@code true} if the Directory Server should not start
880       *          its connection handlers, or {@code false} if the
881       *          connection handlers should be enabled.
882       */
883      public boolean disableConnectionHandlers()
884      {
885        String disableStr =
886             getProperty(PROPERTY_DISABLE_CONNECTION_HANDLERS);
887        if (disableStr == null)
888        {
889          return false;
890        }
891    
892        return disableStr.equalsIgnoreCase("true");
893      }
894    
895    
896    
897      /**
898       * Specifies whether the Directory Server startup process should
899       * skip the connection handler creation and initialization phases.
900       *
901       * @param  disableConnectionHandlers  Indicates whether the
902       *                                    Directory Server should skip
903       *                                    the connection handler
904       *                                    creation and initialization
905       *                                    phases.
906       *
907       * @return  The previous setting for this configuration option.  If
908       *          no previous value was specified, then {@code false} will
909       *          be returned.
910       *
911       * @throws  InitializationException  If the Directory Server is
912       *                                   already running.
913       */
914      public boolean setDisableConnectionHandlers(
915                          boolean disableConnectionHandlers)
916             throws InitializationException
917      {
918        if (DirectoryServer.isRunning())
919        {
920          throw new InitializationException(
921                  ERR_DIRCFG_SERVER_ALREADY_RUNNING.get());
922        }
923    
924        String oldDisableStr =
925             setProperty(PROPERTY_DISABLE_CONNECTION_HANDLERS,
926                         String.valueOf(disableConnectionHandlers));
927        if (oldDisableStr == null)
928        {
929          return false;
930        }
931        else
932        {
933          return oldDisableStr.equalsIgnoreCase("true");
934        }
935      }
936    
937    
938    
939      /**
940       * Indicates whether all threads created by the Directory Server
941       * should be created as daemon threads.
942       *
943       * @return  {@code true} if all threads created by the Directory
944       *          Server should be created as daemon threads, or
945       *          {@code false} if not.
946       */
947      public boolean forceDaemonThreads()
948      {
949        String forceDaemonStr =
950             getProperty(PROPERTY_FORCE_DAEMON_THREADS);
951        if (forceDaemonStr == null)
952        {
953          return false;
954        }
955        else
956        {
957          return forceDaemonStr.equalsIgnoreCase("true");
958        }
959      }
960    
961    
962    
963      /**
964       * Specifies whether all threads created by the Directory Server
965       * should be created as daemon threads.
966       *
967       * @param  forceDaemonThreads  Indicates whether all threads created
968       *                             by the Directory Server should be
969       *                             created as daemon threads.
970       *
971       * @return  The previous setting for this configuration option.  If
972       *          no previous value was specified, then {@code false} will
973       *          be returned.
974       *
975       * @throws  InitializationException  If the Directory Server is
976       *                                   already running.
977       */
978      public boolean setForceDaemonThreads(boolean forceDaemonThreads)
979             throws InitializationException
980      {
981        if (DirectoryServer.isRunning())
982        {
983          throw new InitializationException(
984                  ERR_DIRCFG_SERVER_ALREADY_RUNNING.get());
985        }
986    
987        String oldForceDaemonStr =
988             setProperty(PROPERTY_FORCE_DAEMON_THREADS,
989                         String.valueOf(forceDaemonThreads));
990        if (oldForceDaemonStr == null)
991        {
992          return false;
993        }
994        else
995        {
996          return oldForceDaemonStr.equalsIgnoreCase("true");
997        }
998      }
999    
1000    
1001    
1002      /**
1003       * Indicates whether the Directory Server should be allowed to use
1004       * the {@code Runtime.exec()} method to be able to launch external
1005       * commands on the underlying system.
1006       *
1007       * @return  {@code true} if the Directory Server should be allowed
1008       *          to use {@code Runtime.exec()}, or {@code false} if not.
1009       */
1010      public boolean disableExec()
1011      {
1012        String disableStr = getProperty(PROPERTY_DISABLE_EXEC);
1013        if (disableStr == null)
1014        {
1015          return false;
1016        }
1017        else
1018        {
1019          return disableStr.equalsIgnoreCase("true");
1020        }
1021      }
1022    
1023    
1024    
1025      /**
1026       * Specifies whether the Directory Server should be allowed to use
1027       * the {@code Runtime.exec()} method to be able to launch external
1028       * commands on the underlying system.
1029       *
1030       * @param  disableExec  Indicates whether the Directory Server
1031       *                      should be allowed to launch external
1032       *                      commands on the underlying system.
1033       *
1034       * @return  The previous setting for this configuration option.  If
1035       *          no previous value was specified, then {@code false} will
1036       *          be returned.
1037       *
1038       * @throws  InitializationException  If the Directory Server is
1039       *                                   already running.
1040       */
1041      public boolean setDisableExec(boolean disableExec)
1042             throws InitializationException
1043      {
1044        if (DirectoryServer.isRunning())
1045        {
1046          throw new InitializationException(
1047                  ERR_DIRCFG_SERVER_ALREADY_RUNNING.get());
1048        }
1049    
1050        String oldDisableStr = setProperty(PROPERTY_DISABLE_EXEC,
1051                         String.valueOf(disableExec));
1052        if (oldDisableStr == null)
1053        {
1054          return false;
1055        }
1056        else
1057        {
1058          return oldDisableStr.equalsIgnoreCase("true");
1059        }
1060      }
1061    
1062    
1063    
1064      /**
1065       * Retrieves the concurrency level for the Directory Server lock
1066       * table.
1067       *
1068       * @return  The concurrency level for the Directory Server lock
1069       *          table.
1070       */
1071      public int getLockManagerConcurrencyLevel()
1072      {
1073        String levelStr =
1074             getProperty(PROPERTY_LOCK_MANAGER_CONCURRENCY_LEVEL);
1075        if (levelStr == null)
1076        {
1077          return LockManager.DEFAULT_CONCURRENCY_LEVEL;
1078        }
1079    
1080        int concurrencyLevel = -1;
1081        try
1082        {
1083          concurrencyLevel = Integer.parseInt(levelStr);
1084        }
1085        catch (Exception e)
1086        {
1087          return LockManager.DEFAULT_CONCURRENCY_LEVEL;
1088        }
1089    
1090        if (concurrencyLevel <= 0)
1091        {
1092          return LockManager.DEFAULT_CONCURRENCY_LEVEL;
1093        }
1094        else
1095        {
1096          return concurrencyLevel;
1097        }
1098      }
1099    
1100    
1101    
1102      /**
1103       * Specifies the concurrency level for the Directory Server lock
1104       * table.  This should be set to the maximum number of threads that
1105       * could attempt to interact with the lock table at any given time.
1106       *
1107       * @param  concurrencyLevel  The concurrency level for the Directory
1108       *                           Server lock manager.
1109       *
1110       * @return  The previously-configured concurrency level.  If there
1111       *          was no previously-configured value, then the default
1112       *          concurrency level will be returned.
1113       *
1114       * @throws  InitializationException  If the Directory Server is
1115       *                                   already running or there is a
1116       *                                   problem with the provided
1117       *                                   concurrency level value.
1118       */
1119      public int setLockManagerConcurrencyLevel(int concurrencyLevel)
1120             throws InitializationException
1121      {
1122        if (DirectoryServer.isRunning())
1123        {
1124          throw new InitializationException(
1125                  ERR_DIRCFG_SERVER_ALREADY_RUNNING.get());
1126        }
1127    
1128        if (concurrencyLevel <= 0)
1129        {
1130            throw new InitializationException(
1131                    ERR_DIRCFG_INVALID_CONCURRENCY_LEVEL.get(
1132                            concurrencyLevel));
1133        }
1134    
1135        String concurrencyStr =
1136             setProperty(PROPERTY_LOCK_MANAGER_CONCURRENCY_LEVEL,
1137                         String.valueOf(concurrencyLevel));
1138        if (concurrencyStr == null)
1139        {
1140          return LockManager.DEFAULT_CONCURRENCY_LEVEL;
1141        }
1142        else
1143        {
1144          try
1145          {
1146            return Integer.parseInt(concurrencyStr);
1147          }
1148          catch (Exception e)
1149          {
1150            return LockManager.DEFAULT_CONCURRENCY_LEVEL;
1151          }
1152        }
1153      }
1154    
1155      /**
1156       * Retrieves whether a fair ordering should be used for the lock
1157       * manager.
1158       *
1159       * @return True if fair orderin should be used or false otherwise
1160       */
1161      public boolean getLockManagerFairOrdering()
1162      {
1163        String sizeStr = getProperty(PROPERTY_LOCK_MANAGER_FAIR_ORDERING);
1164        if (sizeStr == null)
1165        {
1166          return LockManager.DEFAULT_FAIR_ORDERING;
1167        }
1168        else
1169        {
1170          try
1171          {
1172            return Boolean.parseBoolean(sizeStr);
1173          }
1174          catch (Exception e)
1175          {
1176            return LockManager.DEFAULT_FAIR_ORDERING;
1177          }
1178        }
1179      }
1180    
1181      /**
1182       * Specifies whether a fair ordering should be used for the lock
1183       * manager.
1184       *
1185       * @param  fairOrdering  {@code true} if fair ordering should be
1186       *                       used, or {@code false} if not.
1187       *
1188       * @return  The previously-configured setting for fair ordering.  If
1189       *          there was no previously-configured value, then the
1190       *          default initial setting will be returned.
1191       *
1192       * @throws  InitializationException  If the Directory Server is
1193       *                                   already running.
1194       */
1195      public boolean setLockManagerFairOrdering(boolean fairOrdering)
1196             throws InitializationException
1197      {
1198        if (DirectoryServer.isRunning())
1199        {
1200          throw new InitializationException(
1201                  ERR_DIRCFG_SERVER_ALREADY_RUNNING.get());
1202        }
1203    
1204        String fairOrderingStr =
1205             setProperty(PROPERTY_LOCK_MANAGER_FAIR_ORDERING,
1206                         String.valueOf(fairOrdering));
1207        if (fairOrderingStr == null)
1208        {
1209          return LockManager.DEFAULT_FAIR_ORDERING;
1210        }
1211        else
1212        {
1213          try
1214          {
1215            return Boolean.parseBoolean(fairOrderingStr);
1216          }
1217          catch (Exception e)
1218          {
1219            return LockManager.DEFAULT_FAIR_ORDERING;
1220          }
1221        }
1222      }
1223    
1224      /**
1225       * Retrieves the initial table size for the server lock table.  This
1226       * can be used to ensure that the lock table has the appropriate
1227       * size for the expected number of locks that will be held at any
1228       * given time.
1229       *
1230       * @return  The initial table size for the server lock table.
1231       */
1232      public int getLockManagerTableSize()
1233      {
1234        String sizeStr = getProperty(PROPERTY_LOCK_MANAGER_TABLE_SIZE);
1235        if (sizeStr == null)
1236        {
1237          return LockManager.DEFAULT_INITIAL_TABLE_SIZE;
1238        }
1239        else
1240        {
1241          try
1242          {
1243            return Integer.parseInt(sizeStr);
1244          }
1245          catch (Exception e)
1246          {
1247            return LockManager.DEFAULT_INITIAL_TABLE_SIZE;
1248          }
1249        }
1250      }
1251    
1252    
1253    
1254      /**
1255       * Specifies the initial table size for the server lock table.  This
1256       * can be used to ensure taht the lock table has the appropriate
1257       * size for the expected number of locks that will be held at any
1258       * given time.
1259       *
1260       * @param  lockTableSize  The initial table size for the server lock
1261       *                        table.
1262       *
1263       * @return  The previously-configured initial lock table size.  If
1264       *          there was no previously-configured value, then the
1265       *          default initial table size will be returned.
1266       *
1267       * @throws  InitializationException  If the Directory Server is
1268       *                                   already running or there is a
1269       *                                   problem with the provided
1270       *                                   initial table size.
1271       */
1272      public int setLockManagerTableSize(int lockTableSize)
1273             throws InitializationException
1274      {
1275        if (DirectoryServer.isRunning())
1276        {
1277          throw new InitializationException(
1278                  ERR_DIRCFG_SERVER_ALREADY_RUNNING.get());
1279        }
1280    
1281        if (lockTableSize <= 0)
1282        {
1283            throw new InitializationException(
1284                    ERR_DIRCFG_INVALID_LOCK_TABLE_SIZE.get(
1285                            lockTableSize));
1286        }
1287    
1288        String tableSizeStr =
1289             setProperty(PROPERTY_LOCK_MANAGER_TABLE_SIZE,
1290                         String.valueOf(lockTableSize));
1291        if (tableSizeStr == null)
1292        {
1293          return LockManager.DEFAULT_INITIAL_TABLE_SIZE;
1294        }
1295        else
1296        {
1297          try
1298          {
1299            return Integer.parseInt(tableSizeStr);
1300          }
1301          catch (Exception e)
1302          {
1303            return LockManager.DEFAULT_INITIAL_TABLE_SIZE;
1304          }
1305        }
1306      }
1307    }
1308