|
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.