Various updates to DistMaker

[1] Updated Glum to version: 1.3
[2] Added preliminary support for platform architectures (initial support for x64)
[3] Added support for zip JREs (in addition to tar.gz files)
[4] Switched over to JRE catalog mechanism.
[5] Updated variable names to reflect standardized naming convention.
[6] Reduced duplicate code
[7] Code cleanup. Auto format. Added javadocs.
This commit is contained in:
Norberto Lopez
2020-05-04 12:10:34 +00:00
parent 5961d129f9
commit a5e77b3cab
32 changed files with 795 additions and 951 deletions

View File

@@ -7,7 +7,7 @@
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="lib/glum.jar" sourcepath="lib/glum-src.jar">
<classpathentry kind="lib" path="lib/glum-1.3.jar" sourcepath="lib/glum-1.3-sources.jar">
<attributes>
<attribute name="module" value="true"/>
</attributes>
@@ -17,7 +17,7 @@
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="lib/commons-compress-1.15.jar">
<classpathentry kind="lib" path="lib/commons-compress-1.15.jar" sourcepath="lib/commons-compress-1.15-sources.jar">
<attributes>
<attribute name="module" value="true"/>
</attributes>

Binary file not shown.

View File

@@ -12,7 +12,7 @@ import distMaker.utils.Version;
public class DistApp
{
/** The DistMaker version is defined here. */
public static final Version version = new PlainVersion(0, 55, 0);
public static final Version version = new PlainVersion(0, 56, 0);
/**
* Main entry point that will print out the version of DistMaker to stdout.

View File

@@ -7,7 +7,6 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
import java.util.*;
import javax.swing.JFrame;
@@ -15,22 +14,33 @@ import javax.swing.SwingUtilities;
import com.google.common.base.Joiner;
import distMaker.digest.Digest;
import distMaker.digest.DigestUtils;
import distMaker.gui.PickReleasePanel;
import distMaker.jre.*;
import distMaker.node.*;
import distMaker.platform.PlatformUtils;
import distMaker.platform.*;
import distMaker.utils.Version;
import glum.digest.Digest;
import glum.gui.panel.generic.MessagePanel;
import glum.gui.panel.generic.PromptPanel;
import glum.gui.panel.task.FullTaskPanel;
import glum.io.IoUtil;
import glum.net.Credential;
import glum.net.NetUtil;
import glum.task.*;
import glum.unit.DateUnit;
import glum.util.ThreadUtil;
/**
* Primary controller class of DistMaker package. This class provides the following functionality:
* <UL>
* <LI>Management of initialization stage of DistMaker application.
* <LI>Fetching and downloading of application updates.
* <LI>Fetching and downloading of JRE updates.
* <LI>Applying or reverting of an update.
* </UL>
*
* @author lopeznr1
*/
public class DistMakerEngine
{
// State vars
@@ -44,6 +54,9 @@ public class DistMakerEngine
private PromptPanel promptPanel;
private PickReleasePanel pickVersionPanel;
/**
* Standard Constructor
*/
public DistMakerEngine(JFrame aParentFrame, URL aUpdateSiteUrl)
{
updateSiteUrl = aUpdateSiteUrl;
@@ -122,25 +135,25 @@ public class DistMakerEngine
/**
* returns
*
*
* @return
*/
public UpdateStatus isUpToDate()
{
LoggingTask task = new LoggingTask();
String appName = currRelease.getName();
List<AppRelease> unsortedReleaseList = DistUtils.getAvailableAppReleases(task, updateSiteUrl, appName, refCredential);
List<AppRelease> unsortedReleaseL = DistUtils.getAvailableAppReleases(task, updateSiteUrl, appName, refCredential);
if (unsortedReleaseList == null)
if (unsortedReleaseL == null)
{
// The update check failed, so return a status of false with a message about the problem
String msg = Joiner.on("; ").join(task.getMessages());
return new UpdateStatus(msg);
}
// Sort the items, and isolate the newest item
LinkedList<AppRelease> fullList = new LinkedList<>(unsortedReleaseList);
Collections.sort(fullList);
AppRelease newestRelease = fullList.removeLast();
LinkedList<AppRelease> fullReleaseL = new LinkedList<>(unsortedReleaseL);
Collections.sort(fullReleaseL);
AppRelease newestRelease = fullReleaseL.removeLast();
// The check succeeded, so return whether or not the app is up to date.
return new UpdateStatus(newestRelease.equals(currRelease));
@@ -254,7 +267,7 @@ public class DistMakerEngine
*/
private void checkForUpdatesWorker(FullTaskPanel aTask, UpdateCheckListener aListener)
{
List<AppRelease> fullList;
List<AppRelease> fullReleaseL;
AppRelease chosenItem;
File installPath, deltaPath;
String appName;
@@ -266,12 +279,12 @@ public class DistMakerEngine
// Status info
appName = currRelease.getName();
aTask.infoAppendln("Application: " + appName + " - " + currRelease.getVersion());
aTask.logRegln("Application: " + appName + " - " + currRelease.getVersion());
// Retrieve the list of available releases
aTask.infoAppendln("Checking for updates...\n");
fullList = DistUtils.getAvailableAppReleases(aTask, updateSiteUrl, appName, refCredential);
if (fullList == null)
aTask.logRegln("Checking for updates...\n");
fullReleaseL = DistUtils.getAvailableAppReleases(aTask, updateSiteUrl, appName, refCredential);
if (fullReleaseL == null)
{
aTask.abort();
return;
@@ -285,14 +298,14 @@ public class DistMakerEngine
// (This check used to be in the getAvailableReleases() call above, but I needed
// that to not throw an error for the case of only one release, so I moved that
// check here.)
if (fullList.size() == 1)
if (fullReleaseL.size() == 1)
{
if (fullList.get(0).equals(currRelease))
if (fullReleaseL.get(0).equals(currRelease))
{
// There is only one release out there, and its the same
// as the one being run, so there is nothing to update.
String msg = "There are no updates of " + appName + ". Only one release has been made.";
aTask.infoAppendln(msg);
aTask.logRegln(msg);
aTask.abort();
return;
}
@@ -302,10 +315,10 @@ public class DistMakerEngine
aTask.setVisible(false);
// Prompt the user for the Release
aTask.infoAppendln("Please select the release to install...");
aTask.logRegln("Please select the release to install...");
try
{
Runnable tmpRunnable = () -> queryUserForInput(aTask, deltaPath, fullList);
Runnable tmpRunnable = () -> queryUserForInput(aTask, deltaPath, fullReleaseL);
SwingUtilities.invokeAndWait(tmpRunnable);
}
catch(Exception aExp)
@@ -326,18 +339,18 @@ public class DistMakerEngine
aTask.setVisible(true);
// Log the user chosen action
aTask.infoAppendln("\tRelease chosen: " + chosenItem.getVersion());
aTask.logRegln("\tRelease chosen: " + chosenItem.getVersion());
if (currRelease.getBuildTime() < chosenItem.getBuildTime())
aTask.infoAppendln("\t" + appName + " will be updated...");
aTask.logRegln("\t" + appName + " will be updated...");
else
aTask.infoAppendln("\t" + appName + " will be reverted...");
aTask.logRegln("\t" + appName + " will be reverted...");
// Form the destination path
isPass = deltaPath.mkdirs();
if (isPass == false || aTask.isActive() == false)
{
aTask.infoAppendln("Failed to create delta path: " + deltaPath);
aTask.infoAppendln("Application update aborted.");
aTask.logRegln("Failed to create delta path: " + deltaPath);
aTask.logRegln("Application update aborted.");
aTask.abort();
return;
}
@@ -350,23 +363,23 @@ public class DistMakerEngine
catch(Throwable aThrowable)
{
IoUtil.deleteDirectory(deltaPath);
aTask.infoAppendln("An error occurred while trying to perform an update.");
aTask.infoAppendln("Application update aborted.");
aTask.infoAppendln("\nStackTrace:\n" + ThreadUtil.getStackTraceClassic(aThrowable));
aTask.logRegln("An error occurred while trying to perform an update.");
aTask.logRegln("Application update aborted.");
aTask.logRegln("\nStackTrace:\n" + ThreadUtil.getStackTraceClassic(aThrowable));
aTask.abort();
return;
}
if (isPass == false || aTask.isActive() == false)
{
IoUtil.deleteDirectory(deltaPath);
aTask.infoAppendln("Application update aborted.");
aTask.logRegln("Application update aborted.");
aTask.abort();
return;
}
// Notify the user of success
aTask.infoAppendln(appName + " has been updated to version: " + chosenItem.getVersion() + ".");
aTask.infoAppendln("These updates will become active when " + appName + " is restarted.");
aTask.logRegln(appName + " has been updated to version: " + chosenItem.getVersion() + ".");
aTask.logRegln("These updates will become active when " + appName + " is restarted.");
aTask.setProgress(1.0);
}
@@ -446,7 +459,6 @@ public class DistMakerEngine
Node staleNode, updateNode;
URL catUrl, staleUrl, updateUrl;
File catalogFile;
Task mainTask, tmpTask;
double progressVal;
long tmpFileLen;
@@ -457,7 +469,7 @@ public class DistMakerEngine
}
catch(MalformedURLException aExp)
{
aTask.infoAppendln(ThreadUtil.getStackTrace(aExp));
aTask.logRegln(ThreadUtil.getStackTrace(aExp));
aExp.printStackTrace();
return false;
}
@@ -473,7 +485,8 @@ public class DistMakerEngine
appNewPath.mkdirs();
catUrl = IoUtil.createURL(updateUrl.toString() + "/catalog.txt");
catalogFile = new File(appNewPath, "catalog.txt");
if (DistUtils.downloadFile(new PartialTask(aTask, 0.00, 0.01), catUrl, catalogFile, refCredential, -1L, null) == false)
Task catTask = new PartialTask(aTask, 0.00, 0.01);
if (NetUtil.download(catTask, catUrl, catalogFile, refCredential, -1L, null) == false)
return false;
// Load the update catalog
@@ -490,7 +503,7 @@ public class DistMakerEngine
}
// Set up the mainTask for downloading of remote content (Progress -> [1% - 95%])
mainTask = new PartialTask(aTask, 0.01, 0.94);
Task mainTask = new PartialTask(aTask, 0.01, 0.94);
// Ensure our JRE version is compatible for this release
JreRelease targJre = null;
@@ -516,7 +529,7 @@ public class DistMakerEngine
}
// Download the individual application files
mainTask.infoAppendln("Downloading release: " + aRelease.getVersion() + " Nodes: " + updateCat.getAllNodesList().size());
mainTask.logRegln("Downloading release: " + aRelease.getVersion() + " Nodes: " + updateCat.getAllNodesList().size());
for (Node aNode : updateCat.getAllNodesList())
{
boolean isPass;
@@ -530,7 +543,7 @@ public class DistMakerEngine
tmpFileLen = 0L;
if (updateNode instanceof FileNode)
tmpFileLen = ((FileNode)updateNode).getFileLen();
tmpTask = new PartialTask(mainTask, mainTask.getProgress(), tmpFileLen / (releaseSizeFull + 0.00));
Task tmpTask = new PartialTask(mainTask, mainTask.getProgress(), tmpFileLen / (releaseSizeFull + 0.00));
// Attempt to use the local copy
isPass = false;
@@ -542,7 +555,7 @@ public class DistMakerEngine
// isPass = staleNode.transferContentTo(tmpTask, refCredential, destPath);
isPass = staleNode.transferContentTo(new SilentTask(), refCredential, appNewPath);
if (isPass == true)
mainTask.infoAppendln("\t(L) " + staleNode.getFileName());
mainTask.logRegln("\t(L) " + staleNode.getFileName());
}
// Use the remote update copy, if we were not able to use a local stale copy
@@ -550,16 +563,16 @@ public class DistMakerEngine
{
isPass = updateNode.transferContentTo(tmpTask, refCredential, appNewPath);
if (isPass == true)
mainTask.infoAppendln("\t(R) " + updateNode.getFileName());
mainTask.logRegln("\t(R) " + updateNode.getFileName());
}
// Log the failure and bail
if (isPass == false && mainTask.isActive() == true)
{
mainTask.infoAppendln("Failed to download from update site.");
mainTask.infoAppendln("\tSite: " + updateUrl);
mainTask.infoAppendln("\tFile: " + updateNode.getFileName());
mainTask.infoAppendln("\tDest: " + appNewPath);
mainTask.logRegln("Failed to download from update site.");
mainTask.logRegln("\tSite: " + updateUrl);
mainTask.logRegln("\tFile: " + updateNode.getFileName());
mainTask.logRegln("\tDest: " + appNewPath);
return false;
}
@@ -568,7 +581,7 @@ public class DistMakerEngine
progressVal = releaseSizeCurr / (releaseSizeFull + 0.00);
mainTask.setProgress(progressVal);
}
mainTask.infoAppendln("Finished downloading release.\n");
mainTask.logRegln("Finished downloading release.\n");
// Update the platform configuration files
try
@@ -577,7 +590,7 @@ public class DistMakerEngine
}
catch(ErrorDM aExp)
{
aTask.infoAppendln("Failed updating application configuration.");
aTask.logRegln("Failed updating application configuration.");
MiscUtils.printErrorDM(aTask, aExp, 1);
return false;
}
@@ -629,8 +642,8 @@ public class DistMakerEngine
}
catch(IOException aExp)
{
aTask.infoAppendln("Failed to generate the delta.cfg file.");
aTask.infoAppendln(ThreadUtil.getStackTrace(aExp));
aTask.logRegln("Failed to generate the delta.cfg file.");
aTask.logRegln(ThreadUtil.getStackTrace(aExp));
return false;
}
@@ -647,9 +660,9 @@ public class DistMakerEngine
jreTargPath.getParentFile().setWritable(true);
if (jreDropPath.renameTo(jreTargPath) == false)
{
aTask.infoAppendln("Failed to move the updated JRE to its target location!");
aTask.infoAppendln("\t Current path: " + jreDropPath);
aTask.infoAppendln("\tOfficial path: " + jreTargPath);
aTask.logRegln("Failed to move the updated JRE to its target location!");
aTask.logRegln("\t Current path: " + jreDropPath);
aTask.logRegln("\tOfficial path: " + jreTargPath);
return false;
}
@@ -661,8 +674,8 @@ public class DistMakerEngine
}
catch(IOException aExp)
{
aTask.infoAppendln("Failed to backup application configuration file: " + appCfgFile);
aTask.infoAppendln(ThreadUtil.getStackTrace(aExp));
aTask.logRegln("Failed to backup application configuration file: " + appCfgFile);
aTask.logRegln(ThreadUtil.getStackTrace(aExp));
return false;
}
@@ -675,9 +688,9 @@ public class DistMakerEngine
}
catch(ErrorDM aExp)
{
aTask.infoAppendln("Failed to update the configuration to point to the updated JRE!");
aTask.infoAppendln("\tCurrent JRE: " + currJreVer.getLabel());
aTask.infoAppendln("\t Chosen JRE: " + targJre.getVersion().getLabel());
aTask.logRegln("Failed to update the configuration to point to the updated JRE!");
aTask.logRegln("\tCurrent JRE: " + currJreVer.getLabel());
aTask.logRegln("\t Chosen JRE: " + targJre.getVersion().getLabel());
MiscUtils.printErrorDM(aTask, aExp, 1);
// Remove the just installed JRE
@@ -724,7 +737,7 @@ public class DistMakerEngine
*/
private JreUpdateResult downloadJreUpdate(Task aTask, AppCatalog aUpdateCat, File aDestPath, long releaseSizeFull)
{
List<JreRelease> jreList;
List<JreRelease> availJreL;
// Ensure our JRE version is compatible for this release
JreVersion currJreVer = DistUtils.getJreVersion();
@@ -733,55 +746,55 @@ public class DistMakerEngine
String updnStr = "downgraded";
if (aUpdateCat.isJreVersionTooOld(currJreVer) == true)
updnStr = "upgraded";
aTask.infoAppendln("Your current JRE is not compatible with this release. It will need to be " + updnStr + "!");
aTask.infoAppendln("\tCurrent JRE: " + currJreVer.getLabel());
aTask.infoAppendln("\tMinimum JRE: " + aUpdateCat.getMinJreVersion().getLabel());
aTask.logRegln("Your current JRE is not compatible with this release. It will need to be " + updnStr + "!");
aTask.logRegln("\tCurrent JRE: " + currJreVer.getLabel());
aTask.logRegln("\tMinimum JRE: " + aUpdateCat.getMinJreVersion().getLabel());
JreVersion tmpJreVer = aUpdateCat.getMaxJreVersion();
if (tmpJreVer != null)
aTask.infoAppendln("\tMaximum JRE: " + tmpJreVer.getLabel());
aTask.infoAppendln("");
aTask.logRegln("\tMaximum JRE: " + tmpJreVer.getLabel());
aTask.logRegln("");
// Bail if we are running a non-bundled JRE
if (DistUtils.isJreBundled() == false)
{
aTask.infoAppend("This is the non bundled JRE version of the application. You are running the system JRE. ");
aTask.infoAppendln("Please update the JRE (or path) to reflect a compatible JRE version.\n");
aTask.logReg("This is the non bundled JRE version of the application. You are running the system JRE. ");
aTask.logRegln("Please update the JRE (or path) to reflect a compatible JRE version.\n");
return null;
}
// Get list of all available JREs
jreList = JreUtils.getAvailableJreReleases(aTask, updateSiteUrl, refCredential);
if (jreList == null)
availJreL = JreUtils.getAvailableJreReleases(aTask, updateSiteUrl, refCredential);
if (availJreL == null)
{
aTask.infoAppendln("The update site has not had any JREs deployed.");
aTask.infoAppendln(ErrorMsg.ContactSiteAdmin);
aTask.logRegln("The update site has not had any JREs deployed.");
aTask.logRegln(ErrorMsg.ContactSiteAdmin);
return null;
}
if (jreList.size() == 0)
if (availJreL.size() == 0)
{
aTask.infoAppendln("No JRE releases found!");
aTask.infoAppendln(ErrorMsg.ContactSiteAdmin);
aTask.logRegln("No JRE releases found!");
aTask.logRegln(ErrorMsg.ContactSiteAdmin);
return null;
}
// Retrieve the latest appropriate JreRelease
String archStr = PlatformUtils.getArchitecture();
String platStr = PlatformUtils.getPlatform();
jreList = JreUtils.getMatchingPlatforms(jreList, archStr, platStr);
if (jreList.size() == 0)
Architecture arch = ArchitectureUtils.getArchitecture();
Platform plat = PlatformUtils.getPlatform();
availJreL = JreUtils.getMatchingPlatforms(availJreL, arch, plat);
if (availJreL.size() == 0)
{
aTask.infoAppendln("There are no JRE releases available for platform: (" + archStr + ") " + platStr + "!");
aTask.logRegln("There are no JRE releases available for platform: (" + arch + ") " + plat + "!");
return null;
}
// Retrieve the JRE that is compatible from the list
JreRelease pickJre = aUpdateCat.getCompatibleJre(jreList);
JreRelease pickJre = aUpdateCat.getCompatibleJre(availJreL);
if (pickJre == null)
{
aTask.infoAppendln("There are no compatible JREs found on the deploy site. Available JREs: " + jreList.size());
for (JreRelease aJreRelease : jreList)
aTask.infoAppendln("\t" + aJreRelease.getFileName() + " ---> (JRE: " + aJreRelease.getVersion().getLabel() + ")");
aTask.infoAppendln("\n" + ErrorMsg.ContactSiteAdmin);
aTask.logRegln("There are no compatible JREs found on the deploy site. Available JREs: " + availJreL.size());
for (JreRelease aJreRelease : availJreL)
aTask.logRegln("\t" + aJreRelease.getFileName() + " ---> (JRE: " + aJreRelease.getVersion().getLabel() + ")");
aTask.logRegln("\n" + ErrorMsg.ContactSiteAdmin);
return null;
}
JreVersion pickJreVer = pickJre.getVersion();
@@ -793,7 +806,7 @@ public class DistMakerEngine
pickAppLauncher = AppLauncherUtils.updateAppLauncher(aTask, pickJre, aDestPath, updateSiteUrl, refCredential);
if (pickAppLauncher == null)
return null;
aTask.infoAppendln("");
aTask.logRegln("");
}
// Update the number of bytes to be retrieved to take into account the JRE which we will be downloading
@@ -801,30 +814,16 @@ public class DistMakerEngine
releaseSizeFull += tmpFileLen;
// Download the JRE
Digest targDigest, testDigest;
targDigest = pickJre.getDigest();
MessageDigest msgDigest;
msgDigest = DigestUtils.getDigest(targDigest.getType());
aTask.infoAppendln("Downloading JRE... Version: " + pickJreVer.getLabel());
Digest targDigest = pickJre.getDigest();
aTask.logRegln("Downloading JRE... Version: " + pickJreVer.getLabel());
URL srcUrl = IoUtil.createURL(updateSiteUrl.toString() + "/jre/" + pickJreVer.getLabel() + "/" + pickJre.getFileName());
File dstFile = new File(aDestPath, pickJre.getFileName());
Task tmpTask = new PartialTask(aTask, aTask.getProgress(), (tmpFileLen * 0.75) / (releaseSizeFull + 0.00));
if (DistUtils.downloadFile(tmpTask, srcUrl, dstFile, refCredential, tmpFileLen, msgDigest) == false)
if (NetUtil.download(tmpTask, srcUrl, dstFile, refCredential, tmpFileLen, targDigest) == false)
return null;
// Validate that the JRE was downloaded successfully
testDigest = new Digest(targDigest.getType(), msgDigest.digest());
if (targDigest.equals(testDigest) == false)
{
aTask.infoAppendln("The download of the JRE appears to be corrupted.");
aTask.infoAppendln("\tFile: " + dstFile);
aTask.infoAppendln("\t\tExpected " + targDigest.getDescr());
aTask.infoAppendln("\t\tReceived " + testDigest.getDescr() + "\n");
return null;
}
// Unpack the JRE at the unpack location
aTask.infoAppendln("Finshed downloading JRE. Unpacking JRE...");
aTask.logRegln("Finshed downloading JRE. Unpacking JRE...");
File jreRootPath = null;
File jreTargPath = new File(aDestPath, JreUtils.getExpandJrePath(pickJreVer));
try
@@ -848,12 +847,12 @@ public class DistMakerEngine
}
catch(Exception aExp)
{
aTask.infoAppendln("Failed to properly untar archive. The update has been aborted.");
aTask.infoAppendln("\tTar File: " + dstFile);
aTask.infoAppendln("\tDestination: " + jreTargPath);
aTask.logRegln("Failed to properly untar archive. The update has been aborted.");
aTask.logRegln("\tTar File: " + dstFile);
aTask.logRegln("\tDestination: " + jreTargPath);
String errMsg = ThreadUtil.getStackTrace(aExp);
aTask.infoAppend("\nStack Trace:\n" + errMsg);
aTask.logReg("\nStack Trace:\n" + errMsg);
return null;
}
@@ -890,8 +889,8 @@ public class DistMakerEngine
}
catch(ErrorDM aExp)
{
aTask.infoAppendln("Failed to revert application's JRE!");
aTask.infoAppendln("\tApplication may be in an unstable state.");
aTask.logRegln("Failed to revert application's JRE!");
aTask.logRegln("\tApplication may be in an unstable state.");
MiscUtils.printErrorDM(aTask, aExp, 1);
}
@@ -902,8 +901,8 @@ public class DistMakerEngine
}
catch(ErrorDM aExp)
{
aTask.infoAppendln("Failed to revert application configuration!");
aTask.infoAppendln("\tApplication may be in an unstable state.");
aTask.logRegln("Failed to revert application configuration!");
aTask.logRegln("\tApplication may be in an unstable state.");
MiscUtils.printErrorDM(aTask, aExp, 1);
}
@@ -1040,9 +1039,9 @@ public class DistMakerEngine
}
catch(IOException aExp)
{
aTask.infoAppendln("Failed to revert application configuration!");
aTask.infoAppendln("\tApplication may be in an unstable state.");
aTask.infoAppendln(ThreadUtil.getStackTrace(aExp));
aTask.logRegln("Failed to revert application configuration!");
aTask.logRegln("\tApplication may be in an unstable state.");
aTask.logRegln(ThreadUtil.getStackTrace(aExp));
}
// Remove the entire delta folder
@@ -1067,7 +1066,7 @@ public class DistMakerEngine
promptPanel.setVisibleAsModal();
if (promptPanel.isAccepted() == false)
{
aTask.infoAppendln("Previous update will not be overwritten.");
aTask.logRegln("Previous update will not be overwritten.");
aTask.abort();
return;
}
@@ -1082,7 +1081,7 @@ public class DistMakerEngine
chosenItem = pickVersionPanel.getChosenItem();
if (chosenItem == null)
{
aTask.infoAppendln("No release specified. Update has been aborted.");
aTask.logRegln("No release specified. Update has been aborted.");
aTask.abort();
return;
}

