Index: core/arch/arch-core-launcher.xml =================================================================== RCS file: /cvs/core/arch/arch-core-launcher.xml,v retrieving revision 1.30 diff -c -r1.30 arch-core-launcher.xml *** core/arch/arch-core-launcher.xml 10 Aug 2005 19:26:22 -0000 1.30 --- core/arch/arch-core-launcher.xml 16 Aug 2005 12:28:44 -0000 *************** *** 516,527 **** system property and if provided it loads that class and invokes its main method (in AWT thread) and if no exception is thrown it marks the userdir as already upgraded. ! . ${netbeans.user}/var/imported is used to identify whether a userdir has already been updated or it still needs an update. Can be created by installer if no update check should be performed, no other code is supposed to realy on this file.
  • --- 516,546 ---- system property and if provided it loads that class and invokes its main method (in AWT thread) and if no exception is thrown it marks the userdir as already upgraded. ! ${netbeans.user}/var/imported is used to identify whether a userdir has already been updated or it still needs an update. Can be created by installer if no update check should be performed, no other code is supposed to realy on this file. + + + Before first usage of IDE user must accept license. If user does not install IDE + by installer (user must accept license during installation) user must accept license + during IDE first start. +

    Launcher calls method showLicensePanel of netbeans.acceptlicenseclass + if license was not yet accepted by user and it is necessary to show license + in dialog to user.

    +
    . + + ${netbeans.user}/var/license_accepted and ${nbcluster.dir}/var/license_accepted + are used to identify whether user accepted license. + + + User preferences node org.netbeans.core.startup.Main.class is used to identify whether user accepted license. + As key string "LICENSE" + "|" + [IDE (License) version] + "|" + [MD5 fingerprint of install dir] is used. + Special key is in Bundle for [IDE (License) version]. + MD5 fingerprint is used because key length in default preferences implementation is limited + to 80 characters.
  • Index: core/startup/src/org/netbeans/core/startup/Bundle.properties =================================================================== RCS file: /cvs/core/startup/src/org/netbeans/core/startup/Bundle.properties,v retrieving revision 1.5 diff -c -r1.5 Bundle.properties *** core/startup/src/org/netbeans/core/startup/Bundle.properties 11 Aug 2005 11:51:18 -0000 1.5 --- core/startup/src/org/netbeans/core/startup/Bundle.properties 16 Aug 2005 12:28:44 -0000 *************** *** 21,26 **** --- 21,28 ---- # VERSIONING (TopLogging, MainWindow) # {0} - build number currentVersion=NetBeans Platform Dev (Build {0}) + #Used as ID for license check. It should be changed when license is changed. + licenseVersion=NetBeans Platform 4.2 Dev # TopManager properties ERR_no_user_directory=netbeans.user is not set.\nPlease check your NetBeans startup script. Index: core/startup/src/org/netbeans/core/startup/Main.java =================================================================== RCS file: /cvs/core/startup/src/org/netbeans/core/startup/Main.java,v retrieving revision 1.2 diff -c -r1.2 Main.java *** core/startup/src/org/netbeans/core/startup/Main.java 7 Jun 2005 04:45:59 -0000 1.2 --- core/startup/src/org/netbeans/core/startup/Main.java 16 Aug 2005 12:28:46 -0000 *************** *** 12,45 **** */ package org.netbeans.core.startup; - - import java.awt.*; - import java.awt.event.*; import java.beans.*; import java.io.*; import java.lang.reflect.Method; import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.MissingResourceException; import javax.swing.*; - import javax.swing.border.*; import org.openide.*; import org.openide.filesystems.*; - import org.openide.filesystems.FileSystem; import org.openide.modules.SpecificationVersion; import org.openide.modules.Dependency; import org.openide.util.NbBundle; import org.openide.util.SharedClassObject; import org.openide.util.Utilities; - import org.openide.util.io.*; - - import java.util.Hashtable; - import java.lang.reflect.Field; import java.net.URL; ! import javax.swing.plaf.InputMapUIResource; ! import javax.swing.plaf.metal.MetalLookAndFeel; /** * Main class for NetBeans when run in GUI mode. --- 12,38 ---- */ package org.netbeans.core.startup; import java.beans.*; import java.io.*; import java.lang.reflect.Method; + import java.security.MessageDigest; + import java.security.NoSuchAlgorithmException; import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.MissingResourceException; + import java.util.prefs.Preferences; import javax.swing.*; import org.openide.*; import org.openide.filesystems.*; import org.openide.modules.SpecificationVersion; import org.openide.modules.Dependency; import org.openide.util.NbBundle; import org.openide.util.SharedClassObject; import org.openide.util.Utilities; import java.net.URL; ! import org.openide.modules.InstalledFileLocator; /** * Main class for NetBeans when run in GUI mode. *************** *** 331,336 **** --- 324,342 ---- // ----------------------------------------------------------------------------------------------------- + // License check + try { + if ((System.getProperty ("netbeans.full.hack") == null) && (System.getProperty ("netbeans.close") == null)) { + if (!handleLicenseCheck()) { + org.netbeans.TopSecurityManager.exit(0); + } + } + } catch (Exception e) { + ErrorManager.getDefault().notify(e); + } + StartLog.logProgress ("License check performed"); // NOI18N + + // ----------------------------------------------------------------------------------------------------- // Upgrade try { if ((System.getProperty ("netbeans.full.hack") == null) && (System.getProperty ("netbeans.close") == null)) { *************** *** 565,571 **** ImportHandler handler = new ImportHandler (); ! return handler.canContinue (); } --- 571,727 ---- ImportHandler handler = new ImportHandler (); ! ! return handler.canContinue (); ! } ! ! /** Displays license to user to accept if necessary. Made non-private just for testing purposes. ! * ! * @return true if the execution should continue or false if it should ! * stop ! */ ! static boolean handleLicenseCheck () { ! class LicenseHandler implements Runnable { ! private String classname; ! private boolean executedOk; ! private String nbHome; ! private Preferences prefUserNode; ! private String licenseVersion; ! private String LICENSE = "LICENSE"; // NOI18N ! private String md5sumKey; ! ! /** Generate 32 byte long fingerprint of input string in sting form */ ! private String generateKey (String input) { ! String key = null; ! //Set default value in case anything fails. ! if (input.length() > 32) { ! key = input.substring(input.length() - 32, input.length()); ! } else { ! key = input; ! } ! MessageDigest md = null; ! try { ! md = MessageDigest.getInstance("MD5"); // NOI18N ! } catch (NoSuchAlgorithmException exc) { ! exc.printStackTrace(); ! return key; ! } ! ! byte [] arr = new byte[0]; ! try { ! arr = nbHome.getBytes("UTF-8"); // NOI18N ! } catch (UnsupportedEncodingException exc) { ! exc.printStackTrace(); ! return key; ! } ! ! byte [] md5sum = md.digest(arr); ! StringBuffer keyBuff = new StringBuffer(32); ! //Convert byte array to hexadecimal string to be used as key ! for (int i = 0; i < md5sum.length; i++) { ! int val = md5sum[i]; ! if (val < 0) { ! val = val + 256; ! } ! String s = Integer.toHexString(val); ! if (s.length() == 1) { ! keyBuff.append("0"); ! } ! keyBuff.append(Integer.toHexString(val)); ! } ! key = keyBuff.toString(); ! return key; ! } ! ! /** Checks if licence was accepted already or not. */ ! public boolean shouldDisplayLicense () { ! File f = InstalledFileLocator.getDefault().locate("var/license_accepted",null,false); // NOI18N ! if (f != null) { ! return false; ! } ! //Check preferences ! licenseVersion = NbBundle.getMessage(Main.class,"licenseVersion"); // NOI18N ! nbHome = System.getProperty("netbeans.home"); // NOI18N ! File nbHomeDir = new File(nbHome); ! try { ! nbHome = nbHomeDir.getCanonicalPath(); ! } catch (IOException exc) { ! exc.printStackTrace(); ! } ! md5sumKey = generateKey(nbHome); ! ! prefUserNode = Preferences.userNodeForPackage(Main.class); ! String value = prefUserNode.get(LICENSE + "|" + licenseVersion + "|" + md5sumKey,"N/A"); // NOI18N ! if ("N/A".equals(value)) { ! classname = System.getProperty("netbeans.accept_license_class"); // NOI18N ! return (classname != null); ! } else { ! //Create file "var/license_accepted" in user dir if it does not exist ! //to speed up check ! f = new File (new File(CLIOptions.getUserDir(), "var"), "license_accepted"); // NOI18N ! if (!f.exists()) { ! f.getParentFile().mkdirs (); ! try { ! f.createNewFile(); ! } catch (IOException exc) { ! exc.printStackTrace(); ! } ! } ! return false; ! } ! } ! ! public void run() { ! Class clazz = getKlass (classname); ! ! // This module is included in our distro somewhere... may or may not be turned on. ! // Whatever - try running some classes from it anyway. ! try { ! Method showMethod = clazz.getMethod("showLicensePanel",null); // NOI18N ! showMethod.invoke (null, null); ! executedOk = true; ! //License accepted - set any string != "N/A" ! prefUserNode.put(LICENSE + "|" + licenseVersion + "|" + md5sumKey,"accepted"); // NOI18N ! } catch (java.lang.reflect.InvocationTargetException ex) { ! // canceled by user, all is fine ! if (ex.getTargetException() instanceof org.openide.util.UserCancelException) { ! executedOk = false; ! } else { ! ex.printStackTrace(); ! } ! } catch (Exception ex) { ! // If exceptions are thrown, notify them - something is broken. ! ex.printStackTrace(); ! } catch (LinkageError ex) { ! // These too... ! ex.printStackTrace(); ! } ! } ! ! public boolean canContinue () { ! if (shouldDisplayLicense ()) { ! try { ! SwingUtilities.invokeAndWait (this); ! if (executedOk) { ! return true; ! } else { ! return false; ! } ! } catch (java.lang.reflect.InvocationTargetException ex) { ! return false; ! } catch (InterruptedException ex) { ! ex.printStackTrace(); ! return false; ! } ! } else { ! // if there is no need to upgrade that every thing is good ! return true; ! } ! } ! } ! ! LicenseHandler handler = new LicenseHandler (); ! return handler.canContinue (); } Index: ide/branding/core/src/org/netbeans/core/startup/Bundle_nb.properties =================================================================== RCS file: /cvs/ide/branding/core/src/org/netbeans/core/startup/Bundle_nb.properties,v retrieving revision 1.2 diff -c -r1.2 Bundle_nb.properties *** ide/branding/core/src/org/netbeans/core/startup/Bundle_nb.properties 1 Aug 2005 21:42:37 -0000 1.2 --- ide/branding/core/src/org/netbeans/core/startup/Bundle_nb.properties 16 Aug 2005 12:28:48 -0000 *************** *** 44,46 **** --- 44,49 ---- LBL_splash_window_title=Starting NetBeans IDE currentVersion=NetBeans IDE Dev (Build {0}) + #Used as ID for license check. It should be changed when license is changed. + licenseVersion=NetBeans IDE 4.2 Dev + Index: ide/launcher/os2/netbeans.cmd =================================================================== RCS file: /cvs/ide/launcher/os2/netbeans.cmd,v retrieving revision 1.10 diff -c -r1.10 netbeans.cmd *** ide/launcher/os2/netbeans.cmd 22 Jul 2005 09:01:03 -0000 1.10 --- ide/launcher/os2/netbeans.cmd 16 Aug 2005 12:28:51 -0000 *************** *** 55,61 **** platdir = directory(progdir||"\platform6\lib") say platdir ! nb_args='-J-Dnetbeans.importclass=org.netbeans.upgrade.AutoUpgrade --branding nb --clusters '||netbeans_clusters||' '||nb_args __launcher = 'call "'||platdir||'\nbexec.cmd" (nb_args)' interpret __launcher n = endlocal() --- 55,61 ---- platdir = directory(progdir||"\platform6\lib") say platdir ! nb_args='-J-Dnetbeans.importclass=org.netbeans.upgrade.AutoUpgrade -J-Dnetbeans.accept_license_class=org.netbeans.license.AcceptLicense --branding nb --clusters '||netbeans_clusters||' '||nb_args __launcher = 'call "'||platdir||'\nbexec.cmd" (nb_args)' interpret __launcher n = endlocal() Index: ide/launcher/unix/netbeans =================================================================== RCS file: /cvs/ide/launcher/unix/netbeans,v retrieving revision 1.22 diff -c -r1.22 netbeans *** ide/launcher/unix/netbeans 8 Aug 2005 06:48:00 -0000 1.22 --- ide/launcher/unix/netbeans 16 Aug 2005 12:28:51 -0000 *************** *** 78,83 **** --- 78,84 ---- --clusters "$netbeans_clusters" \ --userdir "${userdir}" \ -J-Dnetbeans.importclass=org.netbeans.upgrade.AutoUpgrade \ + -J-Dnetbeans.accept_license_class=org.netbeans.license.AcceptLicense \ ${netbeans_default_options} \ $args ;; *************** *** 88,93 **** --- 89,95 ---- --clusters "$netbeans_clusters" \ --userdir "${userdir}" \ -J-Dnetbeans.importclass=org.netbeans.upgrade.AutoUpgrade \ + -J-Dnetbeans.accept_license_class=org.netbeans.license.AcceptLicense \ ${netbeans_default_options} \ $args ;; Index: ide/launcher/windows/netbeans.cpp =================================================================== RCS file: /cvs/ide/launcher/windows/netbeans.cpp,v retrieving revision 1.16 diff -c -r1.16 netbeans.cpp *** ide/launcher/windows/netbeans.cpp 3 Aug 2005 00:08:32 -0000 1.16 --- ide/launcher/windows/netbeans.cpp 16 Aug 2005 12:28:53 -0000 *************** *** 109,115 **** sprintf(nbexec, "%s\\platform6\\lib\\nbexec.exe", topdir); ! sprintf(cmdline2, "\"%s\" %s -J-Dnetbeans.importclass=org.netbeans.upgrade.AutoUpgrade --branding nb --clusters \"%s\" --userdir \"%s\" %s %s", nbexec, jdkswitch, dirs, --- 109,115 ---- sprintf(nbexec, "%s\\platform6\\lib\\nbexec.exe", topdir); ! sprintf(cmdline2, "\"%s\" %s -J-Dnetbeans.importclass=org.netbeans.upgrade.AutoUpgrade -J-Dnetbeans.accept_license_class=org.netbeans.license.AcceptLicense --branding nb --clusters \"%s\" --userdir \"%s\" %s %s", nbexec, jdkswitch, dirs, Index: installer/lib/src/org/netbeans/installer/PostInstallFixupAction.java =================================================================== RCS file: /cvs/installer/lib/src/org/netbeans/installer/PostInstallFixupAction.java,v retrieving revision 1.12 diff -c -r1.12 PostInstallFixupAction.java *** installer/lib/src/org/netbeans/installer/PostInstallFixupAction.java 3 Aug 2005 08:19:40 -0000 1.12 --- installer/lib/src/org/netbeans/installer/PostInstallFixupAction.java 16 Aug 2005 12:29:04 -0000 *************** *** 117,122 **** --- 117,138 ---- logEvent(this, Log.ERROR, ex); } } + //Create file 'license_accepted'. It gives info to IDE that user + //accepted license during installation + try { + String dir = nbInstallDir + sep + nbClusterDir + sep + "var"; + if (!fileService.fileExists(dir)) { + fileService.createDirectory(dir); + } else if (!fileService.isDirectory(dir)) { + logEvent(this, Log.WARNING, "File: " + dir + " already exists but is not directory."); + } + String fileName = nbInstallDir + sep + nbClusterDir + sep + "var" + sep + "license_accepted"; + logEvent(this, Log.DBG, "create file: " + fileName); + fileService.createBinaryFile(fileName,new byte[0]); + } + catch (Exception ex) { + logEvent(this, Log.ERROR, ex); + } installIDEConfigFile(); *************** *** 139,144 **** --- 155,165 ---- deleteFiles(nbInstallDir, new String[] {"etc" + sep + "netbeans.conf"}); deleteFiles(uninstallDir, new String[] {"install.log"}); deleteFiles(nbInstallDir, new String[] {nbClusterDir + sep + "config" + sep + "productid" }); + deleteFiles(nbInstallDir, new String[] {nbClusterDir + sep + "var" + sep + "license_accepted" }); + //Delete only this dir and only if empty + String dirName = nbInstallDir + sep + nbClusterDir + sep + "var"; + logEvent(this, Log.DBG, "Trying to delete: " + dirName); + fileService.deleteDirectory(dirName,true,false); if (Util.isMacOSX()) { deleteSymbolicLink(); *************** *** 290,300 **** } public void deleteFiles(String dir, String[] fileNames) { ! for (int i=0; i< fileNames.length; i++) { if (fileNames[i] == null) { //array bigger than num objs in array. return; } ! String filename =dir + sep + fileNames[i]; try { if (fileService.fileExists(filename)) { logEvent(this, Log.DBG, "deleting " + filename); --- 311,321 ---- } public void deleteFiles(String dir, String[] fileNames) { ! for (int i = 0; i < fileNames.length; i++) { if (fileNames[i] == null) { //array bigger than num objs in array. return; } ! String filename = dir + sep + fileNames[i]; try { if (fileService.fileExists(filename)) { logEvent(this, Log.DBG, "deleting " + filename);