|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.updater; import java.io.*; import java.util.*; import java.util.jar.*; //import org.openide.util.NbBundle; /** Class used by autoupdate module for the work with module files and * for installing / uninstalling modules * * @author Petr Hrebejk, Ales Kemr * @version */ public final class ModuleUpdater extends Thread { /** Platform dependent file name separator */ private static final String FILE_SEPARATOR = System.getProperty ("file.separator"); private static final String PATH_SEPARATOR = System.getProperty ("path.separator"); /** Relative name of update directory */ private static final String UPDATE_DIR = "update"; // NOI18N /** Relative name of directory where the .NBM files are downloaded */ static final String DOWNLOAD_DIR =UPDATE_DIR + FILE_SEPARATOR + "download"; // NOI18N /** Relative name of backup directory */ private static final String BACKUP_DIR = UPDATE_DIR + FILE_SEPARATOR + "backup"; // NOI18N /** Relative name of netbeans/lib directory */ private static final String NB_LIB_DIR = "lib"; // NOI18N /** Name of extension directory */ private static final String EXT_DIR = "ext"; // NOI18N /** Relative name of java/lib/ext directory */ private static final String JAVA_LIB_EXT_DIR = "lib" + FILE_SEPARATOR + EXT_DIR; // NOI18N /** The name of zip entry containing netbeans files */ public static final String UPDATE_NETBEANS_DIR = "netbeans"; // NOI18N /** The name of zip entry containing java_extension files */ public static final String UPDATE_JAVA_EXT_DIR = "java_ext"; // NOI18N /** The name of zip entry containing files for external installer */ public static final String UPDATE_MAIN_DIR = "main"; // NOI18N /** Name of external installer parameters file*/ private static final String JVM_PARAMS_FILE = "main.properties"; // NOI18N /** Extension of the distribution files */ public static final String NBM_EXTENSION = "nbm"; // NOI18N /** The name of the log file */ public static final String LOG_FILE_NAME = "update.log"; // NOI18N /** The name of the install_later file */ public static final String LATER_FILE_NAME = "install_later.xml"; // NOI18N public static final char SPACE = ' '; public static final char QUOTE = '\"'; private File downloadDirectory = null; private File backupDirectory = null; private File netbeansDirectory = null; private File nbLibDirectory = null; private File javaLibExtDirectory = null; private File updateDirectory = null; private File mainDirectory = null; /** files that are supposed to be installed (when running inside the ide) */ private Set installOnly; /** found files in various cluster/update/download folders */ private Set installFiles; private static Boolean singleMode = null; /** Should the thread stop */ private volatile boolean stop = false; private volatile boolean suspend = false; /** Total length of unpacked files */ private long totalLength; private static int instCount = 0; private static boolean fromInstall = false; /** Creates new ModuleUpdater */ public void run() { instCount = 0; getDownloadDirectory(); checkStop(); if ( downloadDirectory == null ) { endRun(); } checkStop(); installFiles = new HashSet (); Iterator it = UpdateTracking.clusters (true).iterator (); while (it.hasNext ()) { File cluster = (File)it.next (); UpdateTracking ut = UpdateTracking.getTracking (cluster); if (ut != null) { installFiles.addAll (ut.getModulesToInstall ()); } } if (installOnly != null) { // keep only those that we really wish to install installFiles.retainAll (installOnly); } if (installFiles.isEmpty ()) { endRun(); } checkStop(); totalLength(); checkStop(); unpack(); if ( !UpdaterFrame.isFromIDE() ) deleteInstall_Later(); UpdaterFrame.getUpdaterFrame().unpackingFinished(); } private void deleteInstall_Later() { File later = null; if ( isMultiuser() ) { later = new File(System.getProperty ("netbeans.user") + FILE_SEPARATOR + DOWNLOAD_DIR + FILE_SEPARATOR + LATER_FILE_NAME); if ( later.exists() ) later.delete(); } later = new File(org.netbeans.updater.UpdateTracking.getPlatformDir (), DOWNLOAD_DIR + FILE_SEPARATOR + LATER_FILE_NAME); if ( later.exists() ) later.delete(); } /** ends the run of update */ void endRun() { stop = true; } /** checks wheter ends the run of update */ private void checkStop() { if ( suspend ) while ( suspend ); if ( stop ) { if (UpdaterFrame.getUpdaterFrame().isFromIDE ()) { UpdaterFrame.getUpdaterFrame().unpackingFinished(); } else { System.exit( 0 ); } } } /** Can be used to restrict the set of NBM files that should be installed. */ public void setInstallOnly (File[] files) { installOnly = new HashSet (); for (int i = 0; i < files.length; i++) { File f = files[i]; try { f = f.getCanonicalFile (); } catch (IOException ex) { // ok, just use regular file } installOnly.add (f); } } /** Determines size of unpacked modules */ private void totalLength() { totalLength = 0L; UpdaterFrame.setLabel( Localization.getBrandedString( "CTL_PreparingUnpack" ) ); UpdaterFrame.setProgressRange( 0, installFiles.size ()); Iterator it = installFiles.iterator (); for( int i = 0; i < installFiles.size (); i++ ) { JarFile jarFile = null; try { UpdaterFrame.setProgressValue( i + 1 ); jarFile = new JarFile( (File) it.next () ); Enumeration entries = jarFile.entries(); while( entries.hasMoreElements() ) { JarEntry entry = (JarEntry) entries.nextElement(); checkStop(); if ( ( entry.getName().startsWith( UPDATE_NETBEANS_DIR ) || entry.getName().startsWith( ModuleUpdater.UPDATE_JAVA_EXT_DIR ) || entry.getName().startsWith( UPDATE_MAIN_DIR) ) && !entry.isDirectory() ) { totalLength += entry.getSize(); } } } catch ( java.io.IOException e ) { // Ignore non readable files } finally { try { if ( jarFile != null ) jarFile.close(); } catch ( java.io.IOException e ) { // We can't close the file do nothing // System.out.println( "Cant close : " + e ); // NOI18N } } } } /** Unpack the distribution files into update directory */ void unpack () { long bytesRead = 0L; boolean hasMainClass; // System.out.println("Total lengtg " + totalLength ); // NOI18N UpdaterFrame.setLabel( "" ); // NOI18N UpdaterFrame.setProgressRange( 0, totalLength ); fromInstall = true; ArrayList allTrackings = new ArrayList (); HashMap l10ns = new HashMap(); List clusters = UpdateTracking.clusters (true); Iterator clustersIterator = clusters.iterator (); while (clustersIterator.hasNext ()) { File cluster = (File)clustersIterator.next (); UpdateTracking tracking = UpdateTracking.getTracking (cluster, false); if (tracking == null) { continue; } allTrackings.add (tracking); HashSet nbms = new HashSet (tracking.getModulesToInstall ()); nbms.retainAll (installFiles); File[] nbmFiles = (File[])nbms.toArray (new File[0]); for( int i = 0; i < nbmFiles.length; i++ ) { UpdateTracking.Version version; UpdateTracking.Module modtrack; ModuleUpdate mu = new ModuleUpdate( nbmFiles[i], fromInstall ); if ( mu.isL10n() ) { modtrack = null; version = tracking.createVersion( "0" ); // NOI18N l10ns.put( mu, version ); } else { modtrack = tracking.readModuleTracking( ! fromInstall, mu.getCodenamebase(), true ); version = modtrack.addNewVersion( mu.getSpecification_version() ); } // input streams should be released, but following is needed System.gc(); hasMainClass = false; UpdaterFrame.setLabel( Localization.getBrandedString("CTL_UnpackingFile") + " " + nbmFiles[i].getName() ); //NOI18N UpdaterFrame.setProgressValue( bytesRead ); JarFile jarFile = null; try { jarFile = new JarFile( nbmFiles[i] ); Enumeration entries = jarFile.entries(); while( entries.hasMoreElements() ) { JarEntry entry = (JarEntry) entries.nextElement(); checkStop(); if ( entry.getName().startsWith( UPDATE_NETBEANS_DIR ) ) { // Copy files into netbeans directory if ( entry.isDirectory() ) { File newDir = new File( getNetbeansDirectory(), entry.getName().substring( UPDATE_NETBEANS_DIR.length() ) ); if ( !newDir.isDirectory() ) newDir.mkdirs(); File newBckDir = new File( getBackupDirectory(), entry.getName() ); if ( !newBckDir.isDirectory() ) newBckDir.mkdirs(); } else { String pathTo = entry.getName().substring( 9 ); // path without netbeans prefix if ( mu.isL10n() ) version.addL10NFileWithCrc( pathTo, Long.toString( entry.getCrc() ), mu.getSpecification_version()); else version.addFileWithCrc( pathTo, Long.toString( entry.getCrc() ) ); File destFile = new File (cluster, entry.getName ().substring (UPDATE_NETBEANS_DIR.length())); if ( destFile.exists() ) { File bckFile = new File( getBackupDirectory(), entry.getName() ); bckFile.getParentFile ().mkdirs (); // System.out.println("Backing up" ); // NOI18N copyStreams( new FileInputStream( destFile ), new FileOutputStream( bckFile ), -1 ); } else { destFile.getParentFile ().mkdirs (); } bytesRead = copyStreams( jarFile.getInputStream( entry ), new FileOutputStream( destFile ), bytesRead ); UpdaterFrame.setProgressValue( bytesRead ); } } else if ( entry.getName().startsWith( ModuleUpdater.UPDATE_JAVA_EXT_DIR ) && !entry.isDirectory() ) { // Copy files into java/lib/ext directory File destFile = new File( getJavaLibExtDirectory(), entry.getName().substring( UPDATE_JAVA_EXT_DIR.length() ) ); if ( destFile.exists() ) { File bckFile = new File( getBackupDirectory(), ModuleUpdater.UPDATE_JAVA_EXT_DIR + FILE_SEPARATOR + entry.getName().substring( UPDATE_NETBEANS_DIR.length() ) ); bckFile.getParentFile ().mkdirs (); copyStreams( new FileInputStream( destFile ), new FileOutputStream( bckFile ), -1 ); } else { destFile.getParentFile ().mkdirs (); } bytesRead = copyStreams( jarFile.getInputStream( entry ), new FileOutputStream( destFile ), bytesRead ); UpdaterFrame.setProgressValue( bytesRead ); } else if ( entry.getName().startsWith( UPDATE_MAIN_DIR )&& !entry.isDirectory() ) { // run main File destFile = new File( getMainDirectory(), entry.getName().substring(UPDATE_MAIN_DIR.length() + 1) ); destFile.getParentFile ().mkdirs (); hasMainClass = true; bytesRead = copyStreams( jarFile.getInputStream( entry ), new FileOutputStream( destFile ), bytesRead ); UpdaterFrame.setProgressValue( bytesRead ); } } if ( hasMainClass ) { MainConfig mconfig = new MainConfig(getMainDirString() + FILE_SEPARATOR + JVM_PARAMS_FILE); if (mconfig.isValid()) { String java_path = System.getProperty ("java.home") + FILE_SEPARATOR + "bin" + FILE_SEPARATOR + "java"; // NOI18N java_path = quoteString( java_path ); String torun = java_path + " -cp " + quoteString( getMainDirString() + mconfig.getClasspath() ) + mconfig.getCommand(); // NOI18N startCommand(torun); deleteDir( getMainDirectory() ); } } } catch ( java.io.IOException e ) { // Ignore non readable files e.printStackTrace (); } finally { try { if ( jarFile != null ) jarFile.close(); } catch ( java.io.IOException e ) { // We can't close the file do nothing // System.out.println("Can't close : " + e ); // NOI18N } //System.out.println("Dleting :" + nbmFiles[i].getName() + ":" + nbmFiles[i].delete() ); // NOI18N nbmFiles[i].delete(); } if ( ! mu.isL10n() ) modtrack.write(); modtrack.writeConfigModuleXMLIfMissing (); } } Iterator trakingsIter = allTrackings.iterator (); while (trakingsIter.hasNext ()) { UpdateTracking t = (UpdateTracking)trakingsIter.next (); // update_tracking of l10n's Iterator it = l10ns.entrySet().iterator(); while ( it.hasNext() ) { Map.Entry entry = (Map.Entry) it.next(); ModuleUpdate mod = (ModuleUpdate) entry.getKey(); UpdateTracking.Version version = (UpdateTracking.Version) entry.getValue(); UpdateTracking.Module modtrack = t.readModuleTracking( ! mod.isFromInstall(), mod.getCodenamebase(), true ); modtrack.addL10NVersion( version ); modtrack.write(); } t.deleteUnusedFiles (); } } /** The directory where to download the distribution files of modules */ public File getUpdateDirectory() { if ( updateDirectory == null ) { if ( isMultiuser() ) updateDirectory = new File (System.getProperty ("netbeans.user") + FILE_SEPARATOR + UPDATE_DIR ); else updateDirectory = new File (org.netbeans.updater.UpdateTracking.getPlatformDir (), UPDATE_DIR ); if ( !updateDirectory.isDirectory() ) updateDirectory.mkdirs(); } return updateDirectory; } /** The directory where to download the distribution files of modules */ private File getInstallDownloadDirectory() { File idir = new File (org.netbeans.updater.UpdateTracking.getPlatformDir(), DOWNLOAD_DIR ); if ( !idir.isDirectory() ) idir.mkdirs(); return idir; } /** The directory where to download the distribution files of modules */ private File getDownloadDirectory() { if ( downloadDirectory == null ) { downloadDirectory = new File (System.getProperty ("netbeans.user") + FILE_SEPARATOR + DOWNLOAD_DIR ); /* if ( !downloadDirectory.isDirectory() ) downloadDirectory.mkdirs(); */ } return downloadDirectory; } private void startCommand(String torun) { Runtime runtime=Runtime.getRuntime(); Process proces; try { proces=runtime.exec(parseParameters( torun )); final Process proc2 = proces; new Thread() { public void run() { try { InputStreamReader stream= new InputStreamReader (proc2.getErrorStream()); BufferedReader reader= new BufferedReader(stream); String vystup; do { vystup = reader.readLine(); if (vystup!=null) System.out.println(vystup); } while (vystup != null); } catch (Exception e) { e.printStackTrace(); } } }.start(); int x=proces.waitFor(); } catch (Exception e){ e.printStackTrace(); } } /** The directory where to backup old versions of modules */ public File getBackupDirectory() { if ( backupDirectory == null ) { if ( isMultiuser() ) backupDirectory = new File (System.getProperty ("netbeans.user") + FILE_SEPARATOR + BACKUP_DIR ); else backupDirectory = new File (org.netbeans.updater.UpdateTracking.getPlatformDir (), BACKUP_DIR ); if ( !backupDirectory.isDirectory() ) backupDirectory.mkdirs(); } return backupDirectory; } /** Gets the netbeans directory */ public File getNetbeansDirectory() { if ( netbeansDirectory == null ) { if ( isMultiuser() ) netbeansDirectory = new File (System.getProperty ("netbeans.user") ); else netbeansDirectory = org.netbeans.updater.UpdateTracking.getPlatformDir (); } return netbeansDirectory; } /** Gets the netbeans directory */ private File getMainDirectory() { if ( mainDirectory == null ) { if ( isMultiuser() ) mainDirectory = new File (System.getProperty ("netbeans.user") + FILE_SEPARATOR + UPDATE_DIR + FILE_SEPARATOR + UPDATE_MAIN_DIR ); else mainDirectory = new File (org.netbeans.updater.UpdateTracking.getPlatformDir (), FILE_SEPARATOR + UPDATE_DIR + FILE_SEPARATOR + UPDATE_MAIN_DIR ); } return mainDirectory; } private String getMainDirString() { return getMainDirectory().getPath(); } /** Quotes string correctly, eg. removes all quotes from the string and adds * just one at the start and * second one at the end. * @param s string to be quoted * @return correctly quoted string */ public static final String quoteString(String s) { if ( s.indexOf( SPACE ) > -1 ) { StringBuffer sb = new StringBuffer(s); int i = 0; while ( i < sb.length() ) { if ( sb.charAt(i) == QUOTE ) sb.deleteCharAt( i ); else i++; } sb.insert( 0, QUOTE ); sb.append( QUOTE ); return sb.toString(); } return s; } /** The directory of libraries that are added to CLASSPATH on startup */ public File getNbLibDirectory() { if ( nbLibDirectory == null ) { if ( isMultiuser() ) nbLibDirectory = new File (System.getProperty ("netbeans.user") + FILE_SEPARATOR + NB_LIB_DIR ); else nbLibDirectory = new File (org.netbeans.updater.UpdateTracking.getPlatformDir (), NB_LIB_DIR ); } File nbLibExt = new File( nbLibDirectory, EXT_DIR ); if ( !nbLibExt.isDirectory() ) nbLibExt.mkdirs(); return nbLibDirectory; } /** The directory lib/ext directory of JDK */ public File getJavaLibExtDirectory() { if ( javaLibExtDirectory == null ) { javaLibExtDirectory = new File (System.getProperty ("java.home") + FILE_SEPARATOR + JAVA_LIB_EXT_DIR ); } if ( canWrite( javaLibExtDirectory, true ) ) return javaLibExtDirectory; else return getNbLibDirectory(); } private static boolean isMultiuser() { if ( fromInstall ) return false; return ! singleMode(); } private static boolean singleMode() { if ( singleMode == null ) { singleMode = Boolean.FALSE; if ( System.getProperty ("netbeans.user") == null ) singleMode = Boolean.TRUE; else { File userDir = new File (System.getProperty ("netbeans.user")); File instDir = org.netbeans.updater.UpdateTracking.getPlatformDir (); if ( userDir.equals( instDir ) ) singleMode = Boolean.TRUE; else { try{ if ( userDir.getCanonicalPath().equals( instDir.getCanonicalPath()) ) singleMode = Boolean.TRUE; } catch ( IOException ioe ) { } } } } return singleMode.booleanValue(); } /** * It takes the current progress value so it can update progress * properly, and also return the new progress value after the * copy is done. * * @param progressVal The current progress bar value. If this is * negative, we don't want to update the progress bar. */ private long copyStreams( InputStream src, OutputStream dest, long progressVal ) throws java.io.IOException { BufferedInputStream bsrc = new BufferedInputStream( src ); BufferedOutputStream bdest = new BufferedOutputStream( dest ); int count = 0; int c; try { while( ( c = bsrc.read() ) != -1 ) { bdest.write( c ); count++; if ( count > 8500 ) { if (progressVal >= 0) { progressVal += count; UpdaterFrame.setProgressValue( progressVal ); } count = 0; checkStop(); } } // Just update the value, no need to update the // GUI yet. Caller can do that. if (progressVal >= 0) { progressVal += count; } } finally { bsrc.close(); bdest.close(); } return progressVal; } /** Test whether the user has rights to write into directory */ private static boolean canWrite( File dir, boolean create ) { if ( !dir.exists() && create ) dir.mkdirs(); if ( !dir.isDirectory() || !dir.canWrite() ) return false; File tmp = null; try { tmp = File.createTempFile( "test", "access", dir ); // NOI18N } catch ( java.io.IOException e ) { return false; } if ( tmp == null ) return false; boolean cw = tmp.canWrite(); if (cw) tmp.delete(); return cw; } private void deleteDir(File dir) { File[] files=dir.listFiles(); for( int j = 0; j < files.length; j++ ) { if ( files[j].isDirectory() ) deleteDir( files[j] ); files[j].delete(); } } private String getLogPath() { return getUpdateDirectory().getPath() + FILE_SEPARATOR + LOG_FILE_NAME; } /** [Copied from org.openide.util.Utilities] * Parses parameters from a given string in shell-like manner. * Users of the Bourne shell (e.g. on Unix) will already be familiar * with the behavior. * For example, when using {@link org.openide.execution.NbProcessDescriptor} * you should be able to: *
|
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.