View File

@@ -1,31 +1,32 @@
package distMaker;
import glum.gui.GuiUtil;
import glum.io.IoUtil;
import glum.net.*;
import glum.reflect.ReflectUtil;
import glum.task.ConsoleTask;
import glum.task.Task;
import glum.unit.DateUnit;
import glum.util.ThreadUtil;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import distMaker.digest.Digest;
import distMaker.digest.DigestType;
import distMaker.jre.JreVersion;
import distMaker.node.*;
import distMaker.utils.ParseUtils;
import distMaker.utils.PlainVersion;
import distMaker.utils.Version;
import distMaker.utils.*;
import glum.digest.Digest;
import glum.digest.DigestType;
import glum.io.IoUtil;
import glum.io.ParseUtil;
import glum.net.Credential;
import glum.net.NetUtil;
import glum.reflect.ReflectUtil;
import glum.task.Task;
import glum.unit.DateUnit;
import glum.util.ThreadUtil;
/**
* Collection of utility methods used to access the state of a DistMaker enabled application.
*
* @author lopeznr1
*/
public class DistUtils
{
// -----------------------------------------------------------------------------------------------------------------
@@ -167,107 +168,13 @@ public class DistUtils
return false;
}
/**
* Downloads the specified file from srcUrl to destFile. Returns true on success
* <P>
* Note the passed in task's progress will be updated from 0% to 100% at file download completion, If the specified
* file size is invalid (aFileSize <= 0) or the download turns out to be bigger than the specified size then there
* will be no progress update while the file is being downloaded - only at completion.
*/
public static boolean downloadFile(Task aTask, URL aUrl, File aFile, Credential aCredential, long aFileSize, MessageDigest aDigest)
{
URLConnection connection;
InputStream inStream;
OutputStream outStream;
String errMsg;
byte[] byteArr;
double progressVal;
long cntByteFull, cntByteCurr;
int numBytes;
// Ensure we have a valid aTask
if (aTask == null)
aTask = new ConsoleTask();
// Allocate space for the byte buffer
byteArr = new byte[10000];
// Perform the actual copying
inStream = null;
outStream = null;
connection = null;
try
{
// Open the src stream (with a 30 sec connect timeout)
connection = aUrl.openConnection();
// connection.setConnectTimeout(30 * 1000);
// connection.setReadTimeout(90 * 1000);
// Open the input/output streams
inStream = NetUtil.getInputStream(connection, aCredential);
if (aDigest != null)
inStream = new DigestInputStream(inStream, aDigest);
outStream = new FileOutputStream(aFile);
// Copy the bytes from the instream to the outstream
cntByteFull = aFileSize;
cntByteCurr = 0;
numBytes = 0;
while (numBytes != -1)
{
numBytes = inStream.read(byteArr);
if (numBytes > 0)
{
outStream.write(byteArr, 0, numBytes);
cntByteCurr += numBytes;
}
// Update the progressVal to reflect the download progress. Note however that we do update the
// progress to 100% since that would change the task to be flagged as inactive and thus cause
// the download to be aborted prematurely.
// TODO: In the future Tasks should not be marked as inactive based on progress values
progressVal = 0;
if (cntByteFull > 0)
{
progressVal = (cntByteCurr + 0.0) / cntByteFull;
if (progressVal >= 1.0)
progressVal = 0.99;
}
aTask.setProgress(progressVal);
// Bail if aTask is aborted
if (aTask.isActive() == false)
{
aTask.infoAppendln("File transfer request has been aborted...");
aTask.infoAppendln("\tFile: " + aFile + " Bytes transferred: " + cntByteCurr);
return false;
}
}
// Mark aTask's progress as complete since the file was downloaded.
aTask.setProgress(1.0);
}
catch(IOException aExp)
{
errMsg = getErrorCodeMessage(aUrl, connection, aExp);
aTask.infoAppendln(errMsg);
return false;
}
finally
{
IoUtil.forceClose(inStream);
IoUtil.forceClose(outStream);
}
return true;
}
/**
* Returns the list of available releases.
*/
public static List<AppRelease> getAvailableAppReleases(Task aTask, URL aUpdateUrl, String appName, Credential aCredential)
public static List<AppRelease> getAvailableAppReleases(Task aTask, URL aUpdateUrl, String appName,
Credential aCredential)
{
List<AppRelease> fullList;
List<AppRelease> fullL;
AppRelease workAR;
URL catUrl;
URLConnection connection;
@@ -276,7 +183,7 @@ public class DistUtils
String errMsg;
errMsg = null;
fullList = new ArrayList<>();
fullL = new ArrayList<>();
catUrl = IoUtil.createURL(aUpdateUrl.toString() + "/" + appName + "/" + "appCatalog.txt");
workAR = null;
@@ -335,7 +242,7 @@ public class DistUtils
// Record the prior AppRelease
if (workAR != null)
fullList.add(workAR);
fullL.add(workAR);
workAR = new AppRelease(appName, verName, buildTime);
}
@@ -364,18 +271,18 @@ public class DistUtils
}
else
{
aTask.infoAppendln("Unreconized line: " + strLine);
aTask.logRegln("Unreconized line: " + strLine);
}
}
// Add the last AppRelease
if (workAR != null)
fullList.add(workAR);
fullL.add(workAR);
}
catch(IOException aExp)
catch (IOException aExp)
{
// Friendly error message
errMsg = getErrorCodeMessage(aUpdateUrl, connection, aExp);
errMsg = NetUtil.getErrorCodeMessage(aUpdateUrl, connection, aExp);
// Add the stack trace
errMsg += "\n\n" + ThreadUtil.getStackTrace(aExp);
@@ -389,61 +296,17 @@ public class DistUtils
// See if we are in a valid state
if (errMsg != null)
; // Nothing to do, as an earlier error has occurred
else if (fullList.size() == 0)
else if (fullL.size() == 0)
errMsg = "The update URL appears to be invalid.";
// Bail if there were issues
if (errMsg != null)
{
aTask.infoAppendln(errMsg);
aTask.logRegln(errMsg);
return null;
}
return fullList;
}
/**
* Helper method that converts an IOException to an understandable message
*/
private static String getErrorCodeMessage(URL aUpdateUrl, URLConnection aConnection, IOException aExp)
{
// Form a user friendly exception
String errMsg;
errMsg = "The update site, " + aUpdateUrl + ", is not available.\n\t";
Result result;
result = NetUtil.getResult(aExp, aConnection);
switch (result)
{
case BadCredentials:
errMsg += "The update site is password protected and bad credentials were provided.\n";
break;
case ConnectFailure:
case UnreachableHost:
case UnsupportedConnection:
errMsg += "The update site appears to be unreachable.\n";
break;
case Interrupted:
errMsg += "The retrival of the remote file has been interrupted.\n";
break;
case InvalidResource:
errMsg += "The remote file does not appear to be valid.\n";
break;
default:
errMsg += "An undefined error occurred while retrieving the remote file.\n";
break;
}
// Log the URL which we failed on
URL fetchUrl;
fetchUrl = aConnection.getURL();
errMsg += "\tURL: " + fetchUrl + "\n";
return errMsg;
return fullL;
}
/**
@@ -483,12 +346,12 @@ public class DistUtils
*/
public static AppCatalog readAppCatalog(Task aTask, File aCatalogFile, URL aUpdateUrl)
{
List<Node> nodeList;
List<Node> nodeL;
JreVersion minJreVersion, maxJreVersion;
String errMsg, strLine;
errMsg = null;
nodeList = new ArrayList<>();
nodeL = new ArrayList<>();
minJreVersion = null;
maxJreVersion = null;
@@ -496,7 +359,8 @@ public class DistUtils
DigestType digestType;
digestType = DigestType.MD5;
try (BufferedReader tmpBR = new BufferedReader(new InputStreamReader(new BufferedInputStream(new FileInputStream(aCatalogFile))));)
try (BufferedReader tmpBR = new BufferedReader(
new InputStreamReader(new BufferedInputStream(new FileInputStream(aCatalogFile))));)
{
String[] tokens;
@@ -520,7 +384,7 @@ public class DistUtils
// Form the PathNode
filename = tokens[1];
nodeList.add(new PathNode(aUpdateUrl, filename));
nodeL.add(new PathNode(aUpdateUrl, filename));
}
else if (tokens.length == 4 && tokens[0].equals("F") == true)
{
@@ -529,9 +393,9 @@ public class DistUtils
// Form the FileNode
digestStr = tokens[1];
fileLen = GuiUtil.readLong(tokens[2], -1);
fileLen = ParseUtil.readLong(tokens[2], -1);
filename = tokens[3];
nodeList.add(new FileNode(aUpdateUrl, filename, new Digest(digestType, digestStr), fileLen));
nodeL.add(new FileNode(aUpdateUrl, filename, new Digest(digestType, digestStr), fileLen));
}
else if (tokens.length == 2 && tokens[0].equals("digest") == true)
{
@@ -539,7 +403,7 @@ public class DistUtils
tmpDigestType = DigestType.parse(tokens[1]);
if (tmpDigestType == null)
aTask.infoAppendln("Failed to locate DigestType for: " + tokens[1]);
aTask.logRegln("Failed to locate DigestType for: " + tokens[1]);
else
digestType = tmpDigestType;
}
@@ -547,7 +411,8 @@ public class DistUtils
{
if (minJreVersion != null)
{
aTask.infoAppendln("JRE version has already been specified. Current ver: " + minJreVersion.getLabel() + " Requested ver: " + tokens[1] + ". Skipping...");
aTask.logRegln("JRE version has already been specified. Current ver: " + minJreVersion.getLabel()
+ " Requested ver: " + tokens[1] + ". Skipping...");
continue;
}
@@ -557,11 +422,11 @@ public class DistUtils
}
else
{
aTask.infoAppendln("Unreconized line: " + strLine);
aTask.logRegln("Unreconized line: " + strLine);
}
}
}
catch(IOException aExp)
catch (IOException aExp)
{
errMsg = ThreadUtil.getStackTrace(aExp);
}
@@ -569,17 +434,17 @@ public class DistUtils
// See if we are in a valid state
if (errMsg != null)
; // Nothing to do, as an earlier error has occurred
else if (nodeList.size() == 0)
else if (nodeL.size() == 0)
errMsg = "The catalog appears to be invalid.";
// Bail if there were issues
if (errMsg != null)
{
aTask.infoAppendln(errMsg);
aTask.logRegln(errMsg);
return null;
}
return new AppCatalog(nodeList, minJreVersion, maxJreVersion);
return new AppCatalog(nodeL, minJreVersion, maxJreVersion);
}
/**

View File

@@ -2,13 +2,15 @@ package distMaker;
/**
* Generic runtime exception thrown by various DistMaker modules/routines.
*
* @author lopeznr1
*/
public class ErrorDM extends RuntimeException
{
private static final long serialVersionUID = 1L;
// State vars
private String subject;
private final String subject;
public ErrorDM(Throwable aCause, String aMessage, String aSubject)
{

View File

@@ -7,31 +7,31 @@ import java.util.List;
public class LoggingTask extends SilentTask
{
private final List<String> messages = new ArrayList<>();
private final List<String> messageL = new ArrayList<>();
@Override
public void infoAppend(String aMsg)
public void logReg(String aMsg)
{
messages.add(aMsg);
super.infoAppend(aMsg);
messageL.add(aMsg);
super.logReg(aMsg);
}
@Override
public void infoAppendln(String aMsg)
public void logRegln(String aMsg)
{
messages.add(aMsg);
super.infoAppendln(aMsg);
messageL.add(aMsg);
super.logRegln(aMsg);
}
@Override
public void infoUpdate(String aMsg)
public void logRegUpdate(String aMsg)
{
messages.add(aMsg);
super.infoUpdate(aMsg);
messageL.add(aMsg);
super.logRegUpdate(aMsg);
}
List<String> getMessages()
{
return messages;
return messageL;
}
}

View File

@@ -1,27 +1,32 @@
package distMaker;
import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;
import java.security.MessageDigest;
import java.util.*;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipInputStream;
import org.apache.commons.compress.archivers.*;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.utils.IOUtils;
import com.google.common.base.Strings;
import com.google.common.io.CountingInputStream;
import glum.digest.Digest;
import glum.digest.DigestUtils;
import glum.net.*;
import glum.task.Task;
import glum.util.ThreadUtil;
/**
* Collection of generic utility methods that should be migrated to another library / class.
*
* @author lopeznr1
*/
public class MiscUtils
{
@@ -57,6 +62,54 @@ public class MiscUtils
return PosixFilePermissions.fromString(convertUnixModeToStr(aMode));
}
public static boolean download(Task aTask, URL aSrcUrl, File aDstFile, Credential aCredential, long aFileLen,
Digest aTargDigest)
{
// Form the message digest of interest
MessageDigest tmpMessageDigest = null;
if (aTargDigest != null)
tmpMessageDigest = DigestUtils.getDigest(aTargDigest.getType());
try
{
NetUtil.download(aTask, aSrcUrl, aDstFile, aCredential, aFileLen, tmpMessageDigest, null);
if (aTask.isAborted() == true)
{
aTask.logRegln("File download has been aborted...");
aTask.logRegln("\tSource: " + aSrcUrl);
aTask.logRegln("\tFile: " + aDstFile + "\n");
// aTask.logRegln("\tFile: " + dstFile + " Bytes transferred: " + cntByteCurr);
return false;
}
}
catch (FetchError aExp)
{
aTask.logRegln("File download has failed...");
aTask.logRegln("\tReason: " + aExp.getResult());
aTask.logRegln("\tSource: " + aSrcUrl);
aTask.logRegln("\tFile: " + aDstFile + "\n");
return false;
}
// Success if there is no targDigest to validate against
if (aTargDigest == null)
return true;
// Validate that the file was downloaded successfully
Digest testDigest = new Digest(aTargDigest.getType(), tmpMessageDigest.digest());
if (aTargDigest.equals(testDigest) == false)
{
aTask.logRegln("File download is corrupted...");
aTask.logRegln("\tFile: " + aDstFile);
aTask.logRegln("\t\tExpected " + aTargDigest.getDescr());
aTask.logRegln("\t\tReceived " + testDigest.getDescr() + "\n");
return false;
}
return true;
}
/**
* Returns the relative path component of aAbsolutePath relative to aBasePath.
* <P>
@@ -97,25 +150,25 @@ public class MiscUtils
tabStr = Strings.repeat("\t", numTabs);
aTask.infoAppendln(tabStr + "Reason: " + aErrorDM.getMessage());
aTask.logRegln(tabStr + "Reason: " + aErrorDM.getMessage());
cause = aErrorDM.getCause();
while (cause != null)
{
if (cause instanceof ErrorDM)
{
aTask.infoAppendln(tabStr + "Reason: " + cause.getMessage());
aTask.logRegln(tabStr + "Reason: " + cause.getMessage());
}
else
{
aTask.infoAppendln(tabStr + "StackTrace: ");
aTask.infoAppendln(ThreadUtil.getStackTrace(cause));
aTask.logRegln(tabStr + "StackTrace: ");
aTask.logRegln(ThreadUtil.getStackTrace(cause));
break;
}
cause = aErrorDM.getCause();
}
aTask.infoAppendln("");
aTask.logRegln("");
}
/**
@@ -126,7 +179,7 @@ public class MiscUtils
* <P>
* The output file is created in the output folder, having the same name as the input file, minus the '.tar'
* extension.
*
*
* @param inputFile
* the input .tar.gz or zip file
* @param aDestPath
@@ -138,10 +191,10 @@ public class MiscUtils
*/
public static List<File> unPack(Task aTask, final File inputFile, final File aDestPath) throws FileNotFoundException, IOException, ArchiveException
{
Map<File, Long> pathMap;
Map<File, Long> pathM;
InputStream iStream;
final List<File> untaredFiles = new ArrayList<>();
final List<File> untaredFileL = new ArrayList<>();
long fullLen = inputFile.length();
// Open up the stream to the tar file (set up a counting stream to allow for progress updates)
@@ -160,7 +213,7 @@ public class MiscUtils
// iStream = new ZipInputStream(iStream);
}
pathMap = new LinkedHashMap<>();
pathM = new LinkedHashMap<>();
final ArchiveInputStream debInputStream = new ArchiveStreamFactory().createArchiveInputStream(archiverName, iStream);
TarArchiveEntry entry = null;
while ((entry = (TarArchiveEntry)debInputStream.getNextEntry()) != null)
@@ -182,7 +235,7 @@ public class MiscUtils
long tmpUtc = entry.getModTime().getTime();
outputFile.setLastModified(tmpUtc);
pathMap.put(outputFile, tmpUtc);
pathM.put(outputFile, tmpUtc);
}
else if (entry.isSymbolicLink() == true)
{
@@ -201,7 +254,7 @@ public class MiscUtils
// {
// DateUnit dUnit = new DateUnit("", "yyyyMMddHHmmss");
// long tmpUtc = entry.getModTime().getTime();
// String timeStamp = dUnit.getString(tmpUtc);
// String timeStamp = dUnit.getString(tmpUtc);
// Runtime.getRuntime().exec("touch -h -t " + timeStamp + " " + outLink.toAbsolutePath());
// }
}
@@ -235,28 +288,28 @@ public class MiscUtils
// System.out.println(String.format("\tMode: %d %x %s %s name: %s", mode, mode, Integer.toOctalString(mode), permStr, entry.getName()));
}
untaredFiles.add(outputFile);
untaredFileL.add(outputFile);
// Update the progress bar
aTask.infoUpdate("\tUnpacked: " + entry.getName());
aTask.logRegUpdate("\tUnpacked: " + entry.getName());
long currLen = cntStream.getCount();
aTask.setProgress(currLen / (fullLen + 0.0));
}
debInputStream.close();
// Update all of the times on the folders last
for (File aDir : pathMap.keySet())
for (File aDir : pathM.keySet())
{
// Bail if we have been aborted
if (aTask.isActive() == false)
return null;
aDir.setLastModified(pathMap.get(aDir));
aDir.setLastModified(pathM.get(aDir));
}
aTask.infoAppendln("\tUnpacked: " + untaredFiles.size() + " files\n");
aTask.logRegln("\tUnpacked: " + untaredFileL.size() + " files\n");
return untaredFiles;
return untaredFileL;
}
/**
@@ -264,13 +317,13 @@ public class MiscUtils
* <P>
* On failure this method will throw an exception of type ErrorDM.
*/
public static void writeDoc(File aFile, List<String> aStrList)
public static void writeDoc(File aFile, List<String> aStrL)
{
// Output the strList
try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(aFile)));)
{
// Write the lines
for (String aStr : aStrList)
for (String aStr : aStrL)
bw.write(aStr + '\n');
}
catch(IOException aExp)

