Listing of Source filetrans/AdminUtilServerToClientFileTransfer.javapackage se.entra.phantom.server.rconsole;
import java.io.BufferedInputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import se.entra.phantom.server.ClientSessionManager;
import se.entra.phantom.server.VirtualCUserWindow;
import se.entra.phantom.server.VirtualComponentAdapter;
import se.entra.phantom.server.VirtualControl;
import se.entra.phantom.server.VirtualPanel;
import se.entra.phantom.server.VirtualSessionManager;
import se.entra.phantom.server.VirtualUserWindowInterface;
/**
* This class handles the transfer of an arbitrary file from the server to the client.
*/
public class AdminUtilServerToClientFileTransfer extends VirtualComponentAdapter implements AdminFileTransferListener
{
/**
* The file to be transfered from the server.
*/
private File serverFile;
/**
* The stream used for picking up the data.
*/
private BufferedInputStream fileInputStream;
/**
* The total file size.
*/
private int totalSize;
/**
* Current position in file.
*/
private int pos;
/**
* The full path to the file on the client side.
*/
private String clientFilePath;
/**
* The session manager.
*/
private final VirtualSessionManager vsm;
/**
* Flag indicating if file transfer is in progress.
*/
private boolean inProgress;
/**
* Flag indicating if a 'cancel' action is to be processed.
*/
private boolean doCancel;
/**
* The server file control.
*/
private final VirtualControl serverFileControl;
/**
* A general header used for message boxes.
*/
private final String messageHeader;
/**
* A general header used for error message boxes.
*/
private final String errorMessageHeader;
///
/**
* Constructor.
*/
public AdminUtilServerToClientFileTransfer(ClientSessionManager csm,VirtualPanel vp)
{
this.vsm=vp.getVirtualSessionManager();
vp.setListener(this);
// Hide the file transfer user window.
vp.setVisible("FILETRAN",false);
vp.setText("MESSAGE","Progress indicator:");
vp.setText("PROGRESS","0");
serverFileControl=vp.getControlFromID("SRVFILE");
messageHeader="Server-to-client file transfer";
errorMessageHeader="Error during file transfer";
}
/**
* This thread is notified each time the 'old' thread is requested by the client
* for another piece of data.
*/
private void sendData(VirtualPanel vp)
{
try
{
final byte [] buf=new byte [4096];
if ( fileInputStream==null )
{
logEvent(vp,"sendData","Unable to read from FileInputStream");
return;
}
int cc=0;
if ( totalSize>0 )
{
cc=fileInputStream.read(buf);
if ( cc<0 )
throw new EOFException();
}
//Get that userWindow!
final VirtualUserWindowInterface vu=((VirtualCUserWindow)(vp.getControlFromID("FILETRAN"))).getPeer();
final AdminFileTransferInterface userWindow=(AdminFileTransferInterface)vu;
if ( userWindow==null )
{
logEvent(vp,"sendData","Unable to locate server UserWindow");
close(vp);
return;
}
userWindow.serverToClientFileTransfer(this,clientFilePath,totalSize,cc,buf);
pos+=cc;
}
catch(final Exception e)
{
logEvent(vp,"sendData",e.toString());
if ( fileInputStream!=null )
{
try { fileInputStream.close(); }
catch(final IOException e2) {}
fileInputStream=null;
}
close(vp);
}
}
/**
* Method call when download is completed
*/
@Override
public void onFileUploadComplete(VirtualPanel vp,AdminFileTransferInterface ft)
{
if ( fileInputStream!=null )
{
try { fileInputStream.close(); }
catch(final Exception e) {}
fileInputStream=null;
}
vp.setText("PROGRESS","100");
inProgress=false;
vp.messageBox(MB_OK,ICON_INFORMATION,
"You have received a new file ("+clientFilePath+") from the server ("+serverFile+")." ,
messageHeader);
vp.setEnabled("TRANSFER",true);
}
/**
* Called whenever a file transfer error occurs.
*/
@Override
public void onFileTransferError(VirtualPanel vp,AdminFileTransferInterface ft,String errorMessage)
{
vp.messageBox(MB_OK,ICON_WARNING,errorMessage,errorMessageHeader);
vp.setText("PROGRESS","0");
close(vp);
return;
}
/**
* A file has been selected in the dialog box (or canceled if file name is null).
*/
@Override
public void onFileSelected(VirtualPanel vp,AdminFileTransferInterface ft,String fileName,int size)
{
}
/**
* Returns the list of all files or directories in the requested directory.
*/
@Override
public void onDirectoryList(VirtualPanel vp,AdminFileTransferInterface ft,AdminConfigFileTransferItem [] files)
{
}
/**
* A piece of the download data of a file (data is null when canceled).
*/
@Override
public void onFileDownload(VirtualPanel vp,AdminFileTransferInterface ft,int totalSize,byte [] data)
{
}
/**
* The client is requesting a file for download
*/
@Override
public void onFileUpload(VirtualPanel vp,AdminFileTransferInterface ft)
{
// Calculate percentage of download.
final long progress=100L*pos/totalSize;
vp.setText("PROGRESS",Long.toString(progress));
if ( pos<totalSize && !doCancel )
sendData(vp);
}
/**
* A file has been chosen on the client
*/
@Override
public void onTargetFileSelected(VirtualPanel vp,AdminFileTransferInterface ft,String directory)
{
inProgress=false;
vp.setText("CLNTDIR",directory);
}
/**
* Push buttons and menu items generates this event when selected.
*/
@Override
public void onAction(VirtualPanel vp,String controlID)
{
if ( controlID.equals("CANCEL" ) ) onPanelClosing(vp);
else if ( controlID.equals("DIR" ) ) selectTargetFile(vp);
else if ( controlID.equals("FILE" ) ) new AdminConfigSelectFile(vsm,serverFileControl,null);
else if ( controlID.equals("TRANSFER") ) performTransfer(vp);
}
/**
* Method used to initiate a file selection on the client
*/
private void selectTargetFile(VirtualPanel vp)
{
final VirtualUserWindowInterface vu=((VirtualCUserWindow)(vp.getControlFromID("FILETRAN"))).getPeer();
final AdminFileTransferInterface userWindow=(AdminFileTransferInterface)vu;
doCancel=false;
if ( !userWindow.selectTargetFile(this) )
vp.messageBox(MB_OK,ICON_WARNING,"Selection of file to transfer failed.",messageHeader);
}
/**
* Method called when the 'TRANSFER' button is pressed
*/
private void performTransfer(VirtualPanel vp)
{
clientFilePath=vp.getText("CLNTDIR");
final String serverFilePath=vp.getText("SRVFILE");
// Check access rights.
try
{
AdminConfigFileManager.checkAccessRights(serverFilePath);
}
catch(final IOException e)
{
vp.messageBox(MB_OK,ICON_CRITICAL,"Error checking the specified server file: "+e,messageHeader);
return;
}
String cfpEnding="";
String sfpEnding="";
int index=clientFilePath.lastIndexOf('.');
if ( index>=0 )
cfpEnding=clientFilePath.substring(index);
index=serverFilePath.lastIndexOf('.');
if ( index>=0 )
sfpEnding=serverFilePath.substring(index);
// Validation.
if ( clientFilePath.isEmpty() || serverFilePath.isEmpty() )
{
vp.messageBox(MB_OK,ICON_WARNING,"Please specify both a target and a source file.",messageHeader);
return;
}
serverFile=new File(serverFilePath);
if ( !serverFile.isFile() )
{
vp.messageBox(MB_OK,ICON_WARNING,"The file specified does not exist on the server.",messageHeader);
return;
}
if ( !cfpEnding.equals(sfpEnding) )
{
final int answer=vp.messageBox(MB_YESNO,ICON_WARNING,
"Please note that You are about to save the file with a different extension than the original file on the server.\n\n"+
"Do You want to continue?",messageHeader);
if ( answer!=MBID_YES )
return;
}
try
{
fileInputStream=new BufferedInputStream(new FileInputStream(serverFile));
totalSize=fileInputStream.available();
}
catch(final Exception e)
{
logEvent(vp,"performTransfer","Error when creating input stream ("+e+").");
return;
}
pos=0;
vp.setEnabled("TRANSFER",false);
vp.setText("PROGRESS","-1"); // Set undetermined state.
doCancel=false;
inProgress=true;
sendData(vp);
}
/**
* Closes this panel when no progress takes place.
* If transfer is in progress, set cancel flag.
*/
private void close(VirtualPanel vp)
{
pos=0;
if ( fileInputStream!=null )
{
try { fileInputStream.close(); }
catch(final IOException e2) {}
fileInputStream=null;
}
if ( !inProgress )
vsm.stopSession(vp.getPanelSession().getIndex());
else
{
// Get that userWindow!
final VirtualUserWindowInterface vu=((VirtualCUserWindow)(vp.getControlFromID("FILETRAN"))).getPeer();
final AdminFileTransferInterface userWindow=(AdminFileTransferInterface)vu;
userWindow.closeFileTransfer();
vp.setEnabled("TRANSFER",true);
vp.setText("PROGRESS","0");
inProgress=false;
doCancel=true;
}
}
/**
* Called when the close button of a panel is pressed,
* but before any other processing has been done. If this
* function returns false, the application close object
* will be called (if defined), otherwise a faked key-press
* of the Escape key is performed. If these two actions
* failed (because there is no close object or no button or
* menu item is connected to the Escape key), then the
* function <code>onPanelClose</code> is called.
*
* @return true to cancel all default processing.
*/
@Override
public boolean onPanelClosing(VirtualPanel vp)
{
if ( inProgress )
vp.messageBox(MB_OK,ICON_WARNING,
"The file transfer was cancelled. The created file is corrupt.",
errorMessageHeader);
doCancel=true;
close(vp);
return true;
}
/**
* Called to inform the listener that the panel is destroyed.
*
* <p>Closes any currently opened file transfer.
*/
@Override
public void onPanelDestroy(VirtualPanel vp)
{
if ( fileInputStream!=null )
{
try { fileInputStream.close(); }
catch(final IOException e2) {}
fileInputStream=null;
}
}
/**
* Method to display an error message
*/
private void logEvent(VirtualPanel vp,String func,String msg)
{
if ( vp!=null )
vp.messageBox(MB_OK,ICON_WARNING,"Error in "+func+": "+msg,errorMessageHeader);
}
}