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 2006-2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.util;
028    
029    
030    
031    import java.io.BufferedWriter;
032    import java.io.File;
033    import java.io.FileWriter;
034    import java.io.IOException;
035    import java.net.InetSocketAddress;
036    import java.net.ServerSocket;
037    import java.net.Socket;
038    import java.util.LinkedList;
039    
040    import org.opends.server.types.OperatingSystem;
041    
042    
043    /**
044     * This class provides a number of utility methods that may be used during the
045     * graphical or command-line setup process.
046     */
047    @org.opends.server.types.PublicAPI(
048         stability=org.opends.server.types.StabilityLevel.VOLATILE,
049         mayInstantiate=false,
050         mayExtend=false,
051         mayInvoke=true)
052    public class SetupUtils
053    {
054      /**
055       * Java property used to known if we are using web start or not.
056       */
057      public static final String IS_WEBSTART = "org.opends.quicksetup.iswebstart";
058    
059      /**
060       * Specific environment variable used by the scripts to find java.
061       */
062      public static final String OPENDS_JAVA_HOME = "OPENDS_JAVA_HOME";
063    
064      /**
065       * Java property used to know which are the jar files that must be downloaded
066       * lazily.  The current code in WebStartDownloader that uses this property
067       * assumes that the URL are separated with an space.
068       */
069      public static final String LAZY_JAR_URLS =
070          "org.opends.quicksetup.lazyjarurls";
071    
072      /**
073       * Java property used to know which is the name of the zip file that must
074       * be unzipped and whose contents must be extracted during the Web Start
075       * based setup.
076       */
077      public static final String ZIP_FILE_NAME =
078          "org.opends.quicksetup.zipfilename";
079    
080      /**
081       * The relative path where all the libraries (jar files) are.
082       */
083      public static final String LIBRARIES_PATH_RELATIVE = "lib";
084    
085      /* These string values must be synchronized with Directory Server's main
086       * method.  These string values are considered stable by the server team and
087       * not candidates for internationalization. */
088      /** Product name. */
089      public static final String NAME = "Name";
090      /** Build ID. */
091      public static final String BUILD_ID = "Build ID";
092      /** Major version. */
093      public static final String MAJOR_VERSION = "Major Version";
094      /** Minor version. */
095      public static final String MINOR_VERSION = "Minor Version";
096      /** Point version of the product. */
097      public static final String POINT_VERSION = "Point Version";
098      /** Revision number in SVN. */
099      public static final String REVISION_NUMBER = "Revision Number";
100      /** The version qualifier. */
101      public static final String VERSION_QUALIFIER = "Version Qualifier";
102      /** Incompatibilities found between builds (used by the upgrade tool). */
103      public static final String INCOMPATIBILITY_EVENTS = "Upgrade Event IDs";
104      /** Fix IDs associated with the build. */
105      public static final String FIX_IDS = "Fix IDs";
106      /** Debug build identifier. */
107      public static final String DEBUG_BUILD = "Debug Build";
108      /** The OS used during the build. */
109      public static final String BUILD_OS = "Build OS";
110      /** The user that generated the build. */
111      public static final String BUILD_USER = "Build User";
112      /** The java version used to generate the build. */
113      public static final String BUILD_JAVA_VERSION = "Build Java Version";
114      /** The java vendor of the JVM used to build. */
115      public static final String BUILD_JAVA_VENDOR = "Build Java Vendor";
116      /** The version of the JVM used to create the build. */
117      public static final String BUILD_JVM_VERSION = "Build JVM Version";
118      /** The vendor of the JVM used to create the build. */
119      public static final String BUILD_JVM_VENDOR = "Build JVM Vendor";
120      /** The build number. */
121      public static final String BUILD_NUMBER = "Build Number";
122    
123      /**
124       * Creates a MakeLDIF template file using the provided information.
125       *
126       * @param  baseDN      The base DN for the data in the template file.
127       * @param  numEntries  The number of user entries the template file should
128       *                     create.
129       *
130       * @return  The {@code File} object that references the created template file.
131       *
132       * @throws  IOException  If a problem occurs while writing the template file.
133       */
134      public static File createTemplateFile(String baseDN, int numEntries)
135             throws IOException
136      {
137        File templateFile = File.createTempFile("opends-install", ".template");
138        templateFile.deleteOnExit();
139    
140        LinkedList<String> lines = new LinkedList<String>();
141        lines.add("define suffix=" + baseDN);
142    
143        if (numEntries > 0)
144        {
145          lines.add("define numusers=" + numEntries);
146        }
147    
148        lines.add("");
149        lines.add("branch: [suffix]");
150        lines.add("");
151        lines.add("branch: ou=People,[suffix]");
152    
153        if (numEntries > 0)
154        {
155          lines.add("subordinateTemplate: person:[numusers]");
156          lines.add("");
157          lines.add("template: person");
158          lines.add("rdnAttr: uid");
159          lines.add("objectClass: top");
160          lines.add("objectClass: person");
161          lines.add("objectClass: organizationalPerson");
162          lines.add("objectClass: inetOrgPerson");
163          lines.add("givenName: <first>");
164          lines.add("sn: <last>");
165          lines.add("cn: {givenName} {sn}");
166          lines.add("initials: {givenName:1}" +
167                    "<random:chars:ABCDEFGHIJKLMNOPQRSTUVWXYZ:1>{sn:1}");
168          lines.add("employeeNumber: <sequential:0>");
169          lines.add("uid: user.{employeeNumber}");
170          lines.add("mail: {uid}@maildomain.net");
171          lines.add("userPassword: password");
172          lines.add("telephoneNumber: <random:telephone>");
173          lines.add("homePhone: <random:telephone>");
174          lines.add("pager: <random:telephone>");
175          lines.add("mobile: <random:telephone>");
176          lines.add("street: <random:numeric:5> <file:streets> Street");
177          lines.add("l: <file:cities>");
178          lines.add("st: <file:states>");
179          lines.add("postalCode: <random:numeric:5>");
180          lines.add("postalAddress: {cn}${street}${l}, {st}  {postalCode}");
181          lines.add("description: This is the description for {cn}.");
182        }
183    
184        BufferedWriter writer = new BufferedWriter(new FileWriter(templateFile));
185        for (String line : lines)
186        {
187          writer.write(line);
188          writer.newLine();
189        }
190    
191        writer.flush();
192        writer.close();
193    
194        return templateFile;
195      }
196    
197      /**
198       * Returns {@code true} if we are running under Mac OS and
199       * {@code false} otherwise.
200       * @return {@code true} if we are running under Mac OS and
201       * {@code false} otherwise.
202       */
203      public static boolean isMacOS()
204      {
205        return OperatingSystem.MACOS == getOperatingSystem();
206      }
207    
208      /**
209       * Returns {@code true} if we are running under Unix and
210       * {@code false} otherwise.
211       * @return {@code true} if we are running under Unix and
212       * {@code false} otherwise.
213       */
214      public static boolean isUnix()
215      {
216        return OperatingSystem.isUNIXBased(getOperatingSystem());
217      }
218    
219      /**
220       * Indicates whether the underlying operating system is a Windows variant.
221       *
222       * @return  {@code true} if the underlying operating system is a Windows
223       *          variant, or {@code false} if not.
224       */
225      public static boolean isWindows()
226      {
227          return OperatingSystem.WINDOWS == getOperatingSystem();
228      }
229    
230      /**
231       * Indicates whether the underlying operating system is Windows Vista.
232       *
233       * @return  {@code true} if the underlying operating system is Windows
234       *          Vista, or {@code false} if not.
235       */
236      public static boolean isVista()
237      {
238        boolean isVista;
239        String os = System.getProperty("os.name");
240        if (os != null)
241        {
242         isVista = isWindows() && (os.toLowerCase().indexOf("vista") != -1);
243        }
244        else
245        {
246          isVista = false;
247        }
248        return isVista;
249      }
250      /**
251       * Returns a String representation of the OS we are running.
252       * @return a String representation of the OS we are running.
253       */
254      public static String getOSString()
255      {
256        return getOperatingSystem().toString();
257      }
258    
259      /**
260       * Commodity method to help identifying the OS we are running on.
261       * @return the OperatingSystem we are running on.
262       */
263      public static OperatingSystem getOperatingSystem()
264      {
265        return OperatingSystem.forName(System.getProperty("os.name"));
266      }
267    
268      /**
269       * Returns {@code true} if the provided port is free and we can use it,
270       * {@code false} otherwise.
271       * @param hostname the host name we are analyzing.
272       * @param port the port we are analyzing.
273       * @return {@code true} if the provided port is free and we can use it,
274       * {@code false} otherwise.
275       */
276      public static boolean canUseAsPort(String hostname, int port)
277      {
278        boolean canUseAsPort = false;
279        ServerSocket serverSocket = null;
280        try
281        {
282          InetSocketAddress socketAddress = new InetSocketAddress(hostname, port);
283          serverSocket = new ServerSocket();
284          if (!isWindows())
285          {
286            serverSocket.setReuseAddress(true);
287          }
288          serverSocket.bind(socketAddress);
289          canUseAsPort = true;
290    
291          serverSocket.close();
292    
293          /* Try to create a socket because sometimes even if we can create a server
294           * socket there is already someone listening to the port (is the case
295           * of products as Sun DS 6.0).
296           */
297          Socket s = null;
298          try
299          {
300            s = new Socket();
301            s.connect(socketAddress, 1000);
302            canUseAsPort = false;
303    
304          } catch (Throwable t)
305          {
306          }
307          finally
308          {
309            if (s != null)
310            {
311              try
312              {
313                s.close();
314              }
315              catch (Throwable t)
316              {
317              }
318            }
319          }
320    
321    
322        } catch (IOException ex)
323        {
324          canUseAsPort = false;
325        } finally
326        {
327          try
328          {
329            if (serverSocket != null)
330            {
331              serverSocket.close();
332            }
333          } catch (Exception ex)
334          {
335          }
336        }
337    
338        return canUseAsPort;
339      }
340    
341      /**
342       * Returns {@code true} if the provided port is free and we can use it,
343       * {@code false} otherwise.
344       * @param port the port we are analyzing.
345       * @return {@code true} if the provided port is free and we can use it,
346       * {@code false} otherwise.
347       */
348      public static boolean canUseAsPort(int port)
349      {
350        return canUseAsPort("localhost", port);
351      }
352    
353      /**
354       * Returns {@code true} if the provided port is a priviledged port,
355       * {@code false} otherwise.
356       * @param port the port we are analyzing.
357       * @return {@code true} if the provided port is a priviledged port,
358       * {@code false} otherwise.
359       */
360      public static boolean isPriviledgedPort(int port)
361      {
362        return (port <= 1024) && !isWindows();
363      }
364    
365      /**
366       * Returns the default value for the JMX Port.
367       * @return the default value for the JMX Port.
368       */
369      public static int getDefaultJMXPort()
370      {
371        return 1689;
372      }
373    
374      /**
375       * Indicates whether we are in a web start installation or not.
376       *
377       * @return <CODE>true</CODE> if we are in a web start installation and
378       *         <CODE>false</CODE> if not.
379       */
380      public static boolean isWebStart()
381      {
382        return "true".equals(System.getProperty(IS_WEBSTART));
383      }
384    
385      /**
386       * Returns the String that can be used to launch an script using Runtime.exec.
387       * This method is required because in Windows the script that contain a "="
388       * in their path must be quoted.
389       * @param script the script name
390       * @return the absolute path for the given parentPath and relativePath.
391       */
392      public static String getScriptPath(String script)
393      {
394        String s = script;
395        if (isWindows())
396        {
397          if (s != null)
398          {
399            if (!s.startsWith("\"") || !s.endsWith("\""))
400            {
401              s = "\""+script+"\"";
402            }
403          }
404        }
405        return s;
406      }
407    }
408