View File

@@ -1,83 +0,0 @@
package distMaker.digest;
import java.util.Arrays;
public class Digest
{
private final DigestType digestType;
private final byte[] digestValueArr;
public Digest(DigestType aDigestType, byte[] aDigestValueArr)
{
digestType = aDigestType;
digestValueArr = Arrays.copyOf(aDigestValueArr, aDigestValueArr.length);
}
public Digest(DigestType aDigestType, String aHexStr)
{
digestType = aDigestType;
digestValueArr = DigestUtils.hexStr2ByteArr(aHexStr);
}
/**
* Returns a user friendly description (string) of this digest result.
* <P>
* The result will be DigestType:hexDigestValue
*/
public String getDescr()
{
return "" + digestType + ":" + getValueAsString();
}
/**
* Returns the DigestType associated with this Digest.
*/
public DigestType getType()
{
return digestType;
}
/**
* Returns the actual digest (as a string) associated with this Digest.
*/
public byte[] getValue()
{
return Arrays.copyOf(digestValueArr, digestValueArr.length);
}
/**
* Returns the actual digest (as a string) associated with this Digest.
*/
public String getValueAsString()
{
return DigestUtils.byteArr2HexStr(digestValueArr);
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((digestType == null) ? 0 : digestType.hashCode());
result = prime * result + Arrays.hashCode(digestValueArr);
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Digest other = (Digest)obj;
if (digestType != other.digestType)
return false;
if (!Arrays.equals(digestValueArr, other.digestValueArr))
return false;
return true;
}
}

