first commit

This commit is contained in:
Jose Caban
2025-06-07 01:59:34 -04:00
commit 388ac241f0
3558 changed files with 9116289 additions and 0 deletions

View File

@@ -0,0 +1,418 @@
package nettext.client;
import java.util.List;
import java.util.Vector;
import nettext.messaging.MessageFactory;
import nettext.messaging.MessageSettings;
import nettext.messaging.AbstractMessage;
import nettext.client.networking.ClientNetworking;
import nettext.client.gui.ClientUI;
import nettext.document.Document;
import nettext.file.ASCIIDocumentReader;
import nettext.file.HTMLDocumentReader;
import nettext.file.ASCIIOutputHandler;
import nettext.file.HTMLOutputHandler;
/**
* Class Client: This singleton class will tie everything together -
* the networking, the ui, etc.
*
* <PRE>
* Revision History:
* v1.0 (Feb. 20, 2004) - Created the Client class
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Feb. 20, 2004
*/
public final class Client {
/**
* YASLI: Yet Another SingLeton Instance.
*/
private static Client instance;
/**
* This is the name under which the user is connected to the
* server. If no name was provided, a generic name will be used.
*/
private String userName;
/**
* The object that encapsulates the networking functionality for the
* client.
*/
private ClientNetworking network;
/**
* This guy will be used to handle all of the message processing for
* the client.
*/
private MessageProcessor processor;
/**
* Creates a new <code>Client</code> instance.
*/
private Client() {
userName = null;
network = new ClientNetworking();
processor = new MessageProcessor();
}
/**
* That's right... Another singleton! God, am I getting sick of
* reimplementing them over and over! Why? Why doesn't java 1.4 have
* templates, so I could just make ONE bloody singleton class and
* inherit from a templated copy of it? :(
*
* @return a <code>Client</code> value
*/
public static Client getInstance() {
if (instance == null) {
instance = new Client();
}
return instance;
}
/**
* Returns the name under which the user is connected to the server.
*
* @return a <code>String</code> value
*/
public String getUsername() {
return userName;
}
/**
* Gives the user a new name.
*
* @param name a <code>String</code> value
*/
protected void setUsername(final String name) {
this.userName = name;
}
/**
* Attempts to connect to the server specified in the parameters.
*
* @param host The hostname of the server to connect to.
* @param port The port at which we want to connect to the server.
* @param username The username that we want to use for this connection.
* @return True if the connection was successful, and false if it failed.
*/
public boolean connectToServer(final String host,
final int port,
final String username) {
boolean result = false;
List data = new Vector();
AbstractMessage message = null;
if (username != null) {
setUsername(username);
}
//Connect to the server
result = network.connect(host, port);
if (!result) {
//Could not connect to the server...
//Tell ClientUI to issue a warning saying the connection failed.
ClientUI.getInstance().showWarning("Connection Failed",
"Could not connect to the server.");
return false;
}
//Issue a helo message
data.add(getUsername());
message = MessageFactory.getInstance()
.makeMessage(MessageSettings.JOIN_TYPE, data);
result = sendMessage(message);
if (!result) {
//Failed to send the HELO message
if (ClientSettings.VERBOSE) {
System.out.println("Client: Could not send HELO message...");
}
//Tell ClientUI to issue a warning
ClientUI.getInstance().showWarning("Connection Failed",
"Could not send a join message to"
+ " the server.");
network.shutDown();
return false;
}
return true;
}
/**
* This function will issue a QUIT message to the server and then
* tell client networking to shut down.
* @param clean Specifies whether or not a QUIT message should be
* issued. If this parameter is false, the client will just close
* the socket.
*/
public void disconnectFromServer(final boolean clean) {
List data = new Vector();
AbstractMessage message = null;
if (!network.isConnected()) {
return;
}
if (clean) {
//Issue a quit message:
data.add(getUsername());
message = MessageFactory.getInstance()
.makeMessage(MessageSettings.QUIT_TYPE, data);
sendMessage(message);
}
//Shut down networking:
network.shutDown();
ClientUI.getInstance().hideDocumentListFrame();
}
/**
* Returns true if the client is currrently connected to the server,
* and false if he is not.
*
* @return a <code>boolean</code> value
*/
public boolean isConnected() {
return network.isConnected();
}
/**
* Sends a message to the server. If the send succeeds, returns
* true. Otherwise returns false.
*
* @param message an <code>AbstractMessage</code> value
* @return a <code>boolean</code> value
*/
public boolean sendMessage(final AbstractMessage message) {
if (message == null) {
return false;
}
if (!network.isConnected()) {
return false;
}
network.sendMessage(message);
return true;
}
/**
* This will be called when the client wishes to create a new
* document.
*/
public void createDocument() {
//See if we are connected
if (!isConnected()) {
return;
}
//Ask the user for a document name
String name = ClientUI.getInstance()
.showInputDialog("Choose Document Name",
"Please choose the name for your new document:",
"Document1");
if (name == null) {
return;
}
//Tell the server we have created a new document. It should either
//tell us that the document has been added by sending us a DCMT
//message, or that one with the same name already exists.
List data = new Vector();
Document doc = new Document();
doc.setDocumentName(name);
doc.setDocumentLoaded(true);
doc.updateDocument();
data.add(doc);
sendMessage(MessageFactory.getInstance()
.makeMessage(MessageSettings.DOC_TRANSFER_TYPE, data));
}
/**
* Shows the open dialog first and then performs the loading of the
* document, after which, this document is send over to the server
* for approval.
*/
public void importDocument() {
//written by Jose Caban
//Check for connection
if (!isConnected()) {
return;
}
//Pop up the thingamabob to select the file
String fileName = ClientUI.getInstance().browseLoadFileName(null);
if (fileName == null) {
return;
}
//Check the file type
if (fileName.endsWith(".txt")) {
/* Load ASCII */
ASCIIDocumentReader asciiDocReader = new ASCIIDocumentReader();
if (!asciiDocReader.initialize(fileName)) {
System.err.println("Error Loading Document");
System.err.flush();
ClientUI.getInstance()
.showError("File I/O Error",
"Error accessing the File");
return;
}
Document docImportMe = asciiDocReader.readDocument();
if (docImportMe == null) {
System.err.println("Error loading the document");
return;
}
asciiDocReader.cleanUp();
docImportMe.updateDocument();
List v = new Vector();
v.add(docImportMe);
sendMessage(MessageFactory.getInstance()
.makeMessage(MessageSettings.DOC_TRANSFER_TYPE, v));
} else if (fileName.endsWith(".html") || fileName.endsWith(".htm")) {
/* Load HTML */
HTMLDocumentReader htmlDocReader = new HTMLDocumentReader();
if (!htmlDocReader.initialize(fileName)) {
System.err.println("Error Loading Document");
System.err.flush();
ClientUI.getInstance()
.showError("File I/O Error",
"Error accessing the File");
return;
}
Document docImportMe = htmlDocReader.readDocument();
if (docImportMe == null) {
System.err.println("Error loading the document");
return;
}
htmlDocReader.cleanUp();
List v = new Vector();
v.add(docImportMe);
sendMessage(MessageFactory.getInstance()
.makeMessage(MessageSettings.DOC_TRANSFER_TYPE, v));
} else {
ClientUI.getInstance()
.showError("File Type Unsupported",
"The file you selected is not Supported");
return;
}
}
/**
* Export a Document
* @param docExportMe the Document to export
*/
public void exportDocument(Document docExportMe) {
String fileName = ClientUI.getInstance().browseSaveFileName(null);
if (fileName == null) {
return;
}
fileName = fileName.substring(0, fileName.length() - 4);
if (ClientSettings.VERBOSE) {
System.out.println("Export file: " + fileName);
}
//Check the file type
if (fileName.endsWith(".html") || fileName.endsWith(".htm")) {
HTMLOutputHandler htmlOutputHandler = new HTMLOutputHandler();
htmlOutputHandler.initialize(fileName);
if (!htmlOutputHandler.writeToDisk(docExportMe)) {
ClientUI.getInstance().showError("Error Writing File",
"The system encountered an error writing the file to disk."
+ " This is most likely Linux's fault");
}
} else {
ASCIIOutputHandler asciiOutputHandler = new ASCIIOutputHandler();
asciiOutputHandler.initialize(fileName);
if (!asciiOutputHandler.writeToDisk(docExportMe)) {
ClientUI.getInstance().showError("Error Writing File",
"The system encountered an error writing the file to disk."
+ " This is most likely Linux's fault");
}
asciiOutputHandler.cleanUp();
}
}
/**
* This function receives the message from the server. It needs to
* check the type of message first. Then, if the message is a
* graphics message, this should send it to the message list, and
* tell the graphics panel to rerender. If it is a chat message, it
* should be sent to the message list, and then to the chat
* panel. Etc.
*
* @param message an <code>AbstractMessage</code> value
*/
public void processMessage(final AbstractMessage message) {
processor.processMessage(message);
}
/**
* This function will be called by the server listener when the
* server drops the connection. It will take appropriate steps to
* shut down the connection and notify the user of the problem.
*/
public void serverQuit() {
ClientUI.getInstance().showWarning("Server Lost",
"The connection to the server has "
+ "been lost...");
network.shutDown();
}
/**
* Shuts down the client.
*/
public void shutDown() {
//FIXME: Implement a clean shutdown.
System.exit(0);
}
}