installer/engine/src/org/netbeans/installer/utils/applications/NetBeansUtils.java
author Jaroslav Tulach <jtulach@netbeans.org>
Sun Nov 22 11:35:02 2009 +0100 (10 hours ago)
changeset 154033 fa8b12981306
parent 1344721974ff9f1dad
permissions -rw-r--r--
Merge RP javadoc improvements
     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  * 
     4  * Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
     5  * 
     6  * The contents of this file are subject to the terms of either the GNU General
     7  * Public License Version 2 only ("GPL") or the Common Development and Distribution
     8  * License("CDDL") (collectively, the "License"). You may not use this file except in
     9  * compliance with the License. You can obtain a copy of the License at
    10  * http://www.netbeans.org/cddl-gplv2.html or nbbuild/licenses/CDDL-GPL-2-CP. See the
    11  * License for the specific language governing permissions and limitations under the
    12  * License.  When distributing the software, include this License Header Notice in
    13  * each file and include the License file at nbbuild/licenses/CDDL-GPL-2-CP.  Sun
    14  * designates this particular file as subject to the "Classpath" exception as
    15  * provided by Sun in the GPL Version 2 section of the License file that
    16  * accompanied this code. If applicable, add the following below the License Header,
    17  * with the fields enclosed by brackets [] replaced by your own identifying
    18  * information: "Portions Copyrighted [year] [name of copyright owner]"
    19  * 
    20  * Contributor(s):
    21  * 
    22  * The Original Software is NetBeans. The Initial Developer of the Original Software
    23  * is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun Microsystems, Inc. All
    24  * Rights Reserved.
    25  * 
    26  * If you wish your version of this file to be governed by only the CDDL or only the
    27  * GPL Version 2, indicate your decision by adding "[Contributor] elects to include
    28  * this software in this distribution under the [CDDL or GPL Version 2] license." If
    29  * you do not indicate a single choice of license, a recipient has the option to
    30  * distribute your version of this file under either the CDDL, the GPL Version 2 or
    31  * to extend the choice of license to its licensees as provided above. However, if
    32  * you add GPL Version 2 code and therefore, elected the GPL Version 2 license, then
    33  * the option applies only if the new code is made subject to such option by the
    34  * copyright holder.
    35  */
    36 
    37 package org.netbeans.installer.utils.applications;
    38 
    39 import java.io.File;
    40 import java.io.FileFilter;
    41 import java.io.IOException;
    42 import java.util.ArrayList;
    43 import java.util.Arrays;
    44 import java.util.Date;
    45 import java.util.HashMap;
    46 import java.util.HashSet;
    47 import java.util.LinkedList;
    48 import java.util.List;
    49 import java.util.Map;
    50 import java.util.Set;
    51 import java.util.regex.Matcher;
    52 import java.util.regex.Pattern;
    53 import org.netbeans.installer.utils.ErrorManager;
    54 import org.netbeans.installer.utils.FileUtils;
    55 import org.netbeans.installer.utils.LogManager;
    56 import org.netbeans.installer.utils.ResourceUtils;
    57 import org.netbeans.installer.utils.StringUtils;
    58 import org.netbeans.installer.utils.SystemUtils;
    59 import org.netbeans.installer.utils.XMLUtils;
    60 import org.netbeans.installer.utils.exceptions.XMLException;
    61 import org.netbeans.installer.utils.helper.FilesList;
    62 import org.netbeans.installer.utils.helper.ErrorLevel;
    63 import org.netbeans.installer.wizard.components.panels.netbeans.NbWelcomePanel;
    64 import org.netbeans.installer.wizard.components.panels.netbeans.NbWelcomePanel.BundleType;
    65 import org.w3c.dom.Document;
    66 import org.w3c.dom.Element;
    67 
    68 /**
    69  *
    70  * @author Kirill Sorokin
    71  * @author Dmitry Lipin
    72  */
    73 public class NetBeansUtils {
    74     /////////////////////////////////////////////////////////////////////////////////
    75     // Static
    76     public static void addCluster(File nbLocation, String clusterName) throws IOException {
    77         addCluster(nbLocation, clusterName, null);
    78     }
    79 
    80     public static void addCluster(File nbLocation, String clusterName, String afterCluster) throws IOException {
    81         LogManager.log(ErrorLevel.DEBUG, "Modifying netbeans.conf for NetBeans installed at " + nbLocation + " by adding cluster \""+ clusterName + "\"" + (afterCluster==null ? "" : " after cluster \"" + afterCluster + "\""));
    82         final File netbeansclusters = new File(nbLocation, NETBEANS_CLUSTERS);
    83         touchLastModified(nbLocation, clusterName);
    84         List<String> list = FileUtils.readStringList(netbeansclusters);
    85         LogManager.log(ErrorLevel.DEBUG, "... initial list of clusters : ");
    86         LogManager.indent();
    87         LogManager.log(ErrorLevel.DEBUG, StringUtils.asString(list, SystemUtils.getLineSeparator()));
    88         LogManager.unindent();
    89         int length  = list.size();
    90         for (int i=0;i<length;i++) {
    91             String string = list.get(i);
    92             if (string.equals(clusterName)) {
    93                 if(afterCluster!=null) {
    94                     LogManager.log(ErrorLevel.DEBUG, "... after-cluster exist, removing from the list");
    95                     list.remove(i);
    96                     break;
    97                 } else {
    98                     LogManager.log(ErrorLevel.DEBUG, "... requested cluster already exist, do nothing");
    99                     return;
   100                 }
   101             }
   102         }
   103 
   104         int index = 0;
   105         for (String string : list) {
   106             index++;
   107             if (afterCluster != null && string.equals(afterCluster)) {
   108                 break;
   109             }
   110         }
   111 
   112         list.add(index, clusterName);
   113         LogManager.log(ErrorLevel.DEBUG, "... final list of clusters : ");
   114         LogManager.indent();
   115         LogManager.log(ErrorLevel.DEBUG, StringUtils.asString(list, SystemUtils.getLineSeparator()));
   116         LogManager.unindent();
   117         FileUtils.writeStringList(netbeansclusters, list);
   118     }
   119     
   120     private static void touchLastModified(File nbLocation, String clusterName) {
   121         final File clusterFile = new File(nbLocation, clusterName);
   122         final File lastModified = new File(clusterFile, LAST_MODIFIED_MARKER);
   123         // Workaround to Issue #129288 (http://www.netbeans.org/issues/show_bug.cgi?id=129288)
   124         // Enabling clusters has no effect without removal userdir
   125         // Touching of .lastModified file is done everytime when user requests to add the cluster -
   126         // even though it is already in the netbeans.clusters
   127         if(FileUtils.exists(clusterFile)) {
   128             if(!FileUtils.exists(lastModified)) {
   129                 try {
   130                     lastModified.createNewFile();
   131                     lastModified.setLastModified(new Date().getTime());
   132                 } catch (IOException e) {
   133                     LogManager.log(e);
   134                 }
   135             } else {
   136                 lastModified.setLastModified(new Date().getTime());
   137             }
   138         }
   139     }
   140     
   141     public static void removeCluster(File nbLocation, String clusterName) throws IOException {
   142         File netbeansclusters = new File(nbLocation, NETBEANS_CLUSTERS);
   143         
   144         List<String> list = FileUtils.readStringList(netbeansclusters);
   145         list.remove(clusterName);
   146         
   147         FileUtils.writeStringList(netbeansclusters, list);
   148     }
   149     
   150     public static FilesList createProductId(File nbLocation) throws IOException {
   151         File nbCluster = getNbCluster(nbLocation);
   152         
   153         File productid = new File(nbCluster, PRODUCT_ID);
   154         
   155         return FileUtils.writeFile(productid, getNetBeansId());
   156     }
   157     
   158     public static FilesList addPackId(File nbLocation, String packId) throws IOException {
   159         final File nbCluster = getNbCluster(nbLocation);
   160         
   161         final File productid = new File(nbCluster, PRODUCT_ID);
   162         
   163         final String id;
   164         if (!productid.exists()) {
   165             id = getNetBeansId();
   166         } else {
   167             id = FileUtils.readFile(productid).trim();
   168         }
   169         
   170         final List<String> ids =
   171                 new LinkedList(Arrays.asList(id.split(PACK_ID_SEPARATOR)));
   172         
   173         boolean packAdded = false;
   174         for (int i = 1; i < ids.size(); i++) {
   175             if (packId.equals(ids.get(i))) {
   176                 return new FilesList();
   177             }
   178             
   179             if (packId.compareTo(ids.get(i)) < 0) {
   180                 ids.add(i, packId);
   181                 packAdded = true;
   182                 break;
   183             }
   184         }
   185         
   186         if (!packAdded) {
   187             ids.add(packId);
   188         }
   189         
   190         return FileUtils.writeFile(
   191                 productid,
   192                 StringUtils.asString(ids, PACK_ID_SEPARATOR));
   193     }
   194 
   195     public static void updateTrackingFilesInfo(File nbLocation, String clusterName) throws IOException {
   196 
   197         File clusterDir = new File(nbLocation, clusterName);
   198         if (!FileUtils.exists(clusterDir)) {
   199             return;
   200         }
   201         LogManager.log("Update update_tracking files for cluster directory " + clusterDir);
   202         File[] files = new File(clusterDir,UPDATE_TRACKING_DIR).listFiles(new FileFilter() {
   203             public boolean accept(File pathname) {
   204                 return pathname.getName().endsWith(".xml");
   205             }
   206         });
   207         
   208         if (files != null) {
   209             for (File f : files) {
   210                 updateTrackingFilesCRC(f, clusterDir);
   211             }
   212         }
   213     }
   214 
   215     private static void updateTrackingFilesCRC(File f, File clusterDir) throws IOException {
   216         try {
   217             LogManager.log("... check if correct CRC sums are used in update_tracking file " + f);
   218             Element root = XMLUtils.getDocumentElement(f);
   219             boolean needSave = false;
   220             for (Element el : XMLUtils.getChildren(root, "module_version")) {
   221                 if ("true".equals(el.getAttribute("last"))) {
   222                     for (Element fileEl : XMLUtils.getChildren(el)) {
   223                         String crc = fileEl.getAttribute("crc");
   224                         String name = fileEl.getAttribute("name");
   225                         if (name != null && crc != null) {
   226                             File utFile = new File(clusterDir, name);
   227                             if (FileUtils.exists(utFile)) {
   228                                 long crcValue = Long.parseLong(crc);
   229                                 long realCRC = FileUtils.getCrc32(utFile);
   230                                 if (realCRC != crcValue) {
   231                                     fileEl.setAttribute("crc", new Long(realCRC).toString());
   232                                     needSave = true;
   233                                 }
   234                             }
   235                         }
   236                     }
   237                     break;
   238                 }
   239             }
   240             if (needSave) {
   241                 XMLUtils.saveXMLDocument(root.getOwnerDocument(), f);
   242             }
   243         } catch (XMLException e) {
   244             LogManager.log(e);
   245             IOException ex = new IOException("Can`t update CRC in update_tracking files");
   246             ex.initCause(e);
   247             throw ex;
   248         } catch (NumberFormatException e) {
   249             LogManager.log(e);
   250             IOException ex = new IOException("Can`t update CRC in update_tracking files");
   251             ex.initCause(e);
   252             throw ex;
   253         } catch (IOException e) {
   254             LogManager.log(e);
   255             IOException ex = new IOException("Can`t update CRC in update_tracking files");
   256             ex.initCause(e);
   257             throw ex;
   258         }
   259     }
   260 
   261     public static void removePackId(File nbLocation, String packId) throws IOException {
   262         File nbCluster = getNbCluster(nbLocation);
   263         
   264         File productid = new File(nbCluster, PRODUCT_ID);
   265         
   266         String id;
   267         if (!productid.exists()) {
   268             id = getNetBeansId();
   269         } else {
   270             id = FileUtils.readFile(productid).trim();
   271         }
   272         
   273         String[] components = id.split(PACK_ID_SEPARATOR);
   274         
   275         StringBuilder builder = new StringBuilder(components[0]);
   276         for (int i = 1; i < components.length; i++) {
   277             if (!components[i].equals(packId)) {
   278                 builder.append(PACK_ID_SEPARATOR).append(components[i]);
   279             }
   280         }
   281         
   282         FileUtils.writeFile(productid, builder);
   283     }
   284     
   285     public static void removeProductId(File nbLocation) throws IOException {
   286         File nbCluster = getNbCluster(nbLocation);
   287         
   288         File productid = new File(nbCluster, PRODUCT_ID);
   289         
   290         FileUtils.deleteFile(productid);
   291     }
   292     
   293     public static FilesList createLicenseAcceptedMarker(File nbLocation) throws IOException {
   294         File nbCluster = getNbCluster(nbLocation);
   295         
   296         File license_accepted = new File(nbCluster, LICENSE_ACCEPTED);
   297         
   298         if (!license_accepted.exists()) {
   299             return FileUtils.writeFile(license_accepted, "");
   300         } else {
   301             return new FilesList();
   302         }
   303     }
   304     
   305     public static void removeLicenseAcceptedMarker(File nbLocation) throws IOException {
   306         File nbCluster = getNbCluster(nbLocation);
   307         
   308         File license_accepted = new File(nbCluster, LICENSE_ACCEPTED);
   309         
   310         if (license_accepted.exists()) {
   311             FileUtils.deleteFile(license_accepted);
   312         }
   313     }
   314     
   315     public static FilesList setUsageStatistics(File nbLocation, boolean enabled) throws IOException {
   316         File file = new File(getNbCluster(nbLocation), CORE_PROPERTIES);
   317         String prop = USAGE_STATISTICS_ENABLED_PROPERTY + "=" + enabled;
   318         if (!file.exists()) {
   319             return FileUtils.writeFile(file,
   320                     prop);
   321         } else {
   322             List<String> list = FileUtils.readStringList(file);
   323             boolean exist = false;
   324             for (int i = 0; i < list.size(); i++) {
   325                 String s = list.get(i);
   326                 if (s.startsWith(USAGE_STATISTICS_ENABLED_PROPERTY)) {
   327                     exist = true;
   328                     if (!s.endsWith("" + enabled)) {
   329                         list.remove(i);
   330                         list.add(prop);
   331                     }
   332                     break;
   333                 }
   334             }
   335             if (!exist) {
   336                 list.add(prop);
   337             }
   338             FileUtils.writeStringList(file, list);
   339             return new FilesList();
   340         }
   341     }
   342     
   343     public static void setJavaHome(File nbLocation, File javaHome) throws IOException {
   344         File netbeansconf = new File(nbLocation, NETBEANS_CONF);
   345         
   346         String contents = FileUtils.readFile(netbeansconf);
   347         
   348         String correctJavaHome = StringUtils.escapeRegExp(javaHome.getAbsolutePath());
   349         
   350         contents = contents.replaceAll(
   351                 "#?" + NETBEANS_JDKHOME + "\".*?\"",
   352                 NETBEANS_JDKHOME + "\"" + correctJavaHome + "\"");
   353         
   354         FileUtils.writeFile(netbeansconf, contents);
   355     }
   356     
   357     public static void setUserDir(File nbLocation, File userDir) throws IOException {
   358         File netbeansconf = new File(nbLocation, NETBEANS_CONF);
   359         
   360         String contents = FileUtils.readFile(netbeansconf);
   361         
   362         String correctUserDir = StringUtils.escapeRegExp(userDir.getAbsolutePath());
   363         
   364         contents = contents.replaceAll(
   365                 NETBEANS_USERDIR +
   366                 "\".*?\"",
   367                 NETBEANS_USERDIR +
   368                 "\"" + correctUserDir + "\"");
   369         
   370         FileUtils.writeFile(netbeansconf, contents);
   371     }
   372     
   373     public static String getJvmOption(File nbLocation, String name) throws IOException {
   374         return getJvmOption(nbLocation, name, "=");
   375     }
   376     
   377     public static String getJvmOption(File nbLocation, String name, String separator) throws IOException {
   378         final File netbeansconf = new File(nbLocation, NETBEANS_CONF);
   379         
   380         final String pattern = StringUtils.format(
   381                 NETBEANS_OPTIONS_PATTERN,
   382                 StringUtils.escapeRegExp(name),
   383                 StringUtils.escapeRegExp(separator));
   384         
   385         final Matcher matcher =
   386                 Pattern.compile(pattern).matcher(FileUtils.readFile(netbeansconf));
   387         
   388         if (matcher.find()) {
   389             String value = matcher.group(4);
   390             if (value == null) {
   391                 value = matcher.group(5);
   392             }
   393             if (value == null) {
   394                 value = matcher.group(6);
   395             }
   396             
   397             return value;
   398         } else {
   399             return null;
   400         }
   401     }
   402     
   403     @Deprecated
   404     public static void addJvmOption(File nbLocation, String name) throws IOException {
   405         setJvmOption(nbLocation, name, null);
   406     }
   407     
   408     @Deprecated
   409     public static void addJvmOption(File nbLocation, String name, String value) throws IOException {
   410         setJvmOption(nbLocation, name, value);
   411     }
   412     
   413     @Deprecated
   414     public static void addJvmOption(File nbLocation, String name, String value, boolean quote) throws IOException {
   415         setJvmOption(nbLocation, name, value, quote);
   416     }
   417     
   418     @Deprecated
   419     public static void addJvmOption(File nbLocation, String name, String value, boolean quote, String separator) throws IOException {
   420         setJvmOption(nbLocation, name, value, quote, separator);
   421     }
   422     
   423     public static void setJvmOption(File nbLocation, String name) throws IOException {
   424         setJvmOption(nbLocation, name, null, false);
   425     }
   426     
   427     public static void setJvmOption(File nbLocation, String name, String value) throws IOException {
   428         setJvmOption(nbLocation, name, value, false);
   429     }
   430     
   431     public static void setJvmOption(File nbLocation, String name, String value, boolean quote) throws IOException {
   432         setJvmOption(nbLocation, name, value, quote, "=");
   433     }
   434     
   435     public static void setJvmOption(File nbLocation, String name, String value, boolean quote, String separator) throws IOException {
   436         final File netbeansconf = new File(nbLocation, NETBEANS_CONF);
   437         final String option = "-J" + name + (value != null ?
   438             separator + (quote ? "\\\"" : "") + value + (quote ? "\\\"" : "") : "");
   439         
   440         final String pattern = StringUtils.format(
   441                 NETBEANS_OPTIONS_PATTERN,
   442                 StringUtils.escapeRegExp(name),
   443                 StringUtils.escapeRegExp(separator));
   444         
   445         String contents = FileUtils.readFile(netbeansconf);
   446         final Matcher matcher =
   447                 Pattern.compile(pattern).matcher(contents);
   448         
   449         if (matcher.find()) {
   450             contents = contents.replace(matcher.group(3), option);
   451         } else {
   452             contents = contents.replace(
   453                     NETBEANS_OPTIONS + "\"",
   454                     NETBEANS_OPTIONS + "\"" + option + " ");
   455         }
   456         
   457         FileUtils.writeFile(netbeansconf, contents);
   458     }
   459     
   460     public static void removeJvmOption(File nbLocation, String name) throws IOException {
   461         removeJvmOption(nbLocation, name, "=");
   462     }
   463     
   464     public static void removeJvmOption(File nbLocation, String name, String separator) throws IOException {
   465         final File netbeansconf = new File(nbLocation, NETBEANS_CONF);
   466         
   467         String contents = FileUtils.readFile(netbeansconf);
   468         
   469         final String pattern = StringUtils.format(
   470                 NETBEANS_OPTIONS_PATTERN,
   471                 StringUtils.escapeRegExp(name),
   472                 StringUtils.escapeRegExp(separator));
   473         
   474         final Matcher matcher =
   475                 Pattern.compile(pattern).matcher(contents);
   476         
   477         if (matcher.find()) {
   478             contents = contents.replace(" " + matcher.group(3), "");
   479             contents = contents.replace(matcher.group(3) + " ", "");
   480             contents = contents.replace(matcher.group(3), "");
   481         }
   482         
   483         FileUtils.writeFile(netbeansconf, contents);
   484     }
   485     
   486     /**
   487      * Get JVM memory value.
   488      *
   489      * @param nbLocation NetBeans home directory
   490      * @param memoryType Memory type that can be one of the following values
   491      *          <ul><li> <code>MEMORY_XMX</code></li>
   492      *              <li> <code>MEMORY_XMS</code></li>
   493      *              <li> <code>MEMORY_XSS</code></li>
   494      *          </ul>
   495      * @return The size of memory in bytes. <br>
   496      *         If there is no such option then return 0;
   497      */
   498     public static long getJvmMemorySize(File nbLocation, String memoryType) throws IOException {
   499         final String size = getJvmOption(nbLocation, memoryType, "");
   500         
   501         if (size != null) {
   502             return getJavaMemorySize(size);
   503         } else {
   504             return 0;
   505         }
   506     }
   507     
   508     /**
   509      * Get JVM memory value. <br>
   510      * If value is <i>zero</i> then remove the jvm option from netbeans options<br><br>
   511      * @param nbLocation NetBeans home directory
   512      * @param memoryType Memory type that can be one of the following values
   513      *           <ul><li> <code>MEMORY_XMX</code></li>
   514      *              <li> <code>MEMORY_XMS</code></li>
   515      *              <li> <code>MEMORY_XSS</code></li>
   516      *          </ul>
   517      * @param value Size of memory to be set
   518      */
   519     public static void setJvmMemorySize(File nbLocation, String memoryType, long size) throws IOException {
   520         setJvmOption(nbLocation, memoryType, formatJavaMemoryString(size), false, "");
   521     }
   522     /**
   523      * Get NetBeans branding cluster directory
   524      * @throws IOException if the no cluster directory exists
   525      */
   526     public static File getNbCluster(File nbLocation) throws IOException {
   527         for (File child: nbLocation.listFiles()) {
   528             if (child.isDirectory() && child.getName().matches(NB_CLUSTER_PATTERN)) {
   529                 return child;
   530             }
   531         }
   532         throw new IOException(ERROR_BRANDING_CLUSTER_NOT_EXIS_STRING);
   533     }
   534     
   535     /**
   536      * Get resolved netbeans user directory
   537      * @param nbLocation NetBeans home directory
   538      * @throws IOException if can`t get netbeans default userdir
   539      */
   540     public static File getNetBeansUserDirFile(File nbLocation) throws IOException {
   541         String dir = getNetBeansUserDir(nbLocation);
   542         dir = dir.replace(USER_HOME_TOKEN, System.getProperty("user.home"));
   543         return new File(dir);
   544     }
   545     
   546     /**
   547      * Get netbeans user directory as it is written in netbeans.conf
   548      * @param nbLocation NetBeans home directory
   549      * @throws IOException if can`t get netbeans default userdir
   550      */
   551     public static String getNetBeansUserDir(File nbLocation) throws IOException {
   552         File netbeansconf = new File(nbLocation, NETBEANS_CONF);
   553         String contents = FileUtils.readFile(netbeansconf);
   554         Matcher matcher = Pattern.compile(
   555                 NEW_LINE_PATTERN + SPACES_PATTERN +
   556                 NETBEANS_USERDIR +
   557                 "\"(.*?)\"").matcher(contents);
   558         if(matcher.find() && matcher.groupCount() == 1) {
   559             return matcher.group(1);
   560         } else {
   561             throw new IOException(StringUtils.format(
   562                     ERROR_CANNOT_GET_USERDIR_STRING,netbeansconf));
   563         }
   564     }
   565     
   566     /**
   567      * Get jdkhome as it is written in netbeans.conf
   568      * @param nbLocation NetBeans home directory
   569      * @return JDK location
   570      * @throws IOException if can`t get netbeans_jdkhome value of netbeans.conf
   571      */
   572     public static String getJavaHome(File nbLocation) throws IOException {
   573         File netbeansconf = new File(nbLocation, NETBEANS_CONF);
   574         String contents = FileUtils.readFile(netbeansconf);
   575         
   576         Matcher matcher = Pattern.compile(
   577                 NEW_LINE_PATTERN + SPACES_PATTERN +
   578                 NETBEANS_JDKHOME +
   579                 "\"(.*?)\"").matcher(contents);
   580         
   581         if(matcher.find() && matcher.groupCount() == 1) {
   582             return matcher.group(1);
   583         } else {
   584             throw new IOException(StringUtils.format(
   585                     ERROR_CANNOT_GET_JAVAHOME_STRING, netbeansconf));
   586         }
   587     }
   588     
   589     /**
   590      * Check if NetBeans is running
   591      * @param nbLocation NetBeans home directory
   592      * @return True if NetBeans is running
   593      * @throws IOException if can`t say for sure whether it is running or not
   594      */
   595     public static boolean isNbRunning(File nbLocation) throws IOException {
   596         return FileUtils.exists(getLockFile(nbLocation));
   597     }
   598     
   599     public static File getLockFile(File nbLocation) throws IOException {
   600         return new File(getNetBeansUserDirFile(nbLocation), "lock");
   601     }
   602     
   603     /**
   604      *  Test for running NetBeans IDE.<br>
   605      *  If the lock file exist - issue a warning but do not throw an exception
   606      */
   607     public static boolean warnNetbeansRunning(File nbLocation) {
   608         try {
   609             boolean isRunning = isNbRunning(nbLocation);
   610             if (isRunning) {
   611                 if(!checkedAndRunning.contains(nbLocation)) {
   612                     checkedAndRunning.add(nbLocation);
   613                     final String message = ResourceUtils.getString(
   614                             NetBeansUtils.class,
   615                             "NU.warning.running"); // NOI18N
   616                     final String warning = StringUtils.format(
   617                             message,
   618                             nbLocation,
   619                             NetBeansUtils.getLockFile(nbLocation));
   620                     
   621                     ErrorManager.notifyWarning(warning);
   622                 }
   623             } else {
   624                 checkedAndRunning.remove(nbLocation);
   625             }
   626             
   627             return isRunning;
   628         } catch (IOException e) {
   629             ErrorManager.notifyDebug(
   630                     "Can`t say for sure if NetBeans is running or not",
   631                     e);
   632         }
   633         
   634         return false;
   635     }
   636     
   637     public static void updateNetBeansHome(final File nbLocation) throws IOException {
   638         FileUtils.modifyFile(
   639                 new File(nbLocation, NETBEANS_CONF),
   640                 NETBEANS_HOME_TOKEN,
   641                 nbLocation.getAbsolutePath());
   642     }
   643     
   644     public static void runUpdater(File nbLocation) throws IOException {
   645         File jdkLocation = new File(getJavaHome(nbLocation));
   646         LogManager.log("running the NetBeans updater : ");
   647         LogManager.log("    nbLocation = " + nbLocation);
   648         LogManager.log("    jdkLocation = " + jdkLocation);
   649         
   650         List <File> classes = new ArrayList <File> ();
   651         List <File> nbDirs = new ArrayList <File> ();
   652         
   653         
   654         File netbeansclusters = new File(nbLocation, NETBEANS_CLUSTERS);
   655         List<String> list = FileUtils.readStringList(netbeansclusters);
   656                 
   657         File platformCluster = null;
   658         
   659         for(String s : list) {
   660             String cluster = s.trim();
   661             if(!cluster.startsWith("#") &&
   662                     !cluster.equals("etc")) {
   663                 nbDirs.add(new File(nbLocation, cluster));
   664                 if(cluster.startsWith("platform")) {
   665                     platformCluster= new File(nbLocation, cluster);
   666                 }
   667             }
   668         }
   669         
   670         String nbDirsString = StringUtils.asString(nbDirs, File.pathSeparator);
   671         
   672         LogManager.log("    adding classes to classpath");
   673         classes.add(new File(platformCluster,
   674                 "lib" + File.separator + "boot.jar"));
   675         if(!SystemUtils.isMacOS()) {
   676             classes.add(new File(jdkLocation,
   677                     "lib" + File.separator + "tools.jar" ));
   678         }
   679         classes.add(new File(jdkLocation,
   680                 "lib" + File.separator + "dt.jar"));
   681         classes.add(new File(platformCluster,
   682                 "modules" + File.separator +
   683                 "ext" + File.separator +
   684                 "updater.jar"));
   685         String classpath = StringUtils.asString(classes, File.pathSeparator);
   686         
   687         String importClassProp = "netbeans.importclass";
   688         String nbHomeProp = "netbeans.home";
   689         String nbHome = platformCluster.getPath();
   690         String nbUserdir = getNetBeansUserDirFile(nbLocation).getPath();
   691         String nbUserdirProp = "netbeans.user";
   692         String nbDirsProp = "netbeans.dirs";
   693         String sysProp ="-D";
   694         String eq = "=";
   695         String java = JavaUtils.getExecutable(jdkLocation).getPath();
   696         LogManager.log("    executing updater...");
   697         SystemUtils.executeCommand(nbLocation, new String [] {
   698             java,
   699             sysProp + importClassProp + eq + UPDATER_CLASSNAME,
   700             sysProp + nbHomeProp    + eq + nbHome,
   701             sysProp + nbUserdirProp + eq + nbUserdir,
   702             sysProp + nbDirsProp    + eq + nbDirsString,
   703             "-Xms32m", "-XX:MaxPermSize=96m", "-Xverify:none", "-Xmx128m",
   704             "-cp", classpath,
   705             UPDATER_FRAMENAME, "--nosplash"});
   706     }
   707     public static final boolean setModuleStatus(File nbLocation, String clusterName, String moduleName, boolean enable) {        
   708         LogManager.log(ErrorLevel.DEBUG,
   709                 ((enable) ? "... enabling" : "disabling") +
   710                 " module " + moduleName + 
   711                 " in cluster " + clusterName + 
   712                 " at " + nbLocation);
   713         final File configFile = getConfigFile(nbLocation, clusterName, moduleName);
   714         if (FileUtils.exists(configFile)) {
   715             Document doc = null;
   716             try {
   717                 doc = XMLUtils.loadXMLDocument(configFile);
   718             } catch (XMLException e) {
   719                 LogManager.log("Cannot load config file", e);
   720             }
   721             if (doc != null) {
   722                 for (Element element : XMLUtils.getChildren(doc.getDocumentElement(), "param")) {
   723                     if (element.getAttribute("name").equals("enabled")) {
   724                         if (element.getTextContent().equals(Boolean.toString(!enable))) {
   725                             element.setTextContent(Boolean.toString(enable));
   726                             try {
   727                                 XMLUtils.saveXMLDocument(doc, configFile);
   728                                 LogManager.log(ErrorLevel.MESSAGE, "... module status changed");
   729                                 return true;
   730                             } catch (XMLException e) {
   731                                 LogManager.log("... Cannot save config file", e);
   732                             }
   733                         } else {
   734                             LogManager.log(ErrorLevel.MESSAGE, "... module is already set to requested status");
   735                             return true;
   736                         }
   737                         break;
   738                     }
   739                 }
   740             }
   741             LogManager.log(ErrorLevel.MESSAGE,"... module status did not changed");
   742         } else {
   743             LogManager.log(ErrorLevel.MESSAGE,"... module config file does not exist at " + configFile);
   744         }
   745         return false;
   746     }
   747     
   748     public static final Boolean getModuleStatus(File nbLocation, String clusterName, String moduleName) {        
   749         LogManager.log(ErrorLevel.DEBUG, 
   750                 "... getting status of module " + moduleName + 
   751                 " in cluster " + clusterName + 
   752                 " at " + nbLocation);
   753         final File configFile = getConfigFile(nbLocation, clusterName, moduleName);
   754         
   755         if (FileUtils.exists(configFile)) {
   756             Document doc = null;
   757             try {
   758                 doc = XMLUtils.loadXMLDocument(configFile);
   759             } catch (XMLException e) {
   760                 LogManager.log("Cannot load config file", e);
   761             }
   762             if (doc != null) {
   763                 for (Element element : XMLUtils.getChildren(doc.getDocumentElement(), "param")) {
   764                     if (element.getAttribute("name").equals("enabled")) {
   765                          return new Boolean(element.getTextContent());
   766                 }
   767                 }
   768             }
   769             LogManager.log(ErrorLevel.MESSAGE,"... cannot get module status");
   770         } else {
   771             LogManager.log(ErrorLevel.MESSAGE,"... module config file does not exist");
   772         }
   773         return null;
   774     }
   775     
   776     private static File getConfigFile(File nbLocation, String clusterName, String moduleName) {
   777         File cluster = new File (nbLocation, clusterName);
   778         return new File(cluster, "config" + File.separator + "Modules" + File.separator + moduleName + ".xml");
   779     }
   780     
   781     // private //////////////////////////////////////////////////////////////////////
   782     private static long getJavaMemorySize(String string) {
   783         String suffix = string.substring(string.length() - 1);
   784         
   785         if(!suffix.matches(DIGITS_PATTERN)) {
   786             long value = Long.parseLong(string.substring(0, string.length() - 1));
   787             if(suffix.equalsIgnoreCase("k")) {
   788                 value *= K;
   789             } else if(suffix.equalsIgnoreCase("m")) {
   790                 value *= M;
   791             } else if(suffix.equalsIgnoreCase("g")) {
   792                 value *= G;
   793             } else if(suffix.equalsIgnoreCase("t")) {
   794                 value *= T;
   795             }
   796             return value;
   797         } else {
   798             return new Long(string).longValue() * M; // default - megabytes
   799         }
   800     }
   801     
   802     private static String formatJavaMemoryString(long size) {
   803         if((size > T) && (size % T == 0)) {
   804             return StringUtils.EMPTY_STRING + (size/T) + "t";
   805         } else if((size > G) && (size % G == 0)) {
   806             return StringUtils.EMPTY_STRING + (size/G) + "g";
   807         } else if((size > M) && (size % M == 0)) {
   808             return StringUtils.EMPTY_STRING + (size/M) + "m";
   809         }  else if((size > K) && (size % K == 0)) {
   810             return StringUtils.EMPTY_STRING + (size/K) + "k";
   811         } else {
   812             if(size > (10 * M)) {
   813                 // round up to the nearest M value
   814                 return StringUtils.EMPTY_STRING + (size/M + 1) + "m";
   815             } else {
   816                 // round up to the nearest K value
   817                 return StringUtils.EMPTY_STRING + (size/K + 1) + "k";
   818             }
   819         }
   820     }
   821     public static String getNetBeansId() {
   822         return BundleType.getType(
   823                 System.getProperty(NbWelcomePanel.WELCOME_PAGE_TYPE_PROPERTY)).
   824                 getNetBeansBundleId();
   825     }
   826     /////////////////////////////////////////////////////////////////////////////////
   827     // Instance
   828     private NetBeansUtils() {
   829         // does nothing
   830     }
   831     
   832     /////////////////////////////////////////////////////////////////////////////////
   833     // Constants
   834     public static final String NETBEANS_CLUSTERS =
   835             "etc/netbeans.clusters"; // NOI18N
   836     public static final String NETBEANS_CONF =
   837             "etc/netbeans.conf"; // NOI18N
   838     public static final String PRODUCT_ID =
   839             "config/productid"; // NOI18N
   840     public static final String LICENSE_ACCEPTED =
   841             "var/license_accepted"; // NOI18N
   842     public static final String CORE_PROPERTIES =
   843             "config/Preferences/org/netbeans/core.properties";
   844     public static final String USAGE_STATISTICS_ENABLED_PROPERTY = 
   845             "usageStatisticsEnabled";//NOI18N
   846     public static final String DIGITS_PATTERN =
   847             "[0-9]+"; // NOI18N
   848     public static final String CLUSTER_NUMBER_PATTERN =
   849             DIGITS_PATTERN + "(\\." + DIGITS_PATTERN + ")?"; // NOI18N
   850     
   851     public static final String NB_CLUSTER_PATTERN =
   852             "nb" + CLUSTER_NUMBER_PATTERN; // NOI18N
   853     public static final String NEW_LINE_PATTERN =
   854             "[\r\n|\n|\r]"; // NOI18N
   855     public static final String SPACES_PATTERN =
   856             "\\ *"; // NOI18N
   857     
   858     public static final String NETBEANS_USERDIR =
   859             "netbeans_default_userdir="; // NOI18N
   860     public static final String NETBEANS_JDKHOME =
   861             "netbeans_jdkhome="; // NOI18N
   862     public static final String NETBEANS_OPTIONS =
   863             "netbeans_default_options="; // NOI18N
   864     
   865     public static final String NETBEANS_OPTIONS_PATTERN =
   866             NETBEANS_OPTIONS + "\"(.*?)( ?)(-J{0}(?:{1}\\\\\\\"(.*?)\\\\\\\"|{1}(.*?)|())(?= |\"))( ?)(.*)?\"";
   867 
   868     public static final String LAST_MODIFIED_MARKER =
   869            ".lastModified";
   870     public static final String UPDATE_TRACKING_DIR =
   871             "update_tracking";
   872     public static final String NB_IDE_ID =
   873             "NB"; // NOI18N
   874     public static final String PACK_ID_SEPARATOR =
   875             "_"; // NOI18N
   876     public static final String MEMORY_XMX =
   877             "-Xmx"; // NOI18N
   878     public static final String MEMORY_XMS =
   879             "-Xms"; // NOI18N
   880     public static final String MEMORY_XSS =
   881             "-Xss"; // NOI18N
   882     public static final String USER_HOME_TOKEN =
   883             "${HOME}"; // NOI18N
   884     public static final String NETBEANS_HOME_TOKEN =
   885             "${NETBEANS_HOME}"; // NOI18N
   886     public static final String UPDATER_FRAMENAME = 
   887             "org.netbeans.updater.UpdaterFrame";
   888     public static final String UPDATER_CLASSNAME = 
   889             "org.netbeans.upgrade.AutoUpgrade";
   890     public static final String ERROR_BRANDING_CLUSTER_NOT_EXIS_STRING =
   891             ResourceUtils.getString(NetBeansUtils.class,
   892             "NU.error.branding.cluster.not.exists");//NOI18N
   893     public static final String ERROR_CANNOT_GET_USERDIR_STRING =
   894             ResourceUtils.getString(NetBeansUtils.class,
   895             "NU.error.cannot.get.userdir");//NOI18N
   896     public static final String ERROR_CANNOT_GET_JAVAHOME_STRING =
   897             ResourceUtils.getString(NetBeansUtils.class,
   898             "NU.error.cannot.get.javahome");//NOI18N
   899     
   900     public static final long K =
   901             1024; // NOMAGI
   902     public static final long M =
   903             K * K;
   904     public static final long G =
   905             M * K;
   906     public static final long T =
   907             G * K;
   908     // one set for the whole installer
   909     private static Set <File> checkedAndRunning = new HashSet <File> ();
   910     
   911     private static final String MEMORY_SUFFIX_PATTERN =
   912             "[kKmMgGtT]?"; // NOI18N
   913 }