View File

@@ -1,46 +0,0 @@
package distMaker.digest;
public enum DigestType
{
// Weak digest - but very fast
MD5("MD5"),
// Fairly strong digest type (with good performance on 32 bit machines)
SHA256("SHA-256"),
// Very strong digest type
SHA512("SHA-512");
// State vars
private String algName;
private DigestType(String aAlgName)
{
algName = aAlgName;
}
/**
* Returns the official digest algorithm name.
*
* @see http://docs.oracle.com/javase/1.5.0/docs/guide/security/CryptoSpec.html#AppA
*/
public String getAlgName()
{
return algName;
}
/**
* Returns the corresponding DigestType.
*/
public static DigestType parse(String aStr)
{
if (aStr.equalsIgnoreCase("MD5") == true)
return MD5;
if (aStr.equalsIgnoreCase("SHA256") == true)
return SHA256;
if (aStr.equalsIgnoreCase("SHA512") == true)
return SHA512;
return null;
}
}

View File

@@ -1,68 +0,0 @@
package distMaker.digest;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import com.google.common.io.BaseEncoding;
/**
* Collection of utility methods to ease working with the MessageDigest and associated classes.
*/
public class DigestUtils
{
/**
* Utility method that will throw a RuntimeExcepption if the specified digest function is not found.
* <P>
* Algorithm should be MD5, SHA-256, SHA-512, ...
* <P>
* See: http://docs.oracle.com/javase/1.8.0/docs/guide/security/CryptoSpec.html#AppA
*/
public static MessageDigest getDigest(String aAlgorithm)
{
MessageDigest retDigest;
try
{
retDigest = MessageDigest.getInstance(aAlgorithm);
}
catch(NoSuchAlgorithmException aExp)
{
throw new RuntimeException("Digest not found. Digest algorith not found: " + aAlgorithm);
}
return retDigest;
}
/**
* Utility method that will throw a RuntimeExcepption if the specified digest function is not found.
* <P>
* See: http://docs.oracle.com/javase/1.8.0/docs/guide/security/CryptoSpec.html#AppA
*/
public static MessageDigest getDigest(DigestType aDigestType)
{
return getDigest(aDigestType.getAlgName());
}
/**
* Utility method that returns the (lower case) hex string corresponding to the byte array.
* <P>
* Delegates to {@link BaseEncoding.base16().lowerCase().encode(CharSequence)}
*/
public static String byteArr2HexStr(byte[] aByteArr)
{
String retStr = BaseEncoding.base16().lowerCase().encode(aByteArr);
return retStr;
}
/**
* Utility method that returns a byte array corresponding to the hex string.
* <P>
* Delegates to {@link BaseEncoding.base16().lowerCase().decode(CharSequence)}
*/
public static byte[] hexStr2ByteArr(String aHexStr)
{
byte[] retArr = BaseEncoding.base16().lowerCase().decode(aHexStr);
return retArr;
}
}

View File

