src.utilities.AS400ToolboxInstaller Maven / Gradle / Ivy
Show all versions of jt400-jdk8 Show documentation
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: AS400ToolboxInstaller.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 1997-2004 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package utilities;
import java.util.Vector;
import java.util.StringTokenizer;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.ResourceBundle;
import java.io.InputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.MalformedURLException;
/**
* Provides a utility to
* install, update, compare, and uninstall the IBM Toolbox for Java
* packages. Note that this class writes to the local file system,
* so it may fail if used in an applet.
*
* The AS400ToolboxInstaller class can be included in the user's program,
* or it can be run as a command line program, as follows:
*
*
* java utilities.AS400ToolboxInstaller [ options ]
*
*
*
*
* Options
*
*
* -install
* - Indicates that the specified packages are to be installed.
* If the -package option is not specified, all packages will be installed.
* The source and target options must be specified when using this option.
* The -install option may be abbreviated to -i.
*
*
-uninstall
* - Indicates that the specified packages are to be removed.
* The package and target options must be specified when using this option.
* The -uninstall option may be abbreviated to -u.
*
*
-compare
* - Indicates that the source package with be compared with the
* target package to determine if
* an update is needed. The package, source, and target options must
* be specified when using this option.
* The -compare option may be abbreviated to -c.
*
*
*
-package
package1[,package2[, ...]]
* - Specifies the package to install, compare, or uninstall.
* If -package is specified, at
* least one package name must be specified.
* The -package option may be abbreviated to -p.
*
*
*
-source
sourceURL
* - Specifies the location of the source files. The HTTP server is used
* to access the files. The system name or the fully-qualified URL
* may be specified. If the system name is specified, it will automatically
* be converted to the URL where the licensed program installed the files.
* For example, if mySystem is specified, http://mySystem/QIBM/ProdData/HTTP/Public/jt400/
* will be used.
* The -source option may be abbreviated to -s.
*
*
-target
targetDirectory
* - Specifies the fully-qualified path name of where to store the files.
* The -target option may be abbreviated to -t.
*
*
-prompt
* - Specifies that the user will be prompted before updating the packages on
* the workstation. If not specified, the packages will be updated.
* The -prompt option may be abbreviated to -pr.
*
*
-?
* - Displays the help text.
*
*
-help
* - Displays the help text.
* The -help parameter may be abbreviated to -h.
*
*
*
* Install Example
* The following example will install all packages.
*
*
* java AS400ToolboxInstaller -install
* -source http://myAS400/QIBM/ProdData/HTTP/Public/jt400/
* -target c:\java\
*
*
*
* The following examples will install the access package.
*
*
* java AS400ToolboxInstaller -install -package ACCESS
* -source http://myAS400/QIBM/ProdData/HTTP/Public/jt400/
* -target c:\java\
*
* java AS400ToolboxInstaller -install -package ACCESS
* -source mySystem
* -target c:\java\
*
* java AS400ToolboxInstaller -i -p ACCESS
* -s mySystem
* -t c:\java\
*
*
*
* Uninstall Example
* This example will remove the access package.
*
*
* java AS400ToolboxInstaller -uninstall -package ACCESS -target c:\java\
*
*
*
*
*
* Compare Example
* This example will compare the current level of the OPNAV package.
*
*
* java AS400ToolboxInstaller -compare
* -package OPNAV
* -source http://myAS400/QIBM/ProdData/HTTP/Public/jt400/
* -target c:\java\
*
*
*
* Help Example
* The following will display help information:
*
* java AS400ToolboxInstaller -?
* java AS400ToolboxInstaller -help
* java AS400ToolboxInstaller -h
*
*
* @deprecated This class is no longer being enhanced, since it has no known users.
**/
public class AS400ToolboxInstaller
{
private static final int INSTALL = 0; // when installing @A2a
private static final int UNINSTALL = 1; // when uninstalling @A2a
private static final int COMPARE = 2; // when comparing @A2a
private static boolean isPrompt_ =false; // indicate if -pr is specified @A2a
// Changes required to the classpath as a result of the latest
// install operation.
private static Vector classpathAdditions_ = new Vector();
private static Vector classpathRemovals_ = new Vector();
private static Vector unexpandedFiles_ = new Vector();
// Return values for classpathContains method.
private static final int NOT_IN_CLASSPATH=0;
private static final int IN_CLASSPATH=1;
private static final int UNKNOWN_CLASSPATH=2; // could not examine classpath
// $D1a constants for the difference between the code on the server
// and the code on the client
private static final int NO_CHANGE = 0;
private static final int SERVER_HAS_NEW_PTF = 1;
private static final int SERVER_HAS_NEW_RELEASE = 2;
// Byte array used to store data read from files. Size is arbitrary.
private static byte[] data_ = new byte[2560];
// Where MRI comes from.
private static ResourceBundle resources_;
// Control files use a forward slash for a path separator. This flag
// says whether the slash has to be changed to a backward slash when
// writing to the local file system.
private static boolean changeSlash_ = !File.separator.equals("/");
// To prevent instantiation. All methods in this class are static.
private AS400ToolboxInstaller()
{}
/**
Adds a trailing separator to the path if it does not already have one.
If the path is blank,
a separator is not added, since that would change the meaning of the
path to be the root directory rather than the curent directory.
@param path The path to which to add a separator.
@return The path with a trailing separator.
**/
private static String addTrailingSeparator(String path)
{
if (path.length() > 0 &&
path.substring(path.length()-1).equals(File.separator));
else if (path.length() > 0)
path = path + File.separator;
return path;
}
/**
Checks to see if path is in the CLASSPATH. If the CLASSPATH
is not accessible, UNKNOWN_CLASSPATH will be returned. This method
is not case-sensitive.
@param path The path for which to check the CLASSPATH.
@return NOT_IN_CLASSPATH if path is not in the CLASSPATH,
IN_CLASSPATH if path is in the CLASSPATH,
UNKNOWN_CLASSPATH if the CLASSPATH cannot be accessed.
**/
private static int classpathContains(String path)
{
try
{
// Search with leading and trailing semicolons to make sure
// paths match exactly. Uppercase to make our check case-
// insensitive.
String separator = System.getProperty("path.separator");
String classpath = separator +
System.getProperty("java.class.path") +
separator;
classpath = classpath.toUpperCase();
path = path.toUpperCase();
if (classpath.lastIndexOf(separator + path + separator) != -1)
return IN_CLASSPATH;
else
return NOT_IN_CLASSPATH;
}
catch(Exception e)
{
return UNKNOWN_CLASSPATH;
}
}
// @D1a The following routine (comparePackageFiles) is new.
/**
Determines if an update is needed.
@param sourceControlFile File that contains VRM info from the server
@param targetControlFile File that contains VRM info on the client.
@return updateNeeded Int that indicates if the files are the same,
the server has a new PTF, or the server has
a new release.
This routine compares the first line of the control files. VRM
information must be the first line of the file and must be in VnRnMnxx
format. If VRM information is not in the first line, the original
check is used. That check assumes the only difference between the
source and target is PTF level. This means if the source is larger
than the target, the source has a new PTF.
An example of the control file is on a system with two PTFs:
V3R2M0
V3R2M01
V3R2M02
**/
private static int comparePackageFiles(String serverFile, String clientFile)
{
int result = NO_CHANGE;
boolean useOriginalCheck = true;
try
{
StringTokenizer parseServerFile = new StringTokenizer(serverFile, "\n\r");
StringTokenizer parseClientFile = new StringTokenizer(clientFile, "\n\r");
// get the first line out of each file
String ServerVRM = parseServerFile.nextToken().toUpperCase();
String ClientVRM = parseClientFile.nextToken().toUpperCase();
// If the first line looks like a VRM string then check the contents
// of the strings.
if ((ServerVRM.charAt(0) == 'V') && (ClientVRM.charAt(0) == 'V') &&
(ServerVRM.charAt(2) == 'R') && (ClientVRM.charAt(2) == 'R') &&
(ServerVRM.charAt(4) == 'M') && (ClientVRM.charAt(4) == 'M'))
{
// If the server has a newer version indicate an update is needed
if (ServerVRM.charAt(1) > ClientVRM.charAt(1))
{
result = SERVER_HAS_NEW_RELEASE;
useOriginalCheck = false;
}
// if the client has a newer version then return saying no
// updated needed.
else if (ServerVRM.charAt(1) < ClientVRM.charAt(1))
{
useOriginalCheck = false;
}
// else the version is the same ...
else
{
// if the server has a newer release indicate an update is needed
if (ServerVRM.charAt(3) > ClientVRM.charAt(3))
{
result = SERVER_HAS_NEW_RELEASE;
useOriginalCheck = false;
}
// if the client has a newer release then return saying no
// update is needed.
else if (ServerVRM.charAt(3) < ClientVRM.charAt(3))
{
useOriginalCheck = false;
}
// else the releases are the same, now check the mod levels
else
{
// if the server has a newer mod level then return indicating
// an updated is needed.
if (ServerVRM.charAt(5) > ClientVRM.charAt(5))
{
result = SERVER_HAS_NEW_RELEASE;
useOriginalCheck = false;
}
// if the client has a newer mod level then return
// saying no update is needed.
else if (ServerVRM.charAt(5) < ClientVRM.charAt(5))
{
useOriginalCheck = false;
}
// note there is no else. This is the case where
// the Version, Release and first digit of the mods are
// the same. We will use the old check to see if a
// PTF is needed.
}
}
}
}
catch (Exception e) {}
// else we cannot find VRM info in the server and/or client
// file. Use the original check -- determine if an update is
// needed by comparing the lengths of the package files. If
// the server's file is larger assume a PTF has been applied
// to the server.
if (useOriginalCheck)
{
if (serverFile.length() > clientFile.length())
result = SERVER_HAS_NEW_PTF;
}
return result;
}
/**
Copies the file pointed to by sourceURL to targetFile.
If the target file exists, it will be replaced, not appended.
@param targetFile The file (on the local system) in which to write the data.
@param sourceURL The location of file to copy.
@exception IOException If an error occurs while communicating to the server.
**/
private static void copyFile(String targetFile, URL sourceURL)
throws IOException
{
InputStream in = sourceURL.openStream();
// Make sure the target directory exists.
if ((new File(targetFile)).getParent() != null)
{
File dir = new File((new File(targetFile)).getParent());
if (!dir.exists())
{
if (!dir.mkdirs() && !dir.isDirectory()) // @D8C
{
throw new IOException("CANNOT_CREATE_DIRECTORY");
}
}
}
FileOutputStream out = new FileOutputStream(targetFile);
int n = in.read(data_);
while (n != -1)
{
out.write(data_, 0, n);
n = in.read(data_);
}
in.close();
out.close();
}
/**
Returns the names of all the IBM Toolbox for Java packages.
@param source The directory in which the Toolbox exists.
@return The vector of Strings which contain the names of all the
packages in the IBM Toolbox for Java.
@exception IOException If the package list file cannot be found.
**/
private static Vector getAllPackageNames(String source)
throws IOException
{
// Get contents of source package list
String packageList = readFile(new FileInputStream(source + "JT400.PKG"));
// Loop through each of the packages in the package list.
StringTokenizer packages = new StringTokenizer(packageList);
Vector list = new Vector();
while (packages.hasMoreTokens())
{
list.addElement(packages.nextToken());
}
return list;
}
/**
Returns the names of all the IBM Toolbox for Java packages installed
on the source.
@param source The location of the Toolbox.
@return The vector of Strings which contain the names of all the
packages in the IBM Toolbox for Java.
@exception IOException If the package list file cannot be found.
**/
private static Vector getAllPackageNames(URL source)
throws IOException
{
// Get contents of source package list
String packageList = readFile(
new URL(source.toExternalForm() + "JT400.PKG"));
// Loop through each of the packages in the package list.
StringTokenizer packages = new StringTokenizer(packageList);
Vector list = new Vector();
while (packages.hasMoreTokens())
{
list.addElement(packages.nextToken());
}
return list;
}
/**
Returns the set of paths that should be added to the CLASSPATH as a
result of the latest install or uninstall operation. The returned
vector will always be empty after an uninstall.
@return The vector of Strings which contain the paths that should be
added to the CLASSPATH
as a result of the latest install or uninstall operation.
**/
public static Vector getClasspathAdditions()
{
return classpathAdditions_;
}
/**
Returns the set of paths that should be removed from the CLASSPATH as a
result of the latest install or uninstall operation.
Note:
Removing directories from the classpath may cause Java programs
to fail if the directory contains code required by the Java program.
Extraneous directories in the CLASSPATH
do no harm. Therefore, you may not wish to remove any CLASSPATH
entries, or remove only directories which do not contain any Java
code.
@return The vector of Strings which contain the paths that should be
removed from the CLASSPATH
as a result of the latest install or uninstall operation.
**/
public static Vector getClasspathRemovals()
{
return classpathRemovals_;
}
/**
Loads the resource bundle if not already done.
@return The resource bundle for this class.
**/
private static ResourceBundle getMRIResource()
{
// Initialize resource bundle if not already done.
if (resources_ == null)
resources_ = ResourceBundle.getBundle("utilities.INMRI");
return resources_;
}
/**
Returns the set of files that should be expanded as a
result of the latest install or uninstall operation.
Note that not all *.zip files will be in this list. Only those files
designated to be expanded by the package will be included. The returned
vector will always be empty after an uninstall.
@return The vector of Strings which contain the files that should be
expanded as a result of the latest install or uninstall operation.
**/
public static Vector getUnexpandedFiles()
{
return unexpandedFiles_;
}
/**
Installs/updates an IBM Toolbox for Java package.
If the package is already installed,
it will be updated if needed. This method just copies files, it will
not modify the CLASSPATH, or expand any 'zipped' files.
URL sourceURL = new URL("http://myAS400/QIBM/ProdData/HTTP/Public/jt400/");
AS400ToolboxInstaller.install("ACCESS", "C:\\java\\", sourceURL);
@param packageName The package which to install.
"*ALL" can be used to install all the IBM
Toolbox for Java packages.
@param targetPath The path in which to install. The directory will be
created if it does not exist.
@param source The URL which contains the location which contains the
current package. File names will be appended
to this location, so a trailing path separator
is required.
@return true if an install/update occurred, false if no updates were
needed.
@exception IOException If an error occurs while communicating with the system.
**/
public static boolean install(String packageName,
String targetPath,
URL source)
throws IOException
{
// Verify parms
if (packageName == null)
throw new NullPointerException("packageName");
if (targetPath == null)
throw new NullPointerException("targetPath");
if (source == null)
throw new NullPointerException("source");
// If *ALL passed for the package, get list of packages
// and call self with 'real' package names.
if (packageName.equalsIgnoreCase("*ALL")) //@D5C
{
Vector packageList = getAllPackageNames(source);
boolean results = false;
Vector cpa = new Vector();
Vector cpr = new Vector();
Vector uf = new Vector();
int size = packageList.size();
for (int i=0; i 1)
{
File parent = new File(targetPath.substring(0, targetPath.length()-1));
if (!parent.exists() || !parent.isDirectory())
{
if (!parent.mkdirs() && !parent.isDirectory()) // @D8C
{
throw new IOException("(" + parent.toString() + ") " +
getMRIResource().getString("EXC_CANNOT_CREATE_DIRECTORY"));
}
}
}
}
// @D1c See if an update is needed.
int updateType = comparePackageFiles(sourcePackageFile, targetPackageFile);
// return false if no update is needed.
if (updateType == NO_CHANGE)
return false;
// End of code that is a copy (almost) of code in isUpdateNeeded().
StringTokenizer sourceUpdates = new StringTokenizer(sourcePackageFile);
StringTokenizer targetUpdates = new StringTokenizer(targetPackageFile);
// @D1a Adjust the files only if a new PTF is on the server. We need
// the entire file if the server has a new release.
if (updateType == SERVER_HAS_NEW_PTF)
{
// Loop through each of the updates in the source package file.
// Throw away any updates that have a corresponding line in the
// target package file. The package files contain a line for
// each update. We depend on the package files being
// left alone by the user. If this is true then the only
// lines in the package files are the list of updates. The top
// section of the source and target file should match. By
// deleting lines, when the target file is emply all that remains
// in the source file is the set of updates to make.
while (targetUpdates.hasMoreTokens())
{
sourceUpdates.nextToken();
targetUpdates.nextToken();
}
}
// Process updates which have not been applied to the target.
// This combines all the updates that have not been applied to
// the target into one set of updates in order to minimize the
// amount of downloads from the remote source system.
String updateFile, update, prevUpdate, fileName, oldAction, newAction;
StringBuffer updateFileURL, workStr;
StringTokenizer updates;
Hashtable finalUpdates = new Hashtable();
Hashtable classpathUpdates = new Hashtable();
while (sourceUpdates.hasMoreTokens())
{
// Read contents of source update file
updateFileURL = new StringBuffer(source.toExternalForm());
updateFileURL.append(sourceUpdates.nextToken());
updateFileURL.append(".LST");
updateFile = readFile(new URL(updateFileURL.toString()));
// Loop through lines in update file, determining
// files that need updating.
// The format of the update file is as follows:
// Column Description
// ------ ----------------
// 1-8 Package affected
// 9 Reserved //@D4A
// 10-13 ADD, UPD, RMV, PADD, or PRMV
// 14 Reserved //@D4A
// 15 Expand file? Y or N
// 16 Classpath affected? Y or N
// 17-19 Reserved //@D4A
// 20-end File name, with possible subdirectory
updates = new StringTokenizer(updateFile, "\n\r");
while (updates.hasMoreTokens())
{
update = updates.nextToken();
// Determine if this line affects our package.
String str = update.substring(0,8).trim();
if (str.equalsIgnoreCase(packageName)) //@D5C
{
newAction = update.substring(9, 13);
if (update.length() > 19) //@D4A
{ //@D4A
// get file name
fileName = update.substring(19);
} else //@D4A
fileName = ""; //@D4A
// if we are dealing with a class path action...
if (newAction.equalsIgnoreCase("PADD") || newAction.equalsIgnoreCase("PRMV")) //@D5C
{
// We don't need to check the hashtable to check
// if the classpath is already contained in it
// since we always want the latest action to
// be the action that we take.
// This will set the action as follows:
// Old action New action Final action
// PADD PADD PADD
// PADD PRMV PRMV
// PRMV PADD PADD
// PRMV PRMV PRMV
if (fileName.length() > 0) //@D4A
{ //@D4A
// add to set of classpath updates
classpathUpdates.put(fileName, update);
} //@D4A
}
// else we are dealing with a file action
else
{
// Determine if this file is already in the set of updates.
prevUpdate = (String)finalUpdates.get(fileName);
if (prevUpdate != null)
{
// Determine if we want to change the action.
// This set of code will set the action as follows:
// Old action New action Final action
// ADD ADD ADD
// ADD RMV RMV
// ADD UPD ADD
// RMV ADD UPD
// RMV RMV RMV
// RMV UPD UPD
// UPD ADD UPD
// UPD RMV RMV
// UPD UPD UPD
oldAction = prevUpdate.substring(9, 13);
// if new action is RMV, change to RMV
if (newAction.equalsIgnoreCase("RMV ")) //@D5C
{
finalUpdates.put(fileName, update);
}
// if old action is ADD, leave as is
else if (oldAction.equalsIgnoreCase("ADD ")) //@D5C
{}
// if new action is ADD...
else if (newAction.equalsIgnoreCase("ADD ")) //@D5C
{
// change action to update
workStr = new StringBuffer(update);
workStr.setCharAt(9, 'U');
workStr.setCharAt(10, 'P');
workStr.setCharAt(11, 'D');
workStr.setCharAt(12, ' ');
finalUpdates.put(fileName, workStr.toString());
}
// otherwise take the new action
else
{
finalUpdates.put(fileName, update);
}
}
else
{
// add file to set of updates
finalUpdates.put(fileName, update);
}
}
}
}
}
// Copy the package list control file to the target.
// Do this first, so an uninstall(*ALL) can be done if the install
// bombs midstream.
copyFile(targetPath.toString() + "JT400.PKG",
new URL(source.toExternalForm() + "JT400.PKG"));
// Copy the package file list control file to the target.
// Do this first, so an uninstall can be done if the install bombs
// midstream.
copyFile(targetPath.toString() + packageName + ".LST",
new URL(source.toExternalForm() + packageName + ".LST"));
// Make needed updates to the files on the target.
String temp;
for (Enumeration e = finalUpdates.elements(); e.hasMoreElements();)
{
update = (String)e.nextElement();
fileName = update.substring(19);
// remove the file if action is RMV
String urlFile = fileName; // save filename with forward slashes
if (changeSlash_) // change slashes if needed
fileName = fileName.replace('/', '\\');
if (update.substring(9, 13).equalsIgnoreCase("RMV ")) //@D5C
{
try
{
File file = new File(targetPath.toString() + fileName);
file.delete();
}
catch(Exception ex) {} // don't worry if can't delete file
// Note that the expand flag is ignored for the RMV action.
// Check if classpath should be updated.
if (update.charAt(15) == 'Y') // remove file from CP
{
// See if it is contained in the classpath
temp = targetPath.toString() + fileName;
temp = (new File(temp)).getAbsolutePath();
if (classpathContains(temp)!=NOT_IN_CLASSPATH)
classpathRemovals_.addElement(temp);
}
}
else
if ((update.substring(9, 13).equalsIgnoreCase("ADD ")) //@D5A
|| (update.substring(9, 13).equalsIgnoreCase("UPD ")) //@D5A
|| (update.substring(9, 13).equalsIgnoreCase("OADD"))) //@D5A
{
// copy the file
boolean miaFile = false;
try
{
copyFile(targetPath.toString() + fileName,
new URL(source.toExternalForm() + urlFile));
}
catch (IOException ex)
{ // assume error is file not found, which is OK if
// this is a .properties or an optional (OADD) file //@D5C
if ((update.substring(9, 13).equalsIgnoreCase("OADD")) //@D5A
|| ((fileName.length() > 11
&& fileName.substring(fileName.length() - 11).equalsIgnoreCase(".properties")))) //@D5C
{
miaFile = true; // mark file as missing so not added to Vectors
} else // otherwise this is a problem, rethrow the error
{
throw ex;
}
}
// Only add file to unexpanded vector if it existed.
if (!miaFile)
{
// Check if file needs to be expanded.
if (update.charAt(14) == 'Y')
{
temp = targetPath.toString() + fileName;
temp = (new File(temp)).getAbsolutePath();
unexpandedFiles_.addElement(temp);
}
// For ADDs, check if classpath should be updated.
if ((update.substring(9, 13).equalsIgnoreCase("ADD ")) || //@D5C
(update.substring(9, 13).equalsIgnoreCase("OADD"))) //@D7a
{
if (update.charAt(15) == 'Y') // add file to CP
{
// See if it is contained in the classpath
temp = targetPath.toString() + fileName;
temp = (new File(temp)).getAbsolutePath();
if (classpathContains(temp)!=IN_CLASSPATH)
classpathAdditions_.addElement(temp);
}
}
}
} else
{
// we don't recognize this tag.
}
}
// Make needed updates to the classpath arrays.
for (Enumeration e = classpathUpdates.elements(); e.hasMoreElements();)
{
update = (String)e.nextElement();
if (update.length() > 19) //@D4A
{ //@D4A
// get file name
fileName = update.substring(19);
} else //@D4A
fileName = ""; //@D4A
fileName = update.substring(19).trim();
if (changeSlash_) // change slashes if needed
fileName = fileName.replace('/', '\\');
// get full path name
if (fileName.length() > 0)
{
temp = targetPath.toString() + fileName;
temp = (new File(temp)).getAbsolutePath();
} else // no path, need to add target directory to classpath
{
if (targetPath.length() > 1)
{
temp = targetPath.substring(0,targetPath.length()-1);
} else
{
temp = "";
}
temp = (new File(temp)).getAbsolutePath();
}
// If this is a classpath addition
if (update.substring(9, 13).equalsIgnoreCase("PADD")) //@D5C
{
// See if it is contained in the classpath
if (classpathContains(temp)!=IN_CLASSPATH)
classpathAdditions_.addElement(temp);
}
// else is a classpath removal
else
{
// See if it is contained in the classpath
if (classpathContains(temp)!=NOT_IN_CLASSPATH)
classpathRemovals_.addElement(temp);
}
}
// Copy the source package file to the target.
// Do this last, after all other updates have been successful,
// so if there is an error midstream, another update can be
// attempted.
FileOutputStream out = new FileOutputStream(
targetPackageFileName.toString() );
int numBytes;
int position = 0;
/* while (position < sourcePackageFile.length())
{
numBytes =
(data_.length < sourcePackageFile.length() - position ?
data_.length :
sourcePackageFile.length() - position);
sourcePackageFile.getBytes(position, position+numBytes, data_, 0);
out.write(data_, 0, numBytes);
position += numBytes;
}
replaced with following 2 lines */
byte[] data = sourcePackageFile.getBytes();
out.write(data, 0, data.length);
out.close();
return true;
}
/**
Indicates if the package is installed. Installation is determined
by examining the target directory for the *.LVL file. This method
does not check for a partial installation, if installation is
incomplete, this method may return true or false.
AS400ToolboxInstaller.isInstalled("ACCESS", "C:\\java\\");
@param packageName The package which will be checked.
Note that *ALL is not supported.
@param targetPath The path in which the package is installed.
@return true if the package has been installed, false if the
package has not been installed.
**/
public static boolean isInstalled(String packageName,
String targetPath)
{
// Verify parms
if (packageName == null)
throw new NullPointerException("packageName");
if (targetPath == null)
throw new NullPointerException("targetPath");
// Make sure the target path has a trailing separator.
targetPath = addTrailingSeparator(targetPath);
// Look for the .LVL file in the target directory.
// If it is there, return true, if not, return false.
StringBuffer filename = new StringBuffer(targetPath);
filename.append(packageName);
filename.append(".LVL");
File file = new File(filename.toString());
if (file.exists())
return true;
return false;
}
/**
Returns whether the package is downlevel. This method will return
true if the package is not installed.
URL sourceURL = new URL("http://myAS400/QIBM/ProdData/HTTP/Public/jt400/");
AS400ToolboxInstaller.isUpdateNeeded("ACCESS", "C:\\java\\", sourceURL);
@param packageName The package which will be checked.
"*ALL" can be used to check all the IBM
Toolbox for Java packages.
@param targetPath The path in which the package is installed.
@param source The URL which contains the location which contains the
current package. File names will be appended
to this location, so a trailing path separator
is required.
@return true if an update is needed, false if no updates are
needed.
@exception IOException If an error occurs while communicating with the system.
**/
public static boolean isUpdateNeeded(String packageName,
String targetPath,
URL source)
throws IOException
{
// Verify parms
if (packageName == null)
throw new NullPointerException("packageName");
if (targetPath == null)
throw new NullPointerException("targetPath");
if (source == null)
throw new NullPointerException("source");
// If *ALL passed for the package, get list of packages
// and call self with 'real' package names.
if (packageName.equalsIgnoreCase("*ALL")) //@D5C
{
Vector packageList = getAllPackageNames(source);
int size = packageList.size();
for (int i=0; i= 0)
{
StringBuffer buffer = new StringBuffer();
buffer.append(result.substring(0, j));
buffer.append(value);
buffer.append(result.substring(j + variable.length ()));
result = buffer.toString ();
}
return result;
}
/**
Returns the contents of the file.
@param file The file to read.
@return The contents of the file
@exception IOException If an error occurs while communicating with the server.
**/
private static String readFile(FileInputStream file)
throws IOException
{
StringBuffer s = new StringBuffer();
int n = file.read(data_);
while (n != -1)
{
s.append(new String(data_, 0, n));
n = file.read(data_);
}
file.close();
return s.toString();
}
/**
Returns the contents of the file located at the URL url.
@param url The URL of the file to read.
@return The contents of the file
@exception IOException If an error occurs while communicating with the server.
**/
private static String readFile(URL url)
throws IOException
{
InputStream in = url.openStream();
StringBuffer s = new StringBuffer();
int n = in.read(data_);
while ( n!= -1)
{
s.append(new String(data_, 0, n));
n = in.read(data_);
}
in.close();
return s.toString();
}
/**
Removes a package from the target. This method deletes all the files
in the package, and deletes directories if they are empty.
It does not modify the CLASSPATH.
AS400ToolboxInstaller.unInstall("ACCESS", "C:\\java\\");
@param packageName The package to remove.
"*ALL" can be used to remove all the IBM
Toolbox for Java packages.
@param targetPath The path from which to remove the package.
@return The vector of Strings which contain the names (including path) of
files and directories which exist but could not be deleted.
@exception IOException If the package is not installed.
**/
// Note that if packages are removed individually, the JT400.PKG file
// will never be deleted from the client. This file is only deleted
// when *ALL is specified for the package name.
public static Vector unInstall(String packageName,
String targetPath)
throws IOException
{
// Verify parms
if (packageName == null)
throw new NullPointerException("packageName");
if (targetPath == null)
throw new NullPointerException("targetPath");
// Make sure the target path has a trailing separator.
targetPath = addTrailingSeparator(targetPath);
// If *ALL passed for the package, get list of packages
// and call self with 'real' package names.
if (packageName.equalsIgnoreCase("*ALL")) //@D5C
{
Vector packageList;
try {
packageList = getAllPackageNames(targetPath);
}
catch (FileNotFoundException e)
{
throw new IOException(
getMRIResource().getString("EXC_NO_PACKAGES_INSTALLED"));
}
boolean packageFound = false; // was any package installed
Vector results = new Vector();
Vector tempResults = new Vector();
Vector cpr = new Vector();
int size = packageList.size();
for (int i=0; i 1)
{
file = new File(targetPath.substring(0,targetPath.length()-1));
file.delete();
}
return results;
}
// Initialize
classpathAdditions_.removeAllElements();
classpathRemovals_.removeAllElements();
unexpandedFiles_.removeAllElements();
Vector errors = new Vector();
// Get contents of package file list file. An exception will
// be thrown if the file does not exist.
StringBuffer listFileName = new StringBuffer(targetPath);
listFileName.append(packageName);
listFileName.append(".LST");
String listFile = "";
try {
listFile = readFile(new FileInputStream(listFileName.toString()));
}
catch(IOException e)
{
throw new IOException("(" + packageName + ") " +
getMRIResource().getString("EXC_PACKAGE_NOT_INSTALLED"));
}
// Delete the package change list file if it exists.
// Do this first, in case the uninstall bombs midstream, user
// can recover by reinstalling.
File file = new File(targetPath + packageName + ".LVL");
if (file.exists())
{
if (!file.delete())
errors.addElement(file.getAbsolutePath());
}
// Loop through lines in the list file, deleting files.
StringTokenizer deletes = new StringTokenizer(listFile, "\n\r");
String name, type, temp;
Vector paths = new Vector(); // keep track of directories
while (deletes.hasMoreTokens())
{
name = deletes.nextToken();
if (changeSlash_)
name = name.replace('/', '\\');
file = new File(targetPath + name);
if (file.exists()) // don't want to fail if file doesn't exist
{
if (!file.delete())
errors.addElement(file.getAbsolutePath());
}
// Add any zip or jar files to the classpath removal list
// if they are in the classpath, and not already in the list.
type = name.substring(name.lastIndexOf('.')+1).toUpperCase();
temp = (new File(targetPath + name)).getAbsolutePath();
if ((type.equalsIgnoreCase("JAR") || type.equalsIgnoreCase("ZIP")) && //@D5C
classpathContains(temp)!=NOT_IN_CLASSPATH &&
!classpathRemovals_.contains(temp))
classpathRemovals_.addElement(temp);
// Keep track of the subdirectories so they can be deleted
// and added to classpath removals.
temp = file.getParent();
if (temp != null)
{
if (!paths.contains(temp))
paths.addElement(temp);
}
}
// Add targetpath to the classpath removal list,
// without trailing delimiter, if in the classpath,
// and not already in list.
if (targetPath.length() > 1)
{
temp = targetPath.substring(0,targetPath.length()-1);
temp = (new File(temp)).getAbsolutePath();
if (classpathContains(temp)!=NOT_IN_CLASSPATH &&
!classpathRemovals_.contains(temp))
classpathRemovals_.addElement(temp);
}
// Delete the package file list file itself.
// Do this last, only if there are no errors, so uninstall can
// be attempted again if we only partially uninstalled.
if (errors.size() == 0)
{
file = new File(listFileName.toString());
if (!file.delete())
errors.addElement(file.getAbsolutePath());
}
// Delete all subdirectories of the target path.
// Note a delete will fail if the directory is not empty.
// Add subdirectories to the classpath removals if in
// the classpath, and not already in the list.
int size = paths.size();
String dir;
if (targetPath.length() > 1)
temp = targetPath.substring(0,targetPath.length()-1);
else
temp = "";
for (int j=0; j 1)
{
file = new File(targetPath.substring(0,targetPath.length()-1));
file.delete();
}
return errors;
}
} // end class AS400ToolboxInstaller