Source code
/*
* Copyright 2004 Francois Guillet
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*/
package artofillusion.spmanager;
import artofillusion.*;
import artofillusion.ui.Translate;
import artofillusion.ui.UIUtilities;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import buoy.widget.*;
import buoy.event.*;
//import artofillusion.ModellingApp;
import java.io.*;
import java.util.*;
import java.util.zip.*;
import java.net.*;
import java.text.*;
/**
* Description of the Class
*
*@author pims
*@created 20 mars 2004
*/
public class InstallSplitPane extends SPMSplitPane
{
private URL repository;
private BButton installAllButton, installSingleButton, selectAllButton;
private BCheckBox selectCB;
private boolean setup = false;
private boolean unknownHost = false;
private StatusDialog status;
private long downloadedLength = 0;
private long lengthToDownload;
private boolean isDownloading;
private SPMObjectInfo installNodeInfo;
protected ArrayList errors=null;
/**
* Constructor for the InstallSplitPane object
*
*@param workMode Description of the Parameter
*@param repository Description of the Parameter
*/
public InstallSplitPane( short workMode, URL repository )
{
super( ( workMode == INSTALL ? "installScriptsPlugins" : "updateScriptsPlugins" ), workMode );
fs = new HttpSPMFileSystem( repository );
initialize();
}
/**
* Constructor for the InstallSplitPane object
*
*@param workMode Description of the Parameter
*@param fs Description of the Parameter
*/
public InstallSplitPane( short workMode, SPMFileSystem fs )
{
super( ( workMode == INSTALL ? "installScriptsPlugins" : "updateScriptsPlugins" ), workMode );
this.fs = fs;
initialize();
}
/**
* Description of the Method
*/
private void initialize()
{
//initialise buttons
LayoutInfo layout = new LayoutInfo( LayoutInfo.CENTER, LayoutInfo.NONE, new Insets( 0, 5, 0, 5 ), new Dimension( 0, 0 ) );
if ( workMode == UPDATE )
{
buttonRow.add( installAllButton = SPMTranslate.bButton( "updateAllSelected", this, "doInstallAll" ), layout );
installAllButton.setIcon( new ImageIcon( getClass().getResource( "/artofillusion/spmanager/icons/Refresh16.gif" ) ) );
//buttonRow.add( installSingleButton = SPMTranslate.bButton( "updateSingle", this, "doInstallSingle" ), layout );
//installSingleButton.setIcon( new ImageIcon( getClass().getResource( "/artofillusion/spmanager/icons/Refresh16.gif" ) ) );
buttonRow.add( selectAllButton = SPMTranslate.bButton( "selectAll", this, "doSelectAll" ), layout );
//selectAllButton.setIcon( new ImageIcon( getClass().getResource( "/artofillusion/spmanager/icons/Refresh16.gif" ) ) );
}
else
{
buttonRow.add( installAllButton = SPMTranslate.bButton( "installAllSelected", this, "doInstallAll" ), layout );
installAllButton.setIcon( new ImageIcon( getClass().getResource( "/artofillusion/spmanager/icons/Import16.gif" ) ) );
//buttonRow.add( installSingleButton = SPMTranslate.bButton( "installSingle", this, "doInstallSingle" ), layout );
//installSingleButton.setIcon( new ImageIcon( getClass().getResource( "/artofillusion/spmanager/icons/Import16.gif" ) ) );
buttonRow.add( selectAllButton = SPMTranslate.bButton( "selectAll", this, "doSelectAll" ), layout );
//selectAllButton.setIcon( new ImageIcon( getClass().getResource( "/artofillusion/spmanager/icons/Import16.gif" ) ) );
}
buttonRow.add( selectCB = SPMTranslate.bCheckBox( "selected", false, this, "doSelectCB" ) );
//installSingleButton.setEnabled( false );
selectCB.setEnabled( false );
updateTree();
modified = false;
}
/**
* Description of the Method
*/
protected void updateTree()
{
if ( setup )
{
//get the scripts
fs.getRemoteInfo(
new Runnable()
{
public void run()
{
doCallbackUpdate();
}
} );
}
}
/**
* Description of the Method
*/
public void doCallbackUpdate()
{
getPlugins();
getToolScripts();
getObjectScripts();
getStartupScripts();
setup = true;
( (DefaultTreeModel) tree.getModel() ).reload();
SPManagerFrame.getInstance().checkForUpdatedMe();
}
/**
* Pane setup
*/
public void doSetup()
{
if ( !setup )
{
//get the scripts
fs.getRemoteInfo(
new Runnable()
{
public void run()
{
doCallbackUpdate();
}
} );
}
}
/**
* Gets the plugins attribute of the InstallSplitPane object
*/
private void getPlugins()
{
getFiles( pluginsPath, fs.getPlugins(), getManager().fs.getPlugins() );
}
/**
* Gets the toolScripts attribute of the InstallSplitPane object
*/
private void getToolScripts()
{
getFiles( toolScriptsPath, fs.getToolScripts(), getManager().fs.getToolScripts() );
}
/**
* Gets the objectScripts attribute of the InstallSplitPane object
*/
private void getObjectScripts()
{
getFiles( objectScriptsPath, fs.getObjectScripts(), getManager().fs.getObjectScripts() );
}
/**
* Gets the startupScripts attribute of the InstallSplitPane object
*/
private void getStartupScripts()
{
getFiles( startupScriptsPath, fs.getStartupScripts(), getManager().fs.getStartupScripts() );
}
/**
* Gets the files attribute of the InstallSplitPane object
*
*@param addTo Description of the Parameter
*@param infos Description of the Parameter
*@param managerInfoVector Description of the Parameter
*/
private void getFiles( TreePath addTo, Vector infos, Vector managerInfoVector )
{
DefaultMutableTreeNode tn;
SPMObjectInfo info;
SPMObjectInfo managerInfo;
boolean eligible;
TreeMap map = new TreeMap();
for ( int i = 0; i < infos.size(); i++ )
{
info = (SPMObjectInfo) infos.elementAt( i );
if (info.restriction >= SPMParameters.HIDE) continue;
{
//check if file candidate for update or install
eligible = ( workMode == INSTALL );
managerInfo = null;
String name = info.getName();
for ( int j = 0; j < managerInfoVector.size(); ++j )
{
if ( ( (SPMObjectInfo) managerInfoVector.elementAt( j ) ).getName().equals( name ) )
{
eligible = ( workMode == UPDATE );
if ( eligible )
{
//check if valid update
managerInfo = (SPMObjectInfo) managerInfoVector.elementAt( j );
System.out.println( info.getName() );
System.out.println( "major distant local :" + info.getMajor() + " " + managerInfo.getMajor() );
System.out.println( "minor distant local :" + info.getMinor() + " " + managerInfo.getMinor() );
System.out.println( "beta distant local :" + info.isBeta() + " " + managerInfo.isBeta() );
System.out.println( "beta distant local :" + info.getBeta() + " " + managerInfo.getBeta() );
if ( info.getMajor() < managerInfo.getMajor() )
{
eligible = false;
}
else if ( info.getMajor() == managerInfo.getMajor() )
{
if ( info.getMinor() < managerInfo.getMinor() )
{
eligible = false;
}
else if ( info.getMinor() == managerInfo.getMinor() )
{
if (managerInfo.isBeta()) {
if (info.isBeta() && info.getBeta()
<= managerInfo.getBeta())
{
eligible = false;
}
}
else
{
eligible = false;
}
}
}
}
}
}
if ( eligible ) {
map.put( info.getName(), info);
}
}
}
Collection col = map.values();
if ( ! col.isEmpty() )
{
for( Iterator iter = col.iterator(); iter.hasNext(); )
{
info = (SPMObjectInfo) iter.next();
tn = new DefaultMutableTreeNode( info.getName() );
tn.setAllowsChildren( false );
tn.setUserObject( info );
tree.addNode( addTo, tn );
}
}
}
/**
* Description of the Method
*/
public void doInstallAll()
{
if ( !isDownloading )
{
isDownloading = true;
lengthToDownload = 0;
downloadedLength = 0;
lengthToDownload = getInstallLength( pluginsPath );
lengthToDownload += getInstallLength( toolScriptsPath );
lengthToDownload += getInstallLength( objectScriptsPath );
lengthToDownload += getInstallLength( startupScriptsPath );
if ( lengthToDownload > 0 )
{
status = new StatusDialog(SPManagerPlugin.getFrame());
(
new Thread()
{
public void run()
{
installAllSelected( pluginsPath );
installAllSelected( toolScriptsPath );
installAllSelected( objectScriptsPath );
installAllSelected( startupScriptsPath );
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run()
{
voidSelection();
getManager().doUpdate();
isDownloading = false;
status.dispose();
status = null;
SPManagerUtils.updateAllAoIWindows();
}
});
} catch (Exception e) {
System.out.println("install error: " + e);
}
}
}).start();
}
}
}
/**
* Gets the installLength attribute of the InstallSplitPane object
*
*@param path Description of the Parameter
*@return The installLength value
*/
private long getInstallLength( TreePath path )
{
long length = 0;
int count = tree.getChildNodeCount( path );
if ( count > 0 )
{
for ( int j = count - 1; j >= 0; --j )
{
DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getChildNode( path, j ).getLastPathComponent();
SPMObjectInfo nodeInfo = (SPMObjectInfo) node.getUserObject();
if ( nodeInfo.isSelected() )
{
length += nodeInfo.getTotalLength();
}
}
}
return length;
}
/**
* Description of the Method
*
*@param path Description of the Parameter
*/
private void installAllSelected( TreePath path )
{
int count = tree.getChildNodeCount( path );
if ( count > 0 )
{
if (errors == null) errors = new ArrayList(128);
else errors.clear();
boolean ignoreErrs = false;
int err = 0, cut1, cut2;
download:
for ( int j = count - 1; j >= 0; --j )
{
DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getChildNode( path, j ).getLastPathComponent();
SPMObjectInfo nodeInfo = (SPMObjectInfo) node.getUserObject();
if ( nodeInfo.isSelected() )
{
// confirm before proceeding?
if (nodeInfo.restriction == SPMParameters.CONFIRM) {
String reason = nodeInfo.getComments();
cut1 = reason.indexOf("**");
cut2 = reason.indexOf("**", cut1+2);
if (cut1 >= 0) {
if (cut2 <= cut1+2) cut2 = reason.length();
reason = reason.substring(cut1+2, cut2) + "\n";
}
else
reason = "\n";
reason = SPMTranslate.text("markedConfirm", nodeInfo.getName()) +
reason + SPMTranslate.text("Confirm");
if (new BStandardDialog("SPManager", UIUtilities.breakString(reason),
BStandardDialog.QUESTION)
.showOptionDialog(null, SPManagerFrame.YES_NO, SPManagerFrame.YES_NO[1]) == 1)
{
errors.add(SPMTranslate.text("Cancelled",
nodeInfo.getName()));
continue;
}
}
installFile( nodeInfo );
tree.removeNode( tree.getChildNode( path, j ) );
if (errors.size() > err && ignoreErrs == false) {
BLabel messg = SPMTranslate.bLabel("errMsg");
BStandardDialog dlg = new
BStandardDialog("SPManager", messg,
BStandardDialog.WARNING);
switch (dlg.showOptionDialog(null, SPManagerFrame.CONTINUE_IGNORE,
SPMTranslate.text("Continue"))) {
case 1:
break download;
case 2:
ignoreErrs = true;
}
}
err = errors.size();
}
}
if (errors.size() > 0) showErrors(errors);
}
}
/**
* Description of the Method
*/
public void doInstallSingle()
{
if (errors == null) errors = new ArrayList(128);
else errors.clear();
installNodeInfo = getSelectedNodeInfo();
if ( installNodeInfo == null )
{
return;
}
// confirm before proceeding?
if (installNodeInfo.restriction == SPMParameters.CONFIRM) {
String reason = installNodeInfo.getComments();
int cut1 = reason.indexOf("**");
int cut2 = reason.indexOf("**", cut1+2);
if (cut1 >= 0) {
if (cut2 <= cut1+2) cut2 = reason.length();
reason = reason.substring(cut1+2, cut2) + "\n";
}
else
reason = "\n";
reason = SPMTranslate.text("markedConfirm", installNodeInfo.getName()) +
reason + SPMTranslate.text("Confirm");
if (new BStandardDialog("SPManager", UIUtilities.breakString(reason),
BStandardDialog.QUESTION)
.showOptionDialog(null, SPManagerFrame.YES_NO, SPManagerFrame.YES_NO[1]) == 1)
{
errors.add(SPMTranslate.text("Cancelled",
installNodeInfo.getName()));
showErrors(errors);
return;
}
}
if ( !isDownloading )
{
isDownloading = true;
lengthToDownload = installNodeInfo.getTotalLength();
downloadedLength = 0;
if ( lengthToDownload > 0 )
{
if (errors == null) errors = new ArrayList(128);
else errors.clear();
status = new StatusDialog(SPManagerPlugin.getFrame());
(
new Thread()
{
public void run()
{
installFile( installNodeInfo );
if (errors.size() > 0) showErrors(errors);
//status.dispose();
//SPManagerPlugin.restart();
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run()
{
/* NTJ - replaced by restart() */
tree.removeNode(tree.getSelectedNode());
voidSelection();
getManager().doUpdate();
isDownloading = false;
status.dispose();
status = null;
SPManagerUtils.updateAllAoIWindows();
}
});
} catch (Exception e) {
System.out.println("install error: " + e);
}
}
}).start();
}
}
if (errors.size() > 0) showErrors(errors);
}
/**
* Description of the Method
*
*@param nodeInfo Description of the Parameter
*/
public void installFile( SPMObjectInfo nodeInfo )
{
HashMap transaction = new HashMap(32);
if (errors == null) errors = new ArrayList(16);
int errCount = errors.size();
File file = null;
switch ( fs.getInfoType( nodeInfo ) )
{
case SPMFileSystem.PLUGIN_TYPE:
file = new File(SPManagerPlugin.PLUGIN_DIRECTORY, nodeInfo.getName() + ".jar");
modified = true;
break;
case SPMFileSystem.TOOL_SCRIPT_TYPE:
file = new File(SPManagerPlugin.TOOL_SCRIPT_DIRECTORY, nodeInfo.getName() + ".bsh");
break;
case SPMFileSystem.OBJECT_SCRIPT_TYPE:
file = new File(SPManagerPlugin.OBJECT_SCRIPT_DIRECTORY, nodeInfo.getName() + ".bsh");
break;
case SPMFileSystem.STARTUP_SCRIPT_TYPE:
file = new File(SPManagerPlugin.STARTUP_SCRIPT_DIRECTORY, nodeInfo.getName() + ".bsh");
break;
}
File folder = new File(SPManagerPlugin.TEMP_DIR,
file.getParentFile().getName());
System.out.println("folder=" + folder.getAbsolutePath());
if (!folder.exists() && !folder.mkdirs()) {
errors.add(SPMTranslate.text("error") + "cannot open/create " +
folder.getAbsolutePath());
System.out.println("cannot open/create " +
folder.getAbsolutePath());
}
File update = new File(folder, file.getName() + ".upd");
System.out.println("downloading to " + update.getAbsolutePath());
if (status == null)
status = new StatusDialog(SPManagerPlugin.getFrame());
status.setText( SPMTranslate.text( "downloading", nodeInfo.getName() ) );
if ( fs.getInfoType( nodeInfo ) == SPMFileSystem.PLUGIN_TYPE )
{
downloadedLength += HttpSPMFileSystem.downloadRemoteBinaryFile( nodeInfo.httpFile, update.getAbsolutePath(), nodeInfo.length, status, lengthToDownload, downloadedLength, errors );
}
else
{
downloadedLength += HttpSPMFileSystem.downloadRemoteBinaryFile( nodeInfo.httpFile, update.getAbsolutePath(), nodeInfo.length, status, lengthToDownload, downloadedLength, errors );
}
transaction.put(file, update);
if ( nodeInfo.files != null )
{
String dest;
int sep;
for ( int j = 0; j < nodeInfo.files.length; ++j )
{
dest = (String) nodeInfo.destination.get(j);
sep = dest.indexOf('/');
// build the destination path
if (sep == 0) {
file = new File(SPManagerPlugin.APP_DIRECTORY, dest.substring(1));
}
else if (dest.startsWith("$")) {
try {
file = new File(SPManagerPlugin.class.getField(dest.substring(1, sep)).get(null).toString(), dest.substring(sep+1));
} catch (Exception e) {
System.out.println("SPManager: cannot resolve: " + dest);
errors.add("Cannot resolve: " + dest);
}
}
else {
switch ( fs.getInfoType( nodeInfo ) )
{
case SPMFileSystem.PLUGIN_TYPE:
file = new File(SPManagerPlugin.PLUGIN_DIRECTORY, dest);
break;
case SPMFileSystem.TOOL_SCRIPT_TYPE:
file = new File(SPManagerPlugin.TOOL_SCRIPT_DIRECTORY, dest);
break;
case SPMFileSystem.OBJECT_SCRIPT_TYPE:
file = new File(SPManagerPlugin.OBJECT_SCRIPT_DIRECTORY, dest);
break;
case SPMFileSystem.STARTUP_SCRIPT_TYPE:
file = new File(SPManagerPlugin.STARTUP_SCRIPT_DIRECTORY, dest);
break;
}
}
// now add the actual file name
//file = new File(file, nodeInfo.files[j]); NTJ: now added in SPMObjectInfo when XML is parsed
folder = new File(SPManagerPlugin.TEMP_DIR,
file.getParentFile().getName());
if (!folder.exists() && !folder.mkdirs()) {
errors.add(SPMTranslate.text("error") +
"cannot open/create " +
folder.getAbsolutePath());
System.out.println("cannot open/create " +
folder.getAbsolutePath());
}
update = new File(folder, file.getName() + ".upd");
System.out.println("downloading to " +
update.getAbsolutePath());
if ( status != null )
{
status.setText( SPMTranslate.text( "downloading", nodeInfo.files[j] ) );
}
//value = status.getBarValue();
URL addFileURL = nodeInfo.getAddFileURL( j );
System.out.println("downloading from " + addFileURL.toString());
downloadedLength += HttpSPMFileSystem.downloadRemoteBinaryFile( addFileURL, update.getAbsolutePath(), nodeInfo.fileSizes[j], status, lengthToDownload, downloadedLength, errors );
transaction.put(file, update);
}
}
File orig;
Map.Entry entry;
Iterator iter = transaction.entrySet().iterator();
while (iter.hasNext()) {
try {
entry = (Map.Entry) iter.next();
orig = (File) entry.getKey();
update = (File) entry.getValue();
// if there are errors, just clean up...
if (errors.size() > errCount) {
if (!update.delete()) {
System.out.println("SPManager: tx abort: " +
" update file not deleted: " +
update.getAbsolutePath());
// NTJ Happens normally on some Wincrap boxes, so don't
// display an error
//errors.add("couldn't delete " +
// update.getAbsolutePath());
// make file zero-length
RandomAccessFile raf =
new RandomAccessFile(update, "rw");
raf.setLength(0);
raf.close();
}
continue;
}
folder = file.getParentFile();
if (!folder.exists() && !folder.mkdirs()) {
throw new RuntimeException("cannot open/create " +
folder.getAbsolutePath());
}
// now delete the original, and rename the new file
if (orig.exists()) orig.delete();
System.out.println("copying file to " +
orig.getAbsolutePath());
if (!update.renameTo(orig)) {
System.out.println("SPManager: old-style copy...");
if (copyFile(update, orig)) {
// make sure update file really was deleted
if (!update.delete()) {
System.out.println("SPManager:" +
" update file not deleted: " +
update.getAbsolutePath());
// NTJ Happens normally on some Wincrap boxes, so don't
// display an error
//errors.add("couldn't delete " +
// update.getAbsolutePath());
// make file zero-length
RandomAccessFile raf =
new RandomAccessFile(update, "rw");
raf.setLength(0);
raf.close();
}
}
else {
System.out.println("SPManager.cleanup: " +
"could not copy " + file.getPath());
errors.add("couldn't copy " + file.getName());
}
}
} catch (Exception e) {
errors.add(SPMTranslate.text("error") +
"(" + file.getName() + ")" + e);
}
}
//fs.deleteInfo(nodeInfo);
}
/**
* copy one file to another
*/
protected static boolean copyFile(File in, File out)
{
InputStream is = null;
OutputStream os = null;
try {
is = new BufferedInputStream(new FileInputStream(in));
os = new BufferedOutputStream(new FileOutputStream(out));
int b;
while ((b = is.read()) >= 0) os.write((byte) b);
}
catch (Exception e) {
return false;
}
finally {
try {
os.flush();
os.close();
is.close();
} catch (Exception e) {}
}
return true;
}
/**
* Description of the Method
*
*@param path Description of the Parameter
*/
private void selectAllInfos( TreePath path )
{
SPMObjectInfo info;
int count = tree.getChildNodeCount( path );
for ( int j = 0; j < count; ++j )
{
DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getChildNode( path, j ).getLastPathComponent();
SPMObjectInfo nodeInfo = (SPMObjectInfo) node.getUserObject();
nodeInfo.setSelected( true );
if (extMap != null) extMap.clear();
selectExternals(nodeInfo);
}
}
/**
* Description of the Method
*/
public void doSelectAll()
{
selectAllInfos( pluginsPath );
selectAllInfos( toolScriptsPath );
selectAllInfos( objectScriptsPath );
selectAllInfos( startupScriptsPath );
SPMObjectInfo nodeInfo = getSelectedNodeInfo();
if ( nodeInfo != null )
{
selectCB.setState( true );
}
repaint();
}
/**
* Description of the Method
*/
public void doSelectCB()
{
SPMObjectInfo nodeInfo = getSelectedNodeInfo();
if ( nodeInfo != null )
{
nodeInfo.setSelected( selectCB.getState() );
if (extMap != null) extMap.clear();
selectExternals(nodeInfo);
}
repaint();
}
/**
* Description of the Method
*
*@param info Description of the Parameter
*/
protected void notifyObjectInfoSelection( SPMObjectInfo info )
{
selectCB.removeEventLink( ValueChangedEvent.class, this );
selectCB.setState( info.isSelected() );
selectCB.addEventLink( ValueChangedEvent.class, this, "doSelectCB" );
super.notifyObjectInfoSelection(info);
}
/**
* Description of the Method
*
*@param deletable Description of the Parameter
*/
public void scriptSelection( boolean deletable )
{
//Button.setEnabled( true );
selectCB.setEnabled( true );
SPMObjectInfo nodeInfo = getSelectedNodeInfo();
if ( nodeInfo != null )
{
selectCB.setState( nodeInfo.isSelected() );
// disable select and install controls if item is restricted
if (nodeInfo.restriction >= SPMParameters.DISABLE) {
selectCB.setEnabled(false);
//installSingleButton.setEnabled(false);
}
// disable select control if item has references
if (nodeInfo.refcount > 0) selectCB.setEnabled(false);
// disable install single if script has dependents
Collection externals = nodeInfo.getExternals();
//if (externals != null && externals.size() > 0)
//installSingleButton.setEnabled(false);
}
super.scriptSelection( deletable );
}
/**
* Description of the Method
*
*@param deletable Description of the Parameter
*/
public void pluginSelection( boolean deletable )
{
//installSingleButton.setEnabled( true );
selectCB.setEnabled( true );
SPMObjectInfo nodeInfo = getSelectedNodeInfo();
if ( nodeInfo != null )
{
selectCB.setState( nodeInfo.isSelected() );
//System.out.println("externals =" +
// (nodeInfo.getExternals() != null
// ? nodeInfo.getExternals().size()
// : 0));
// disable select and install controls if item is restricted
if (nodeInfo.restriction >= SPMParameters.DISABLE) {
selectCB.setEnabled(false);
//installSingleButton.setEnabled(false);
}
// disable select control if item has references
if (nodeInfo.refcount > 0) selectCB.setEnabled(false);
// disable install single if plugin has dependents
Collection externals = nodeInfo.getExternals();
//if (externals != null && externals.size() > 0)
//installSingleButton.setEnabled(false);
}
super.pluginSelection( deletable );
}
/**
* Description of the Method
*/
public void voidSelection()
{
//installSingleButton.setEnabled( false );
selectCB.setEnabled( false );
super.voidSelection();
}
/**
* Sets the repository attribute of the InstallSplitPane object
*
*@param newRep The new repository value
*/
public void setRepository( URL newRep )
{
repository = newRep;
fs = new HttpSPMFileSystem( newRep );
doSetup();
}
public void showErrors()
{ if (errors != null && errors.size() > 0) showErrors(errors); }
/**
* show errors in a panel
*/
public static void showErrors(ArrayList errs)
{
BTextArea txt = new BTextArea(5, 45);
txt.setEditable(false);
txt.setWrapStyle(BTextArea.WRAP_WORD);
for (int i = 0; i < errs.size(); i++)
txt.append(errs.get(i) + "\n");
BScrollPane detail =
new BScrollPane(txt, BScrollPane.SCROLLBAR_NEVER,
BScrollPane.SCROLLBAR_AS_NEEDED);
BLabel messg = SPMTranslate.bLabel("errMsg");
new BStandardDialog("SPManager",
new Widget[] { messg, detail },
BStandardDialog.WARNING)
.showMessageDialog(null);
}
}
Run 1
The code is very difficult to read due to multiple issues. Structure is chaotic: the class handles too many responsibilities (UI setup, tree management, file operations, download logic) with no clear separation. Deeply nested conditionals and loops appear throughout, especially in installAllSelected, getFiles, and installFile, making control flow hard to trace. Methods are excessively long with multiple actions per line and commented-out code cluttering the source. Intent is often unclear due to sparse documentation (many 'Description of the Method' placeholders) and debug System.out.println statements left in. Variable names like 'fs', 'tn', 'col', and 'entry' are uninformative. The code relies heavily on side effects and shared mutable state (errors list, isDownloading flag, status dialog) which obscures logic. Inconsistent indentation, mixed brace styles, and complex ternary/logical expressions further reduce readability. While some method names are descriptive, the implementation details are tangled and require significant mental effort to understand.
Run 2
The code exhibits poor readability due to multiple factors. The structure is monolithic with several large methods (installFile, installAllSelected, getFiles) that mix concerns like UI, file I/O, and business logic. Nesting is deep in places, particularly in getFiles and installAllSelected with multiple nested loops and conditionals. Variable names are often cryptic (tn, cut1, cut2, err) and there are many commented-out blocks that add noise. The code relies heavily on side effects and mutable state (errors list, status dialog, boolean flags). The download logic is duplicated between installAllSelected and doInstallSingle. Action granularity is inconsistent - some lines pack multiple operations while others are spread out. The reading flow is disrupted by excessive debug println statements and inconsistent formatting. There are also several empty code blocks and unused variables. The class lacks clear separation of concerns, making it difficult to follow the program flow.
Run 3
The code is difficult to read due to excessive nesting, tangled logic, and poor separation of concerns. The installAllSelected method has deeply nested loops and conditionals (up to 5+ levels), making it hard to follow. Many methods are overly long (installFile is ~200 lines) and mix multiple responsibilities: UI updates, file I/O, error handling, and thread management. Comments are sparse and often just placeholder text like 'Description of the Method'. The action granularity is inconsistent - some lines perform multiple operations while others are unnecessarily verbose. Reading flow is disorganized, jumping between thread creation, UI updates, and file operations. There are also dead code blocks (commented-out lines) scattered throughout. While the code structure has some logical grouping by method name, the implementation within methods is tangled and hard to maintain.
Run 1
1. Code Structure: Methods separate some UI and installation operations, but the class mixes interface setup, version comparison, downloads, file transactions, and error handling; installFile is particularly overloaded. 2. Nesting: Deep conditionals, loops, anonymous threads, and callbacks make update eligibility and installation paths difficult to follow. 3. Clarity of intent: Many method names convey purpose, but generic documentation, abbreviated variables, raw collections, inherited state, and unexplained numeric options obscure details. 4. Code length: Excessive commented-out code, debug output, duplicated confirmation and selection logic, and identical download branches unnecessarily inflate the class. 5. Action granularity: Most statements perform one action, although assignments embedded in UI calls and compressed conditional statements reduce consistency. 6. Reading flow: Broad method grouping helps, but inconsistent indentation, long expressions, labeled breaks, mutable shared state, and interleaved UI/background operations interrupt natural reading.
Run 2
Code Structure: Methods separate some responsibilities, but the class mixes UI setup, selection, version checks, downloads, and filesystem transactions; several methods are oversized. Nesting: Deep conditionals, loops, and anonymous callbacks make update eligibility and installation difficult to follow. Clarity of intent: Descriptive method names and some useful comments establish the overall purpose, but abbreviated variables, shared mutable state, placeholder documentation, and obsolete commented-out code obscure details. Code length: Duplicated confirmation dialogs, selection handlers, directory switches, and identical download branches add unnecessary length. Action granularity: Most statements occupy separate lines, although assignments embedded in UI calls and compressed conditional statements combine actions. Reading flow: High-level installation sequences are understandable, but inconsistent formatting, long expressions, debug output, labeled breaks, and interleaved error handling interrupt the flow.
Run 3
Code Structure: Named methods provide some organization, but the class mixes UI setup, selection logic, version comparison, downloading, and file transactions; several methods handle too many responsibilities. Nesting: Version eligibility checks, installation loops, and anonymous thread callbacks are deeply nested, making control flow difficult to follow. Clarity of intent: Many method names communicate purpose, but placeholder documentation, abbreviated variables, shared mutable state, raw collections, and commented-out code obscure details. Code length: Excessive boilerplate, duplicated confirmation and selection logic, identical download branches, and repeated file-handling code inflate the class unnecessarily. Action granularity: Most statements perform one action, although assignments embedded in UI calls, compact conditionals, and multiple variable declarations reduce clarity. Reading flow: The broad setup-to-install-to-selection progression is understandable, but inconsistent indentation, long expressions, debugging output, labeled breaks, and interleaved error handling disrupt reading.