@@ -1,16 +1,11 @@
package distMaker.gui;
import glum.gui.FocusUtil;
import glum.gui.GuiUtil;
import glum.gui.action.ClickAction;
import glum.gui.component.GLabel;
import glum.gui.component.GSlider;
import glum.gui.panel.GlassPanel;
import glum.gui.panel.generic.MessagePanel;
import glum.unit.ByteUnit;
import glum.util.ThreadUtil;
import static distMaker.platform.MemUtils.GB_SIZE;
import static distMaker.platform.MemUtils.KB_SIZE;
import static distMaker.platform.MemUtils.MB_SIZE;
import java.awt.*;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.management.ManagementFactory;
@@ -21,14 +16,29 @@ import javax.swing.border.BevelBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import net.miginfocom.swing.MigLayout;
import com.google.common.collect.Range;
import distMaker.ErrorDM;
import distMaker.platform.MemUtils;
import distMaker.platform.PlatformUtils;
import static distMaker.platform.MemUtils.KB_SIZE;
import static distMaker.platform.MemUtils.MB_SIZE;
import static distMaker.platform.MemUtils.GB_SIZE;
import glum.gui.FocusUtil;
import glum.gui.GuiUtil;
import glum.gui.action.ClickAction;
import glum.gui.component.GLabel;
import glum.gui.component.GSlider;
import glum.gui.panel.GlassPanel;
import glum.gui.panel.generic.MessagePanel;
import glum.io.ParseUtil;
import glum.unit.ByteUnit;
import glum.util.ThreadUtil;
import net.miginfocom.swing.MigLayout;
/**
* User input component that configures the applications memory usage. Changes will not take effect until the
* application is restarted.
*
* @author lopeznr1
*/
public class MemoryConfigPanel extends GlassPanel implements ActionListener, ListSelectionListener
{
/** Unused - but added to eliminate warning due to poorly designed java.io.Serializable interface. */
@@ -43,30 +53,31 @@ public class MemoryConfigPanel extends GlassPanel implements ActionListener, Lis
private MessagePanel warnPanel;
// State vars
private long minMemSize, maxMemSize;
private Range<Double> memSizeRange;
private long currMemSize;
private long instMemSize;
private long targMemSize;
/**
* Constructor where the developer specifies the max heap memory. Be careful about using this method, as if a value is specified too large, then the program
* may become non operational on the next run.
* Constructor where the developer specifies the max heap memory. Be careful about using this method, as if a value
* is specified too large, then the program may become non operational on the next run.
* <P>
* Should the program become non operational then the end user would have to manually configure the config/script files by hand or a reinstall would be
* required.
* Should the program become non operational then the end user would have to manually configure the config/script
* files by hand or a reinstall would be required.
*/
public MemoryConfigPanel(Component aParent, long aMaxMemSize)
{
super(aParent);
// State vars
minMemSize = roundToMB(256 * MB_SIZE);
maxMemSize = roundToMB(aMaxMemSize);
double minMemSize = roundToMB(256 * MB_SIZE);
double maxMemSize = roundToMB(aMaxMemSize);
memSizeRange = Range.closed(minMemSize, maxMemSize);
initialize();
// Build the actual GUI
buildGuiArea();
warnPanel = new MessagePanel(this);
warnPanel = new MessagePanel(this, "Memory");
warnPanel.setSize(400, 150);
// Set up some keyboard shortcuts
@@ -75,8 +86,8 @@ public class MemoryConfigPanel extends GlassPanel implements ActionListener, Lis
}
/**
* Constructor where the DistMaker framework attempts to determine the appropriate maxMexSize. Should, the DistMaker framework fail to determine the
* installed system memory, then 4GB will be assumed as the installed system memory.
* Constructor where the DistMaker framework attempts to determine the appropriate maxMexSize. Should, the DistMaker
* framework fail to determine the installed system memory, then 4GB will be assumed as the installed system memory.
*/
public MemoryConfigPanel(Component aParent)
{
@@ -121,7 +132,7 @@ public class MemoryConfigPanel extends GlassPanel implements ActionListener, Lis
public void applyChanges()
{
// Retrieve the targMemSize
targMemSize = (long)targMemS.getModelValue();
targMemSize = (long) targMemS.getModelValue();
targMemSize = roundToMB(targMemSize);
try
@@ -129,7 +140,7 @@ public class MemoryConfigPanel extends GlassPanel implements ActionListener, Lis
// Delegate the updating of the memory
PlatformUtils.setMaxHeapMem(targMemSize);
}
catch(ErrorDM aExp)
catch (ErrorDM aExp)
{
String subjectStr = aExp.getSubject();
if (subjectStr == null)
@@ -173,6 +184,8 @@ public class MemoryConfigPanel extends GlassPanel implements ActionListener, Lis
smallFont = new JTextField().getFont();
// Stat area
double minMemSize = memSizeRange.lowerEndpoint();
double maxMemSize = memSizeRange.upperEndpoint();
tmpL = new JLabel("System memory: ");
maxMemL = new GLabel(byteUnit, smallFont);
maxMemL.setValue(maxMemSize);
@@ -189,8 +202,8 @@ public class MemoryConfigPanel extends GlassPanel implements ActionListener, Lis
tmpComp = GuiUtil.createDivider();
add(tmpComp, "gaptop 15,gapbottom 10,growx,h 4!,span,wrap");
maxSteps = (int)((maxMemSize - minMemSize) / MB_SIZE);
targMemS = new GSlider(this, maxSteps, minMemSize, maxMemSize);
maxSteps = (int) ((maxMemSize - minMemSize) / MB_SIZE);
targMemS = new GSlider(this, memSizeRange, maxSteps);
targMemS.setModelValue(currMemSize);
add(targMemS, "growx,span,wrap");
@@ -218,7 +231,7 @@ public class MemoryConfigPanel extends GlassPanel implements ActionListener, Lis
setBorder(new BevelBorder(BevelBorder.RAISED));
// Configure the slider to be aware of the new memory range
targMemS.setModelRange(256 * MB_SIZE, maxMemSize);
targMemS.setModelRange(memSizeRange);
targMemS.setModelValue(currMemSize);
}
@@ -227,27 +240,27 @@ public class MemoryConfigPanel extends GlassPanel implements ActionListener, Lis
*/
private void initialize()
{
List<String> argList;
List<String> argL;
String memStr;
// Retrieve the default max memory value as specified to the JVM
currMemSize = Runtime.getRuntime().maxMemory();
// Parse the args to see if we could locate the -Xmx JVM argument
argList = ManagementFactory.getRuntimeMXBean().getInputArguments();
for (String aArg : argList)
argL = ManagementFactory.getRuntimeMXBean().getInputArguments();
for (String aArg : argL)
{
if (aArg.startsWith("-Xmx") == true)
{
memStr = aArg.toUpperCase().substring(4);
if (memStr.endsWith("K") == true)
currMemSize = GuiUtil.readLong(memStr.substring(0, memStr.length() - 1), currMemSize) * KB_SIZE;
currMemSize = ParseUtil.readLong(memStr.substring(0, memStr.length() - 1), currMemSize) * KB_SIZE;
else if (memStr.endsWith("M") == true)
currMemSize = GuiUtil.readLong(memStr.substring(0, memStr.length() - 1), currMemSize) * MB_SIZE;
currMemSize = ParseUtil.readLong(memStr.substring(0, memStr.length() - 1), currMemSize) * MB_SIZE;
else if (memStr.endsWith("G") == true)
currMemSize = GuiUtil.readLong(memStr.substring(0, memStr.length() - 1), currMemSize) * GB_SIZE;
currMemSize = ParseUtil.readLong(memStr.substring(0, memStr.length() - 1), currMemSize) * GB_SIZE;
else
currMemSize = GuiUtil.readLong(memStr, currMemSize);
currMemSize = ParseUtil.readLong(memStr, currMemSize);
//System.out.println(" ---> Parsed mem value: " + new ByteUnit(2).getString(currMemSize));
}
@@ -260,7 +273,8 @@ public class MemoryConfigPanel extends GlassPanel implements ActionListener, Lis
}
/**
* Utility method to round (floor) values to the nearest megabyte. The returned value is guaranteed to be at least 1 megabyte.
* Utility method to round (floor) values to the nearest megabyte. The returned value is guaranteed to be at least 1
* megabyte.
* <P>
* The input value, aSize, should be specified in bytes, and the returned value will be specified in bytes.
*/
@@ -284,7 +298,7 @@ public class MemoryConfigPanel extends GlassPanel implements ActionListener, Lis
boolean isEnabled;
// Target area
targMemSize = (long)targMemS.getModelValue();
targMemSize = (long) targMemS.getModelValue();
targMemSize = roundToMB(targMemSize);
targMemS.setModelValue(targMemSize);

View File

@@ -1,5 +1,20 @@
package distMaker.gui;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import distMaker.LookUp;
import distMaker.node.AppRelease;
import glum.gui.FocusUtil;
import glum.gui.GuiUtil;
import glum.gui.action.ClickAction;
@@ -9,23 +24,13 @@ import glum.gui.panel.itemList.StaticItemProcessor;
import glum.gui.panel.itemList.query.*;
import glum.unit.ConstUnitProvider;
import glum.unit.DateUnit;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.List;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import net.miginfocom.swing.MigLayout;
import distMaker.LookUp;
import distMaker.node.AppRelease;
/**
* User input component that allows the user to specify an {@link AppRelease}.
*
* @author lopeznr1
*/
public class PickReleasePanel extends GlassPanel implements ActionListener, ListSelectionListener
{
// Constants
@@ -47,6 +52,9 @@ public class PickReleasePanel extends GlassPanel implements ActionListener, List
private AppRelease installedItem;
private AppRelease newestItem;
/**
* Standard Constructor
*/
public PickReleasePanel(Component aParent, AppRelease aInstalledItem)
{
super(aParent);
@@ -76,7 +84,7 @@ public class PickReleasePanel extends GlassPanel implements ActionListener, List
/**
* Sets in the configuration of available versions
*/
public void setConfiguration(List<AppRelease> aItemList)
public void setConfiguration(List<AppRelease> aItemL)
{
DateUnit dateUnit;
// String currBuildStr;
@@ -85,11 +93,11 @@ public class PickReleasePanel extends GlassPanel implements ActionListener, List
String appName, headMsg;
// Sort the items, and isolate the newest item
LinkedList<AppRelease> linkedList;
linkedList = new LinkedList<>(aItemList);
Collections.sort(linkedList);
Collections.reverse(linkedList); // reverse the list to show most recent versions on top
newestItem = linkedList.removeFirst();
LinkedList<AppRelease> tmpItemL;
tmpItemL = new LinkedList<>(aItemL);
Collections.sort(tmpItemL);
Collections.reverse(tmpItemL); // reverse the list to show most recent versions on top
newestItem = tmpItemL.removeFirst();
// Retrieve vars of interest
appName = installedItem.getName();
@@ -103,7 +111,7 @@ public class PickReleasePanel extends GlassPanel implements ActionListener, List
newestRB.setText("Latest: " + lastVerStr + " (" + lastBuildStr + ")");
// Update the list of available items
myItemProcessor.setItems(linkedList);
myItemProcessor.setItems(tmpItemL);
// Update the infoTA
if (newestItem.equals(installedItem) == true)

View File

@@ -1,14 +1,14 @@
package distMaker.jre;
import distMaker.digest.Digest;
import distMaker.utils.PlainVersion;
import distMaker.utils.Version;
import distMaker.utils.VersionUtils;
import distMaker.utils.*;
import glum.digest.Digest;
/**
* Immutable class that describes an AppLauncher release.
* <P>
* The reference fileName should be a jar file.
*
* @author lopeznr1
*/
public class AppLauncherRelease implements Comparable<AppLauncherRelease>
{

View File

@@ -1,45 +1,39 @@
package distMaker.jre;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.List;
import distMaker.DistUtils;
import distMaker.ErrorMsg;
import distMaker.digest.Digest;
import distMaker.digest.DigestType;
import distMaker.digest.DigestUtils;
import distMaker.*;
import distMaker.platform.PlatformUtils;
import distMaker.utils.ParseUtils;
import distMaker.utils.PlainVersion;
import distMaker.utils.Version;
import distMaker.utils.VersionUtils;
import glum.gui.GuiUtil;
import distMaker.utils.*;
import glum.digest.Digest;
import glum.digest.DigestType;
import glum.io.IoUtil;
import glum.io.ParseUtil;
import glum.net.Credential;
import glum.net.NetUtil;
import glum.task.PartialTask;
import glum.task.Task;
import glum.util.ThreadUtil;
/**
* Collection of utility methods associated with the DistMaker's AppLauncher.
*
* @author lopeznr1
*/
public class AppLauncherUtils
{
/**
* Returns a list of all the available AppLauncher releases specified at: <BR>
* {@literal <aUpdateSiteUrl>/launcher/appCatalog.txt}
*/
public static List<AppLauncherRelease> getAvailableAppLauncherReleases(Task aTask, URL aUpdateSiteUrl, Credential aCredential)
public static List<AppLauncherRelease> getAvailableAppLauncherReleases(Task aTask, URL aUpdateSiteUrl,
Credential aCredential)
{
List<AppLauncherRelease> retList;
List<AppLauncherRelease> retL;
URL catUrl;
URLConnection connection;
InputStream inStream;
@@ -48,7 +42,7 @@ public class AppLauncherUtils
String errMsg, strLine;
errMsg = null;
retList = new ArrayList<>();
retL = new ArrayList<>();
catUrl = IoUtil.createURL(aUpdateSiteUrl.toString() + "/launcher/appCatalog.txt");
// Default to DigestType of MD5
@@ -100,7 +94,7 @@ public class AppLauncherUtils
tmpDigestType = DigestType.parse(tokens[1]);
if (tmpDigestType == null)
aTask.infoAppendln("Failed to locate DigestType for: " + tokens[1]);
aTask.logRegln("Failed to locate DigestType for: " + tokens[1]);
else
digestType = tmpDigestType;
}
@@ -112,24 +106,24 @@ public class AppLauncherUtils
// Form the JreRelease
digestStr = tokens[1];
fileLen = GuiUtil.readLong(tokens[2], -1);
fileLen = ParseUtil.readLong(tokens[2], -1);
filename = tokens[3];
version = tokens[4];
Digest tmpDigest = new Digest(digestType, digestStr);
retList.add(new AppLauncherRelease(version, filename, tmpDigest, fileLen));
retL.add(new AppLauncherRelease(version, filename, tmpDigest, fileLen));
}
else
{
aTask.infoAppendln("Unreconized line: " + strLine);
aTask.logRegln("Unreconized line: " + strLine);
}
}
}
catch(FileNotFoundException aExp)
catch (FileNotFoundException aExp)
{
errMsg = "Failed to locate resource: " + catUrl;
}
catch(IOException aExp)
catch (IOException aExp)
{
errMsg = ThreadUtil.getStackTrace(aExp);
}
@@ -142,17 +136,17 @@ public class AppLauncherUtils
// See if we are in a valid state
if (errMsg != null)
; // Nothing to do, as an earlier error has occurred
else if (retList.size() == 0)
else if (retL.size() == 0)
errMsg = "The catalog appears to be invalid.";
// Bail if there were issues
if (errMsg != null)
{
aTask.infoAppendln(errMsg);
aTask.logRegln(errMsg);
return null;
}
return retList;
return retL;
}
/**
@@ -173,13 +167,13 @@ public class AppLauncherUtils
return false;
// Log the fact that we need to update our AppLauncher
aTask.infoAppendln("Your current AppLauncher is not compatible with this release. It will need to be upgraded!");
aTask.infoAppendln("\tCurrent ver: " + currVer);
aTask.logRegln("Your current AppLauncher is not compatible with this release. It will need to be upgraded!");
aTask.logRegln("\tCurrent ver: " + currVer);
if (nMinVer != PlainVersion.AbsMin)
aTask.infoAppendln("\tMinimum ver: " + nMinVer);
aTask.logRegln("\tMinimum ver: " + nMinVer);
if (nMaxVer != PlainVersion.AbsMax)
aTask.infoAppendln("\tMaximum ver: " + nMaxVer);
aTask.infoAppendln("");
aTask.logRegln("\tMaximum ver: " + nMaxVer);
aTask.logRegln("");
return true;
}
@@ -199,22 +193,23 @@ public class AppLauncherUtils
* <P>
* Returns false on any failure.
*/
public static AppLauncherRelease updateAppLauncher(Task aTask, JreRelease aJreRelease, File aDestPath, URL updateSiteUrl, Credential aCredential)
public static AppLauncherRelease updateAppLauncher(Task aTask, JreRelease aJreRelease, File aDestPath,
URL updateSiteUrl, Credential aCredential)
{
// Locate the list of available AppLaunchers
List<AppLauncherRelease> availList;
availList = AppLauncherUtils.getAvailableAppLauncherReleases(aTask, updateSiteUrl, aCredential);
if (availList == null)
List<AppLauncherRelease> availL;
availL = AppLauncherUtils.getAvailableAppLauncherReleases(aTask, updateSiteUrl, aCredential);
if (availL == null)
{
aTask.infoAppendln("The update site does not have any deployed AppLaunchers.");
aTask.infoAppendln(ErrorMsg.ContactSiteAdmin);
aTask.logRegln("The update site does not have any deployed AppLaunchers.");
aTask.logRegln(ErrorMsg.ContactSiteAdmin);
return null;
}
if (availList.size() == 0)
if (availL.size() == 0)
{
aTask.infoAppendln("No AppLauncher releases found!");
aTask.infoAppendln(ErrorMsg.ContactSiteAdmin);
aTask.logRegln("No AppLauncher releases found!");
aTask.logRegln(ErrorMsg.ContactSiteAdmin);
return null;
}
@@ -223,7 +218,7 @@ public class AppLauncherUtils
Version nMaxVer = aJreRelease.getAppLauncherMaxVersion();
AppLauncherRelease pickRelease = null;
for (AppLauncherRelease aRelease : availList)
for (AppLauncherRelease aRelease : availL)
{
Version evalVer = aRelease.getVersion();
if (VersionUtils.isInRange(evalVer, nMinVer, nMaxVer) == false)
@@ -236,8 +231,8 @@ public class AppLauncherUtils
// Bail if no compatible release could be found
if (pickRelease == null)
{
aTask.infoAppendln("No compatible AppLauncher releases have been deployed!");
aTask.infoAppendln(ErrorMsg.ContactSiteAdmin);
aTask.logRegln("No compatible AppLauncher releases have been deployed!");
aTask.logRegln(ErrorMsg.ContactSiteAdmin);
return null;
}
@@ -250,37 +245,18 @@ public class AppLauncherUtils
relLauncherPath = PlatformUtils.getAppLauncherLocation(pickVer);
// Download the AppLauncher
Digest targDigest, testDigest;
MessageDigest msgDigest;
targDigest = pickRelease.getDigest();
msgDigest = DigestUtils.getDigest(targDigest.getType());
aTask.infoAppendln("Downloading AppLauncher... Version: " + pickVer);
Digest targDigest = pickRelease.getDigest();
aTask.logRegln("Downloading AppLauncher... Version: " + pickVer);
URL srcUrl = IoUtil.createURL(updateSiteUrl.toString() + "/launcher/" + pickRelease.getFileName());
File dstFile = new File(aDestPath.getParentFile(), relLauncherPath);
Task tmpTask = new PartialTask(aTask, aTask.getProgress(), 0.01);
// Task tmpTask = new PartialTask(aTask, aTask.getProgress(), (tmpFileLen * 0.75) / (releaseSizeFull + 0.00));
// Task tmpTask = new SilentTask();
if (DistUtils.downloadFile(tmpTask, srcUrl, dstFile, aCredential, fileLen, msgDigest) == false)
{
aTask.infoAppendln("Failed to download updated AppLauncher.");
aTask.infoAppendln("\tSource: " + srcUrl);
aTask.infoAppendln("\tFile: " + dstFile);
if (MiscUtils.download(tmpTask, srcUrl, dstFile, aCredential, fileLen, targDigest) == false)
return null;
}
// Validate that the AppLauncher was downloaded successfully
testDigest = new Digest(targDigest.getType(), msgDigest.digest());
if (targDigest.equals(testDigest) == false)
{
aTask.infoAppendln("The download of the AppLauncher appears to be corrupted.");
aTask.infoAppendln("\tFile: " + dstFile);
aTask.infoAppendln("\t\tExpected " + targDigest.getDescr());
aTask.infoAppendln("\t\tReceived " + testDigest.getDescr());
return null;
}
// Log the success
aTask.infoAppendln("Success updating AppLauncher...");
aTask.logRegln("Success updating AppLauncher...");
return pickRelease;
}

View File

@@ -1,12 +1,14 @@
package distMaker.jre;
import distMaker.digest.Digest;
import distMaker.platform.Architecture;
import distMaker.platform.Platform;
import distMaker.utils.Version;
import glum.digest.Digest;
/**
* Immutable class that describes a JRE Release.
* <P>
* The reference fileName should be a compressed (tar.gz) JRE.
*
* @author lopeznr1
*/
public class JreRelease implements Comparable<JreRelease>
{
@@ -14,22 +16,26 @@ public class JreRelease implements Comparable<JreRelease>
private final Version alMinVer;
private final Version alMaxVer;
private final String archStr;
private final String platStr;
private final Architecture architecture;
private final Platform platform;
private final String fileName;
private final Digest digest;
private final long fileLen;
public JreRelease(String aArchStr, String aPlatStr, JreVersion aVersion, String aFileName, Digest aDigest, long aFileLen, Version aAlMinVer, Version aAlMaxVer)
/**
* Standard Constructor
*/
public JreRelease(Architecture aArchitecture, Platform aPlatform, JreVersion aVersion, String aFileName,
Digest aDigest, long aFileLen, Version aAlMinVer, Version aAlMaxVer)
{
version = aVersion;
alMinVer = aAlMinVer;
alMaxVer = aAlMaxVer;
archStr = aArchStr.toLowerCase();
platStr = aPlatStr.toLowerCase();
architecture = aArchitecture;
platform = aPlatform;
fileName = aFileName;
digest = aDigest;
fileLen = aFileLen;
@@ -69,24 +75,20 @@ public class JreRelease implements Comparable<JreRelease>
/**
* Returns true if the specified system matches the JRE's system.
*
* @param aArchStr
* Architecture of the relevant system. (Ex: x64)
* @param aPlatStr
* Platform of the relevant system. (Ex: linux)
* @return
*
* @param aArchitecture
* {@link Architecture} of the relevant system.
* @param aPlatform
* {@link Platform} of the relevant system.s
*/
public boolean isSystemMatch(String aArchStr, String aPlatStr)
public boolean isSystemMatch(Architecture aArchitecture, Platform aPlatform)
{
aArchStr = aArchStr.toLowerCase();
aPlatStr = aPlatStr.toLowerCase();
// Ensure the architecture matches
if (archStr.equals(aArchStr) == false)
if (architecture != aArchitecture)
return false;
// Ensure the platform matches
if (platStr.equals(aPlatStr) == false)
if (platform != aPlatform)
return false;
return true;
@@ -113,11 +115,11 @@ public class JreRelease implements Comparable<JreRelease>
{
int cmpVal;
cmpVal = archStr.compareTo(aItem.archStr);
cmpVal = architecture.compareTo(aItem.architecture);
if (cmpVal != 0)
return cmpVal;
cmpVal = platStr.compareTo(aItem.platStr);
cmpVal = platform.compareTo(aItem.platform);
if (cmpVal != 0)
return cmpVal;

View File

@@ -1,28 +1,27 @@
package distMaker.jre;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.*;
import distMaker.digest.Digest;
import distMaker.digest.DigestType;
import distMaker.platform.*;
import distMaker.utils.ParseUtils;
import distMaker.utils.PlainVersion;
import glum.gui.GuiUtil;
import glum.digest.Digest;
import glum.digest.DigestType;
import glum.io.IoUtil;
import glum.io.ParseUtil;
import glum.net.Credential;
import glum.net.NetUtil;
import glum.task.Task;
import glum.util.ThreadUtil;
/**
* Collection of utility methods that provide JRE related functionality.
*
* @author lopeznr1
*/
public class JreUtils
{
/**
@@ -50,7 +49,7 @@ public class JreUtils
*/
public static List<JreRelease> getAvailableJreReleases(Task aTask, URL aUpdateSiteUrl, Credential aCredential)
{
List<JreRelease> retList;
List<JreRelease> retL;
URL catUrl;
URLConnection connection;
InputStream inStream;
@@ -58,7 +57,7 @@ public class JreUtils
String errMsg, strLine;
errMsg = null;
retList = new ArrayList<>();
retL = new ArrayList<>();
catUrl = IoUtil.createURL(aUpdateSiteUrl.toString() + "/jre/jreCatalog.txt");
// Default to DigestType of MD5
@@ -110,7 +109,7 @@ public class JreUtils
{
DigestType tmpDigestType = DigestType.parse(tokens[1]);
if (tmpDigestType == null)
aTask.infoAppendln("Failed to locate DigestType for: " + tokens[1]);
aTask.logRegln("Failed to locate DigestType for: " + tokens[1]);
else
digestType = tmpDigestType;
}
@@ -140,71 +139,93 @@ public class JreUtils
continue;
}
aTask.infoAppendln("Unreconized line: " + strLine);
aTask.logRegln("Unreconized line: " + strLine);
}
// Logic to handle the 'F' command: JRE File
else if (tokens[0].equals("F") == true && tokens.length >= 4 && tokens.length <= 6)
{
if (version == null)
{
aTask.infoAppendln("Skipping input: " + strLine);
aTask.infoAppendln("\tJRE version has not been specifed. Missing input line: jre,<jreVersion>");
aTask.logRegln("Skipping input: " + strLine);
aTask.logRegln("\tJRE version has not been specifed. Missing input line: jre,<jreVersion>");
continue;
}
// Parse the JRE release
String archStr, platStr, filename, digestStr;
Architecture architecture;
Platform platform;
String filename, digestStr;
long fileLen;
if (tokens.length == 6)
{
archStr = tokens[1];
platStr = tokens[2];
architecture = ArchitectureUtils.transformToArchitecture(tokens[1]);
if (architecture == null)
{
aTask.logRegln("Skipping input: " + strLine);
aTask.logRegln("\tFailed to determine the target architecture of the JRE.");
continue;
}
platform = PlatformUtils.transformToPlatform(tokens[2]);
if (platform == null)
{
aTask.logRegln("Skipping input: " + strLine);
aTask.logRegln("\tFailed to determine the target platform of the JRE.");
continue;
}
filename = tokens[3];
digestStr = tokens[4];
fileLen = GuiUtil.readLong(tokens[5], -1);
fileLen = ParseUtil.readLong(tokens[5], -1);
}
else if (tokens.length == 5)
{
archStr = "x64";
architecture = Architecture.x64;
digestStr = tokens[1];
fileLen = GuiUtil.readLong(tokens[2], -1);
platStr = tokens[3];
if (platStr.equalsIgnoreCase("apple") == true)
platStr = "macosx";
fileLen = ParseUtil.readLong(tokens[2], -1);
platform = PlatformUtils.transformToPlatform(tokens[3]);
if (platform == null)
{
aTask.logRegln("Skipping input: " + strLine);
aTask.logRegln("\tFailed to determine the target platform of the JRE.");
continue;
}
filename = tokens[4];
}
else // tokens.length == 4
{
archStr = "x64";
architecture = Architecture.x64;
digestStr = tokens[1];
fileLen = GuiUtil.readLong(tokens[2], -1);
fileLen = ParseUtil.readLong(tokens[2], -1);
filename = tokens[3];
platStr = JreUtils.getPlatformOfJreTarGz(filename);
if (platStr == null)
platform = JreUtils.getPlatformOfJreTarGz(filename);
if (platform == null)
{
aTask.infoAppendln("Skipping input: " + strLine);
aTask.infoAppendln("\tFailed to determine the target platform of the JRE.");
aTask.logRegln("Skipping input: " + strLine);
aTask.logRegln("\tFailed to determine the target platform of the JRE.");
continue;
}
}
// Form the JreRelease
Digest tmpDigest = new Digest(digestType, digestStr);
retList.add(new JreRelease(archStr, platStr, version, filename, tmpDigest, fileLen, alMinVer, alMaxVer));
retL.add(new JreRelease(architecture, platform, version, filename, tmpDigest, fileLen, alMinVer, alMaxVer));
}
else
{
aTask.infoAppendln("Unreconized line: " + strLine);
aTask.logRegln("Unreconized line: " + strLine);
}
}
}
catch(FileNotFoundException aExp)
catch (FileNotFoundException aExp)
{
errMsg = "Failed to locate resource: " + catUrl;
}
catch(IOException aExp)
catch (IOException aExp)
{
errMsg = ThreadUtil.getStackTrace(aExp);
}
@@ -217,42 +238,42 @@ public class JreUtils
// See if we are in a valid state
if (errMsg != null)
; // Nothing to do, as an earlier error has occurred
else if (retList.size() == 0)
else if (retL.size() == 0)
errMsg = "The catalog appears to be invalid.";
// Bail if there were issues
if (errMsg != null)
{
aTask.infoAppendln(errMsg);
aTask.logRegln(errMsg);
return null;
}
return retList;
return retL;
}
/**
* Utility method that returns a list of matching JREs. The list will be sorted in order from newest to oldest. All
* returned JREs will have a platform that matches aPlatform.
*/
public static List<JreRelease> getMatchingPlatforms(List<JreRelease> aJreList, String aArchStr, String aPlatStr)
public static List<JreRelease> getMatchingPlatforms(List<JreRelease> aJreList, Architecture aArch, Platform aPlat)
{
List<JreRelease> retList;
List<JreRelease> retL;
// Grab all JREs with a matching platforms
retList = new ArrayList<>();
retL = new ArrayList<>();
for (JreRelease aRelease : aJreList)
{
if (aRelease.isSystemMatch(aArchStr, aPlatStr) == false)
if (aRelease.isSystemMatch(aArch, aPlat) == false)
continue;
retList.add(aRelease);
retL.add(aRelease);
}
// Sort the platforms, but reverse the order so that the newest version is first
Collections.sort(retList);
Collections.reverse(retList);
Collections.sort(retL);
Collections.reverse(retL);
return retList;
return retL;
}
/**
@@ -263,15 +284,15 @@ public class JreUtils
* This method should be considered deprecated as of DistMaker 0.48
*/
@Deprecated
private static String getPlatformOfJreTarGz(String aFileName)
private static Platform getPlatformOfJreTarGz(String aFileName)
{
aFileName = aFileName.toUpperCase();
if (aFileName.contains("LINUX") == true)
return "Linux";
return Platform.Linux;
if (aFileName.contains("MACOSX") == true)
return "Macosx";
return Platform.Macosx;
if (aFileName.contains("WINDOWS") == true)
return "Windows";
return Platform.Windows;
return null;
}

View File

@@ -5,10 +5,12 @@ import java.util.ArrayList;
import com.google.common.collect.ImmutableList;
import distMaker.utils.Version;
import glum.gui.GuiUtil;
import glum.io.ParseUtil;
/**
* Immutable class which defines a Java version.
*
* @author lopeznr1
*/
public class JreVersion implements Comparable<JreVersion>, Version
{
@@ -32,7 +34,7 @@ public class JreVersion implements Comparable<JreVersion>, Version
ArrayList<Integer> workL = new ArrayList<>();
for (String aStr : tokenArr)
{
int tmpVal = GuiUtil.readInt(aStr, Integer.MIN_VALUE);
int tmpVal = ParseUtil.readInt(aStr, Integer.MIN_VALUE);
if (tmpVal == Integer.MIN_VALUE)
break;

View File

@@ -5,10 +5,13 @@ import java.util.*;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import distMaker.jre.*;
import distMaker.jre.JreRelease;
import distMaker.jre.JreVersion;
/**
* Object that describes the structure (files, folders, and JRE version) of a Java application.
*
* @author lopeznr1
*/
public class AppCatalog
{
@@ -19,27 +22,28 @@ public class AppCatalog
private JreVersion maxJreVer;
/** A mapping of filename to to corresponding Node */
private ImmutableMap<String, Node> nodeMap;
private ImmutableMap<String, Node> nodeM;
public AppCatalog(List<Node> aNodeList, JreVersion aMinJreVer, JreVersion aMaxJreVer)
public AppCatalog(List<Node> aNodeL, JreVersion aMinJreVer, JreVersion aMaxJreVer)
{
minJreVer = aMinJreVer;
maxJreVer = aMaxJreVer;
nodeMap = ImmutableMap.copyOf(formNameMap(aNodeList));
nodeM = ImmutableMap.copyOf(formNameMap(aNodeL));
}
/**
* Returns the most recent JRE from the specified release that is compatible with this Appcatalog.
* Returns the most recent {@link JreRelease} from the specified list that is compatible with this
* {@link AppCatalog}.
* <P>
* Returns null if there are no JREs that are compatible.
* Returns null if there are no {@link JreRelease} that is compatible.
*/
public JreRelease getCompatibleJre(List<JreRelease> aJreList)
public JreRelease getCompatibleJre(List<JreRelease> aJreL)
{
// Sort the platforms, but reverse the order so that the newest version is first
Collections.sort(aJreList);
Collections.reverse(aJreList);
Collections.sort(aJreL);
Collections.reverse(aJreL);
for (JreRelease aRelease : aJreList)
for (JreRelease aRelease : aJreL)
{
if (isJreVersionTooNew(aRelease.getVersion()) == true)
continue;
@@ -112,7 +116,7 @@ public class AppCatalog
*/
public Node getNode(String aName)
{
return nodeMap.get(aName);
return nodeM.get(aName);
}
/**
@@ -120,7 +124,7 @@ public class AppCatalog
*/
public ImmutableList<Node> getAllNodesList()
{
return nodeMap.values().asList();
return nodeM.values().asList();
}
/**
@@ -129,15 +133,15 @@ public class AppCatalog
* TODO: This should be renamed formNameMap to formDigestMap<BR>
* TODO: This should probably be a mapping of Digest to Node rather than filename to Node
*/
private Map<String, Node> formNameMap(List<Node> aNodeList)
private Map<String, Node> formNameMap(List<Node> aNodeL)
{
Map<String, Node> retMap;
Map<String, Node> retM;
retMap = new LinkedHashMap<>();
for (Node aNode : aNodeList)
retMap.put(aNode.getFileName(), aNode);
retM = new LinkedHashMap<>();
for (Node aNode : aNodeL)
retM.put(aNode.getFileName(), aNode);
return retMap;
return retM;
}
}

View File

@@ -1,19 +1,18 @@
package distMaker.node;
import glum.io.IoUtil;
import glum.net.Credential;
import glum.task.Task;
import java.io.File;
import java.net.URL;
import java.security.MessageDigest;
import distMaker.DistUtils;
import distMaker.digest.Digest;
import distMaker.digest.DigestUtils;
import glum.digest.Digest;
import glum.io.IoUtil;
import glum.net.Credential;
import glum.net.NetUtil;
import glum.task.Task;
/**
* Immutable node describing a File.
*
* @author lopeznr1
*/
public class FileNode implements Node
{
@@ -38,7 +37,7 @@ public class FileNode implements Node
if (aNode instanceof FileNode == false)
return false;
fNode = (FileNode)aNode;
fNode = (FileNode) aNode;
if (fNode.digest.equals(digest) == false)
return false;
if (fNode.fileName.equals(fileName) == false)
@@ -66,34 +65,16 @@ public class FileNode implements Node
@Override
public boolean transferContentTo(Task aTask, Credential aCredential, File dstPath)
{
URL srcUrl;
File dstFile;
Digest tmpDigest;
boolean isPass;
// Determine the source URL to copy the contents from
srcUrl = IoUtil.createURL(rootUrl.toString() + "/" + fileName);
URL srcUrl = IoUtil.createURL(rootUrl.toString() + "/" + fileName);
// Determine the file to transfer the contents to
dstFile = new File(dstPath, fileName);
File dstFile = new File(dstPath, fileName);
// Download the file
MessageDigest msgDigest = DigestUtils.getDigest(digest.getType());
isPass = DistUtils.downloadFile(aTask, srcUrl, dstFile, aCredential, fileLen, msgDigest);
if (isPass == false)
if (NetUtil.download(aTask, srcUrl, dstFile, aCredential, fileLen, digest) == false)
return false;
// Validate that the file was downloaded successfully
tmpDigest = new Digest(digest.getType(), msgDigest.digest());
if (digest.equals(tmpDigest) == false)
{
aTask.infoAppendln("\nThe download of the application appears to be corrupted.");
aTask.infoAppendln("\tFile: " + fileName);
aTask.infoAppendln("\t\tExpected " + digest.getDescr());
aTask.infoAppendln("\t\tRecieved " + tmpDigest.getDescr() + "\n");
return false;
}
return true;
}
}

View File

@@ -18,7 +18,9 @@ import distMaker.*;
import distMaker.jre.*;
/**
* Utility class which contains a set of methods to interact with an Apple Info.plist file.
* Collection of utility methods specific to the Macosx platform.
*
* @author lopeznr1
*/
public class AppleUtils
{
@@ -65,7 +67,7 @@ public class AppleUtils
{
Document doc;
Element docElement;
NodeList nodeList;
NodeList nodeL;
Node keyNode, strNode;
String valStr;
@@ -87,10 +89,10 @@ public class AppleUtils
throw new ErrorDM(aExp, "Failed to parse XML document. File: " + pFile);
}
nodeList = docElement.getElementsByTagName("*");
for (int c1 = 0; c1 < nodeList.getLength(); c1++)
nodeL = docElement.getElementsByTagName("*");
for (int c1 = 0; c1 < nodeL.getLength(); c1++)
{
keyNode = nodeList.item(c1).getFirstChild();
keyNode = nodeL.item(c1).getFirstChild();
if (keyNode == null)
continue;
@@ -102,7 +104,7 @@ public class AppleUtils
{
System.out.println("Updating contents of file: " + pFile);
strNode = nodeList.item(c1 + 1).getFirstChild();
strNode = nodeL.item(c1 + 1).getFirstChild();
System.out.println(" Old App Version: " + strNode.getNodeValue());
strNode.setNodeValue(aNewVersin);
@@ -145,7 +147,7 @@ public class AppleUtils
// Pattern tmpPattern = Pattern.compile(regex);
//
// // Process our input
// inputList = new ArrayList<>();
// inputL = new ArrayList<>();
// try (BufferedReader br = MiscUtils.openFileAsBufferedReader(pFile))
// {
// // Read the lines
@@ -173,7 +175,7 @@ public class AppleUtils
// isFound = true;
// }
//
// inputList.add(evalStr);
// inputL.add(evalStr);
// }
// }
// catch(IOException aExp)
@@ -196,7 +198,7 @@ public class AppleUtils
*/
public static void updateJreVersion(JreVersion aJreVersion, File pFile)
{
List<String> inputList;
List<String> inputL;
String evalStr, tmpStr;
String prevKeyValue;
boolean isFound;
@@ -211,7 +213,7 @@ public class AppleUtils
// Process our input
isFound = false;
inputList = new ArrayList<>();
inputL = new ArrayList<>();
try (BufferedReader br = MiscUtils.openFileAsBufferedReader(pFile))
{
// Read the lines
@@ -237,7 +239,7 @@ public class AppleUtils
isFound = true;
}
inputList.add(evalStr);
inputL.add(evalStr);
}
}
catch(IOException aExp)
@@ -250,7 +252,7 @@ public class AppleUtils
throw new ErrorDM("[" + pFile + "] The pFile does not specify a 'JVMRuntime' section.");
// Write the pFile
MiscUtils.writeDoc(pFile, inputList);
MiscUtils.writeDoc(pFile, inputL);
}
/**
@@ -267,7 +269,7 @@ public class AppleUtils
Document doc;
Element docElement;
String evalStr, updateStr;
NodeList dictList, childList;
NodeList dictNL, childNL;
Node childNode, targNode;
Element evalE, arrE, memE;
String tagStr, valStr, currKeyVal;
@@ -292,16 +294,16 @@ public class AppleUtils
}
// Locate the <dict> element
dictList = docElement.getElementsByTagName("dict");
if (dictList.getLength() == 0)
dictNL = docElement.getElementsByTagName("dict");
if (dictNL.getLength() == 0)
throw new ErrorDM("No <dict> element found! File: " + pFile);
arrE = null;
currKeyVal = null;
childList = dictList.item(0).getChildNodes();
for (int c1 = 0; c1 < childList.getLength(); c1++)
childNL = dictNL.item(0).getChildNodes();
for (int c1 = 0; c1 < childNL.getLength(); c1++)
{
childNode = childList.item(c1);
childNode = childNL.item(c1);
if (childNode.getNodeType() != Node.ELEMENT_NODE)
continue;
@@ -332,10 +334,10 @@ public class AppleUtils
throw new ErrorDM("Failed to locate the element <array> following the element: <key>JVMOptions</key>\nFile: " + pFile);
memE = null;
childList = arrE.getChildNodes();
for (int c1 = 0; c1 < childList.getLength(); c1++)
childNL = arrE.getChildNodes();
for (int c1 = 0; c1 < childNL.getLength(); c1++)
{
childNode = childList.item(c1);
childNode = childNL.item(c1);
if (childNode.getNodeType() != Node.ELEMENT_NODE)
continue;
@@ -391,7 +393,7 @@ public class AppleUtils
* <LI>http://java9.wtf/xml-transformer/
* <LI>https://stackoverflow.com/questions/12669686/how-to-remove-extra-empty-lines-from-xml-file
* </UL>
*
*
* @param aDoc
* @throws XPathExpressionException
*/

View File

@@ -0,0 +1,12 @@
package distMaker.platform;
/**
* Enum which defines the supported architecture types.
*
* @author lopeznr1
*/
public enum Architecture
{
x64,
}

View File

@@ -0,0 +1,42 @@
package distMaker.platform;
/**
* Collection of utility methods that provide a mechanism for the following:
* <UL>
* <LI>Retrieval of the system {@link Architecture}.
* <LI>Transformation of a architecture string into the corresponding {@link Architecture}.
* </UL>
* Note that setting of system parameters will not take effect until the DistMaker application is restarted.
*
* @author lopeznr1
*/
public class ArchitectureUtils
{
/**
* Returns the architecture the current JRE is running on.
* <P>
* This always returns x64.
* <P>
* TODO: In the future update the code to return the architecture rather than assume x64!
*/
public static Architecture getArchitecture()
{
return Architecture.x64;
}
/**
* Utility method that takes a string and will transform it to the corresponding {@link Architecture}.
* <P>
* Returns null if the architecture could not be determined.
*/
public static Architecture transformToArchitecture(String aInputStr)
{
aInputStr = aInputStr.toLowerCase();
if (aInputStr.equals("x64") == true)
return Architecture.x64;
return null;
}
}

View File

@@ -9,6 +9,11 @@ import java.util.regex.Pattern;
import distMaker.*;
import distMaker.jre.*;
/**
* Collection of utility methods specific to the Linux platform.
*
* @author lopeznr1
*/
public class LinuxUtils
{
/**
@@ -60,7 +65,7 @@ public class LinuxUtils
*/
public static void updateAppLauncher(AppLauncherRelease aRelease, File aScriptFile)
{
List<String> inputList;
List<String> inputL;
String evalStr, tmpStr;
boolean isFound;
@@ -73,7 +78,7 @@ public class LinuxUtils
// Process our input
isFound = false;
inputList = new ArrayList<>();
inputL = new ArrayList<>();
try (BufferedReader br = MiscUtils.openFileAsBufferedReader(aScriptFile))
{
// Read the lines
@@ -96,7 +101,7 @@ public class LinuxUtils
isFound = true;
}
inputList.add(evalStr);
inputL.add(evalStr);
}
}
catch(IOException aExp)
@@ -109,7 +114,7 @@ public class LinuxUtils
throw new ErrorDM("[" + aScriptFile + "] The script does not specify a valid class path.");
// Write the scriptFile
MiscUtils.writeDoc(aScriptFile, inputList);
MiscUtils.writeDoc(aScriptFile, inputL);
}
/**
@@ -119,7 +124,7 @@ public class LinuxUtils
*/
public static void updateJreVersion(JreVersion aJreVersion, File aScriptFile)
{
List<String> inputList;
List<String> inputL;
String evalStr, tmpStr;
boolean isFound;
@@ -129,7 +134,7 @@ public class LinuxUtils
// Process our input
isFound = false;
inputList = new ArrayList<>();
inputL = new ArrayList<>();
try (BufferedReader br = MiscUtils.openFileAsBufferedReader(aScriptFile))
{
// Read the lines
@@ -147,7 +152,7 @@ public class LinuxUtils
evalStr = "javaExe=../" + JreUtils.getExpandJrePath(aJreVersion) + "/bin/java";
}
inputList.add(evalStr);
inputL.add(evalStr);
}
}
catch(IOException aExp)
@@ -160,7 +165,7 @@ public class LinuxUtils
throw new ErrorDM("[" + aScriptFile + "] The script does not specify a valid JRE path.");
// Write the scriptFile
MiscUtils.writeDoc(aScriptFile, inputList);
MiscUtils.writeDoc(aScriptFile, inputL);
}
/**
@@ -174,9 +179,9 @@ public class LinuxUtils
* <P>
* On failure this method will throw an exception of type ErrorDM.
*/
public static void updateMaxMem(long numBytes, File aScriptFile)
public static void updateMaxMem(long aNumBytes, File aScriptFile)
{
List<String> inputList;
List<String> inputL;
String evalStr, memStr, tmpStr;
int currLineNum, injectLineNum, targLineNum;
@@ -185,7 +190,7 @@ public class LinuxUtils
throw new ErrorDM("The script file is not writeable: " + aScriptFile);
// Process our input
inputList = new ArrayList<>();
inputL = new ArrayList<>();
try (BufferedReader br = MiscUtils.openFileAsBufferedReader(aScriptFile))
{
// Read the lines
@@ -205,7 +210,7 @@ public class LinuxUtils
else if (tmpStr.startsWith("maxMem=") == true)
targLineNum = currLineNum;
inputList.add(evalStr);
inputL.add(evalStr);
currLineNum++;
}
}
@@ -215,24 +220,24 @@ public class LinuxUtils
}
// Determine the memStr to use
if (numBytes % MemUtils.GB_SIZE == 0)
memStr = "" + (numBytes / MemUtils.GB_SIZE) + "g";
if (aNumBytes % MemUtils.GB_SIZE == 0)
memStr = "" + (aNumBytes / MemUtils.GB_SIZE) + "g";
else
memStr = "" + (numBytes / MemUtils.MB_SIZE) + "m";
memStr = "" + (aNumBytes / MemUtils.MB_SIZE) + "m";
// Insert our changes into the script
if (targLineNum != -1)
inputList.set(targLineNum, "maxMem=" + memStr);
inputL.set(targLineNum, "maxMem=" + memStr);
else if (injectLineNum != -1 && injectLineNum < currLineNum)
inputList.add(injectLineNum + 1, "maxMem=" + memStr);
inputL.add(injectLineNum + 1, "maxMem=" + memStr);
else
{
inputList.add(0, "# Define the maximum memory to allow the application to utilize");
inputList.add(1, "maxMem=" + memStr + "\n");
inputL.add(0, "# Define the maximum memory to allow the application to utilize");
inputL.add(1, "maxMem=" + memStr + "\n");
}
// Write the scriptFile
MiscUtils.writeDoc(aScriptFile, inputList);
MiscUtils.writeDoc(aScriptFile, inputL);
}
}

View File

@@ -0,0 +1,16 @@
package distMaker.platform;
/**
* Enum which defines the supported platform types.
*
* @author lopeznr1
*/
public enum Platform
{
Linux,
Macosx,
Windows,
}

View File

@@ -7,29 +7,23 @@ import distMaker.jre.*;
import distMaker.node.AppRelease;
import distMaker.utils.Version;
/**
* Collection of utility methods that provide platform independent mechanism for the following:
* <UL>
* <LI>Retrieval of the DistMaker configuration file
* <LI>Retrieval of the file name of the app launcher.
* <LI>Retrieval of the location of the app launcher.
* <LI>Retrieval / Setting of the JRE location.
* <LI>Retrieval of the system {@link Platform}.
* <LI>Setting of the heap memory.
* <LI>Transformation of a platform string into the corresponding {@link Platform}.
* </UL>
* Note that setting of system parameters will not take effect until the DistMaker application is restarted.
*
* @author lopeznr1
*/
public class PlatformUtils
{
/**
* Utility method that returns the platform specific configuration file for the java application.
*/
public static File getConfigurationFile()
{
File cfgFile;
String platform;
platform = PlatformUtils.getPlatform().toUpperCase();
if (platform.equals("APPLE") == true)
cfgFile = AppleUtils.getPlistFile();
else if (platform.equals("LINUX") == true)
cfgFile = LinuxUtils.getScriptFile();
else if (platform.equals("WINDOWS") == true)
cfgFile = WindowsUtils.getConfigFile();
else
throw new ErrorDM("Unsupported platform: " + platform);
return cfgFile;
}
/**
* Returns the file name that should be used for a specific AppLauncher version.
* <P>
@@ -51,25 +45,47 @@ public class PlatformUtils
* <P>
* The returned path will be relative to the top of the application's DistMaker root rather than the applications
* Java run path.
* <P>
* On failure this method will throw an exception of type {@link ErrorDM}.
*/
public static String getAppLauncherLocation(Version aVersion)
{
String platform, tmpPathName, retPath;
Platform platform;
String tmpPathName;
retPath = null;
tmpPathName = getAppLauncherFileName(aVersion);
platform = PlatformUtils.getPlatform().toUpperCase();
if (platform.equals("APPLE") == true)
retPath = "Java/" + tmpPathName;
else if (platform.equals("LINUX") == true)
retPath = "launcher/" + tmpPathName;
else if (platform.equals("WINDOWS") == true)
retPath = "launcher/" + tmpPathName;
else
throw new ErrorDM("Unsupported platform: " + platform);
// Delegate to the proper util class
platform = PlatformUtils.getPlatform();
if (platform == Platform.Linux)
return "launcher/" + tmpPathName;
else if (platform == Platform.Macosx)
return "Java/" + tmpPathName;
else if (platform == Platform.Windows)
return "launcher/" + tmpPathName;
return retPath;
throw new ErrorDM("Unsupported platform: " + platform);
}
/**
* Utility method that returns the platform specific configuration file for the java application.
* <P>
* On failure this method will throw an exception of type {@link ErrorDM}.
*/
public static File getConfigurationFile()
{
Platform platform;
// Delegate to the proper util class
platform = PlatformUtils.getPlatform();
if (platform == Platform.Linux)
return LinuxUtils.getScriptFile();
else if (platform == Platform.Macosx)
return AppleUtils.getPlistFile();
else if (platform == Platform.Windows)
return WindowsUtils.getConfigFile();
throw new ErrorDM("Unsupported platform: " + platform);
}
/**
@@ -77,56 +93,42 @@ public class PlatformUtils
* <P>
* The returned path will be relative to the top of the application's DistMaker root rather than the applications
* Java run path.
* <P>
* On failure this method will throw an exception of type {@link ErrorDM}.
*/
public static String getJreLocation(JreVersion aJreVersion)
{
String platform, tmpPathName, retPath;
Platform platform;
String tmpPathName;
retPath = null;
tmpPathName = JreUtils.getExpandJrePath(aJreVersion);
platform = PlatformUtils.getPlatform().toUpperCase();
if (platform.equals("APPLE") == true)
retPath = "PlugIns/" + tmpPathName;
else if (platform.equals("LINUX") == true)
retPath = tmpPathName;
else if (platform.equals("WINDOWS") == true)
retPath = tmpPathName;
else
throw new ErrorDM("Unsupported platform: " + platform);
// Delegate to the proper util class
platform = PlatformUtils.getPlatform();
if (platform == Platform.Linux)
return tmpPathName;
else if (platform == Platform.Macosx)
return "PlugIns/" + tmpPathName;
else if (platform == Platform.Windows)
return tmpPathName;
return retPath;
throw new ErrorDM("Unsupported platform: " + platform);
}
/**
* Returns the architecture the current JRE is running on.
* <P>
* This always returns x64.
* <P>
* TODO: In the future update the code to return the architecture rather than assume x64!
*/
public static String getArchitecture()
{
// TODO: In the future update the code to return the architecture rather than assume x64!
return "x64";
}
/**
* Returns the platform (Linux, Macosx, or Windows) on which the current JRE is running on.
* Returns the {@link Platform} on which the current JRE is running on.
* <P>
* If the platform is not recognized the a {@link ErrorDM} will be thrown.
*/
public static String getPlatform()
public static Platform getPlatform()
{
String osName;
osName = System.getProperty("os.name").toUpperCase();
String osName = System.getProperty("os.name").toUpperCase();
if (osName.startsWith("LINUX") == true)
return "Linux";
return Platform.Linux;
else if (osName.startsWith("MAC OS X") == true)
return "Macosx";
return Platform.Macosx;
else if (osName.startsWith("WINDOWS") == true)
return "Windows";
return Platform.Windows;
throw new ErrorDM("Unrecognized os.name: " + osName);
}
@@ -136,26 +138,26 @@ public class PlatformUtils
* <P>
* Note this will only take effect after the application has been restarted.
* <P>
* On failure this method will throw an exception of type ErrorDM.
*
* On failure this method will throw an exception of type {@link ErrorDM}.
*
* @param aRelease
* The AppLauncher release that will be utilized.
*/
public static void setAppLauncher(AppLauncherRelease aRelease)
{
String platform;
Platform platform;
File cfgFile;
// Retrieve the appropriate configuration file
cfgFile = PlatformUtils.getConfigurationFile();
// Delegate to the proper platform code
platform = PlatformUtils.getPlatform().toUpperCase();
if (platform.equals("APPLE") == true)
AppleUtils.updateAppLauncher(aRelease, cfgFile);
else if (platform.equals("LINUX") == true)
// Delegate to the proper util class
platform = PlatformUtils.getPlatform();
if (platform == Platform.Linux)
LinuxUtils.updateAppLauncher(aRelease, cfgFile);
else if (platform.equals("WINDOWS") == true)
else if (platform == Platform.Macosx)
AppleUtils.updateAppLauncher(aRelease, cfgFile);
else if (platform == Platform.Windows)
WindowsUtils.updateAppLauncher(aRelease, cfgFile);
else
throw new ErrorDM("Unrecognized platform: " + platform);
@@ -166,26 +168,26 @@ public class PlatformUtils
* <P>
* Note this will only take effect after the application has been restarted.
* <P>
* On failure this method will throw an exception of type ErrorDM.
*
* On failure this method will throw an exception of type {@link ErrorDM}.
*
* @param aJrePath
* Path to top of the JRE.
*/
public static void setJreVersion(JreVersion aJreVersion)
{
String platform;
Platform platform;
File cfgFile;
// Retrieve the appropriate configuration file
cfgFile = PlatformUtils.getConfigurationFile();
// Delegate to the proper platform code
platform = PlatformUtils.getPlatform().toUpperCase();
if (platform.equals("APPLE") == true)
AppleUtils.updateJreVersion(aJreVersion, cfgFile);
else if (platform.equals("LINUX") == true)
// Delegate to the proper util class
platform = PlatformUtils.getPlatform();
if (platform == Platform.Linux)
LinuxUtils.updateJreVersion(aJreVersion, cfgFile);
else if (platform.equals("WINDOWS") == true)
else if (platform == Platform.Macosx)
AppleUtils.updateJreVersion(aJreVersion, cfgFile);
else if (platform == Platform.Windows)
WindowsUtils.updateJreVersion(aJreVersion, cfgFile);
else
throw new ErrorDM("Unrecognized platform: " + platform);
@@ -196,31 +198,55 @@ public class PlatformUtils
* <P>
* Note this will only take effect after the application has been restarted.
* <P>
* On failure this method will throw an exception of type ErrorDM.
*
* On failure this method will throw an exception of type {@link ErrorDM}.
*
* @param maxMemSize
* Maximum heap memory in bytes.
*/
public static void setMaxHeapMem(long maxMemSize)
{
String platform;
Platform platform;
File cfgFile;
// Retrieve the appropriate configuration file
cfgFile = PlatformUtils.getConfigurationFile();
// Delegate to the proper platform code
platform = PlatformUtils.getPlatform().toUpperCase();
if (platform.equals("APPLE") == true)
AppleUtils.updateMaxMem(maxMemSize, cfgFile);
else if (platform.equals("LINUX") == true)
// Delegate to the proper util class
platform = PlatformUtils.getPlatform();
if (platform == Platform.Linux)
LinuxUtils.updateMaxMem(maxMemSize, cfgFile);
else if (platform.equals("WINDOWS") == true)
else if (platform == Platform.Macosx)
AppleUtils.updateMaxMem(maxMemSize, cfgFile);
else if (platform == Platform.Windows)
WindowsUtils.updateMaxMem(maxMemSize, cfgFile);
else
throw new ErrorDM(null, "Unrecognized platform: " + platform, "Unsupported Platform");
}
/**
* Utility method that takes a string and will transform it to the corresponding {@link Platform}.
* <P>
* Returns null if the platform could not be determined.
*/
public static Platform transformToPlatform(String aInputStr)
{
aInputStr = aInputStr.toLowerCase();
if (aInputStr.equals("linux") == true)
return Platform.Linux;
if (aInputStr.equals("macosx") == true)
return Platform.Macosx;
if (aInputStr.equals("apple") == true)
return Platform.Macosx;
if (aInputStr.equals("windows") == true)
return Platform.Windows;
return null;
}
/**
* Utility method to update the (active) DistMaker distribution to reflect the specified AppRelease.
* <P>
@@ -230,15 +256,15 @@ public class PlatformUtils
*/
public static void updateAppRelease(AppRelease aRelease)
{
String platform;
Platform platform;
File cfgFile;
// Retrieve the appropriate configuration file
cfgFile = PlatformUtils.getConfigurationFile();
// Delegate to the proper platform code
platform = getPlatform().toUpperCase();
if (platform.equals("APPLE") == true)
// Delegate to the proper util class
platform = getPlatform();
if (platform == Platform.Macosx)
AppleUtils.updateAppVersion(aRelease.getVersion(), cfgFile);
}

View File

@@ -8,6 +8,11 @@ import distMaker.*;
import distMaker.jre.AppLauncherRelease;
import distMaker.jre.JreVersion;
/**
* Collection of utility methods specific to the Windows platform.
*
* @author lopeznr1
*/
public class WindowsUtils
{
/**
@@ -99,7 +104,7 @@ public class WindowsUtils
*/
public static void updateMaxMem(long numBytes, File aConfigFile)
{
List<String> inputList;
List<String> inputL;
String strLine, updateStr;
boolean isProcessed;
@@ -108,7 +113,7 @@ public class WindowsUtils
throw new ErrorDM("The config file is not writeable: " + aConfigFile);
isProcessed = false;
inputList = new ArrayList<>();
inputL = new ArrayList<>();
// Process our input
try (BufferedReader br = MiscUtils.openFileAsBufferedReader(aConfigFile))
@@ -127,15 +132,15 @@ public class WindowsUtils
strLine = updateStr;
}
inputList.add(strLine);
inputL.add(strLine);
}
// Create a new max heap input config line if one is not specified
if (isProcessed == false)
{
strLine = MemUtils.transformMaxMemHeapString("-Xmx256m", numBytes);
inputList.add(strLine);
inputList.add("\n");
inputL.add(strLine);
inputL.add("\n");
isProcessed = true;
}
}
@@ -145,7 +150,7 @@ public class WindowsUtils
}
// Update the script
MiscUtils.writeDoc(aConfigFile, inputList);
MiscUtils.writeDoc(aConfigFile, inputL);
}
}

View File

@@ -2,6 +2,8 @@ package distMaker.utils;
/**
* Provides the standard implementation of the Version interface.
*
* @author lopeznr1
*/
public class PlainVersion implements Version
{

View File

@@ -8,6 +8,8 @@ package distMaker.utils;
* Reference: https://semver.org/
* <P>
* Implementors of this interface should be immutable.
*
* @author lopeznr1
*/
public interface Version
{

View File

@@ -5,6 +5,8 @@ package distMaker.utils;
* <P>
* Eventually when Java allows operator overloading then this class can go away since the standard mathematical
* comparison symbols would be much clearer.
*
* @author lopeznr1
*/
public class VersionUtils
{

View File

@@ -84,7 +84,7 @@ public class MainApp
try (FileZinStream iStream = new FileZinStream(aFile))
{
byte[] byteArr;
List<BlockDir> blockDirList;
List<BlockDir> blockDirL;
String dmgMagicKey;
int fileMagicKey;
int allocBlockOffset1, allocBlockOffset2, allocBlockSize;
@@ -134,7 +134,7 @@ int blockAddrArr[];
int blkLen, blkPos;
blkLen = 1 << (blockAddrArr[c1] & 0x1F);
blkPos = (blockAddrArr[c1] >> 5) * 32;
refTask.infoAppendln("BlockAddr[" + c1 + "] -> Size: " + blkLen + " Offset: " + blkPos);
refTask.logRegln("BlockAddr[" + c1 + "] -> Size: " + blkLen + " Offset: " + blkPos);
//The entries in the block address table are what I call block addresses. Each address is a packed offset+size.
//The least-significant 5 bits of the number indicate the block's size, as a power of 2 (from 2^5 to 2^31). If those bits are masked off, the result
@@ -153,23 +153,23 @@ refTask.infoAppendln("BlockAddr[" + c1 + "] -> Size: " + blkLen + " Offset: " +
// Read the block directories
dirCnt = dataBuf.getInt();
refTask.infoAppendln("Block directory count: " + dirCnt);
refTask.logRegln("Block directory count: " + dirCnt);
blockDirList = new ArrayList<>(dirCnt);
blockDirL = new ArrayList<>(dirCnt);
for (int c1 = 0; c1 < dirCnt; c1++)
blockDirList.add(new BlockDir(dataBuf));
blockDirL.add(new BlockDir(dataBuf));
// Read the free lists
int freeCnt;
refTask.infoAppendln("Reading freelists...");
refTask.logRegln("Reading freelists...");
for (int c1 = 0; c1 < 32; c1++)
{
freeCnt = dataBuf.getInt();
refTask.infoAppend("[" + c1 + "]: " + freeCnt + " Offsets: ");
refTask.logReg("[" + c1 + "]: " + freeCnt + " Offsets: ");
for (int c2 = 0; c2 < freeCnt; c2++)
refTask.infoAppend(dataBuf.getInt() + ",");
refTask.infoAppendln("");
refTask.logReg(dataBuf.getInt() + ",");
refTask.logRegln("");
}
@@ -203,7 +203,7 @@ refTask.infoAppendln("Reading freelists...");
public void readRecords(ByteBuffer aBuf)
{
List<Record> recordList;
List<Record> recordL;
BKGDRecord bkgdRecord;
Record tmpRecord;
int pCode, numRecords;
@@ -216,7 +216,7 @@ refTask.infoAppendln("Reading freelists...");
numRecords = aBuf.getInt();
bkgdRecord = null;
recordList = new ArrayList<>(numRecords);
recordL = new ArrayList<>(numRecords);
for (int c1 = 0; c1 < numRecords; c1++)
{
BufUtils.seek(aBuf, 2); // empty
@@ -250,9 +250,9 @@ refTask.infoAppendln("Reading freelists...");
tmpRecord = new ShorRecord(name, id, type);
tmpRecord.readPayload(aBuf);
recordList.add(tmpRecord);
recordL.add(tmpRecord);
refTask.infoAppendln("Found Name: <" + name + "> recordId: " + id + " dataType: " + type + " payloadSize: " + tmpRecord.getSize());
refTask.logRegln("Found Name: <" + name + "> recordId: " + id + " dataType: " + type + " payloadSize: " + tmpRecord.getSize());
}
@@ -260,7 +260,7 @@ refTask.infoAppendln("Reading freelists...");
// Update the records to reflect the new volumeName
if (volumeName != null)
{
for (Record aRecord : recordList)
for (Record aRecord : recordL)
{
if (aRecord instanceof PictRecord)
((PictRecord)aRecord).getAliasRecord().setVolumeName(volumeName);
@@ -273,7 +273,7 @@ refTask.infoAppendln("Reading freelists...");
}
// Sort the list alphabetically
Collections.sort(recordList);
Collections.sort(recordL);
// Output back to the ByteBuf
@@ -282,7 +282,7 @@ refTask.infoAppendln("Reading freelists...");
aBuf.putInt(pCode);
aBuf.putInt(numRecords);
for (Record aRecord : recordList)
for (Record aRecord : recordL)
{
aBuf.putShort((short)0);
aRecord.writeHeader(aBuf);
@@ -316,11 +316,11 @@ refTask.infoAppendln("Reading freelists...");
numNodes = srcBuf.getInt();
valConst = srcBuf.getInt();
refTask.infoAppendln("rootBlockNum: " + rootBlockNum);
refTask.infoAppendln("numLevels: " + numLevels);
refTask.infoAppendln("rootRecords: " + numRecords);
refTask.infoAppendln("rootNodes: " + numNodes);
refTask.infoAppendln("valConst: " + valConst);
refTask.logRegln("rootBlockNum: " + rootBlockNum);
refTask.logRegln("numLevels: " + numLevels);
refTask.logRegln("rootRecords: " + numRecords);
refTask.logRegln("rootNodes: " + numNodes);
refTask.logRegln("valConst: " + valConst);
}