mirror of
https://github.com/binlaab/nanofiles.git
synced 2026-07-01 13:57:21 +02:00
161 lines
4.8 KiB
Java
161 lines
4.8 KiB
Java
package es.um.redes.nanoFiles.udp.message;
|
|
|
|
import es.um.redes.nanoFiles.application.NanoFiles;
|
|
|
|
/**
|
|
* Clase que modela los mensajes del protocolo de comunicación entre pares para
|
|
* implementar el explorador de ficheros remoto (servidor de ficheros). Estos
|
|
* mensajes son intercambiados entre las clases DirectoryServer y
|
|
* DirectoryConnector, y se codifican como texto en formato "campo:valor".
|
|
*
|
|
* @author rtitos
|
|
*
|
|
*/
|
|
public class DirMessage {
|
|
public static final int PACKET_MAX_SIZE = 65507; // 65535 - 8 (UDP header) - 20 (IP header)
|
|
|
|
private static final char DELIMITER = ':'; // Define el delimitador
|
|
private static final char END_LINE = '\n'; // Define el carácter de fin de línea
|
|
|
|
/**
|
|
* Nombre del campo que define el tipo de mensaje (primera línea)
|
|
*/
|
|
private static final String FIELDNAME_OPERATION = "operation";
|
|
/*
|
|
* TODO: (Boletín MensajesASCII) Definir de manera simbólica los nombres de
|
|
* todos los campos que pueden aparecer en los mensajes de este protocolo
|
|
* (formato campo:valor)
|
|
*/
|
|
|
|
private static final String FIELDNAME_PROTOCOL = "protocol";
|
|
/**
|
|
* Tipo del mensaje, de entre los tipos definidos en PeerMessageOps.
|
|
*/
|
|
private String operation = DirMessageOps.OPERATION_INVALID;
|
|
/**
|
|
* Identificador de protocolo usado, para comprobar compatibilidad del directorio.
|
|
*/
|
|
private String protocolId;
|
|
/*
|
|
* TODO: (Boletín MensajesASCII) Crear un atributo correspondiente a cada uno de
|
|
* los campos de los diferentes mensajes de este protocolo.
|
|
*/
|
|
|
|
public DirMessage(String op) {
|
|
operation = op;
|
|
}
|
|
|
|
/*
|
|
* TODO: (Boletín MensajesASCII) Crear diferentes constructores adecuados para
|
|
* construir mensajes de diferentes tipos con sus correspondientes argumentos
|
|
* (campos del mensaje)
|
|
*/
|
|
|
|
public String getOperation() {
|
|
return operation;
|
|
}
|
|
|
|
/*
|
|
* TODO: (Boletín MensajesASCII) Crear métodos getter y setter para obtener los
|
|
* valores de los atributos de un mensaje. Se aconseja incluir código que
|
|
* compruebe que no se modifica/obtiene el valor de un campo (atributo) que no
|
|
* esté definido para el tipo de mensaje dado por "operation".
|
|
*/
|
|
public void setProtocolID(String protocolIdent) {
|
|
if (!operation.equals(DirMessageOps.OPERATION_PING)) {
|
|
throw new RuntimeException(
|
|
"DirMessage: setProtocolId called for message of unexpected type (" + operation + ")");
|
|
}
|
|
protocolId = protocolIdent;
|
|
}
|
|
|
|
public String getProtocolId() {
|
|
|
|
|
|
|
|
return protocolId;
|
|
}
|
|
|
|
/**
|
|
* Método que convierte un mensaje codificado como una cadena de caracteres, a
|
|
* un objeto de la clase PeerMessage, en el cual los atributos correspondientes
|
|
* han sido establecidos con el valor de los campos del mensaje.
|
|
*
|
|
* @param message El mensaje recibido por el socket, como cadena de caracteres
|
|
* @return Un objeto PeerMessage que modela el mensaje recibido (tipo, valores,
|
|
* etc.)
|
|
*/
|
|
public static DirMessage fromString(String message) {
|
|
/*
|
|
* TODO: (Boletín MensajesASCII) Usar un bucle para parsear el mensaje línea a
|
|
* línea, extrayendo para cada línea el nombre del campo y el valor, usando el
|
|
* delimitador DELIMITER, y guardarlo en variables locales.
|
|
*/
|
|
// System.out.println("DirMessage read from socket:");
|
|
// System.out.println(message);
|
|
String[] lines = message.split(END_LINE + "");
|
|
// Local variables to save data during parsing
|
|
DirMessage m = null;
|
|
|
|
for (String line : lines) {
|
|
int idx = line.indexOf(DELIMITER); // Posición del delimitador
|
|
String fieldName = line.substring(0, idx).toLowerCase(); // minúsculas
|
|
String value = line.substring(idx + 1).trim();
|
|
|
|
switch (fieldName) {
|
|
case FIELDNAME_OPERATION: {
|
|
assert (m == null);
|
|
m = new DirMessage(value);
|
|
break;
|
|
}
|
|
|
|
case FIELDNAME_PROTOCOL: {
|
|
m.setProtocolID(value);
|
|
break;
|
|
}
|
|
|
|
|
|
default:
|
|
System.err.println("PANIC: DirMessage.fromString - message with unknown field name " + fieldName);
|
|
System.err.println("Message was:\n" + message);
|
|
System.exit(-1);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
return m;
|
|
}
|
|
|
|
/**
|
|
* Método que devuelve una cadena de caracteres con la codificación del mensaje
|
|
* según el formato campo:valor, a partir del tipo y los valores almacenados en
|
|
* los atributos.
|
|
*
|
|
* @return La cadena de caracteres con el mensaje a enviar por el socket.
|
|
*/
|
|
public String toString() {
|
|
|
|
StringBuffer sb = new StringBuffer();
|
|
sb.append(FIELDNAME_OPERATION + DELIMITER + operation + END_LINE); // Construimos el campo
|
|
/*
|
|
* TODO: (Boletín MensajesASCII) En función de la operación del mensaje, crear
|
|
* una cadena la operación y concatenar el resto de campos necesarios usando los
|
|
* valores de los atributos del objeto.
|
|
*/
|
|
|
|
switch (operation) {
|
|
case DirMessageOps.OPERATION_PING:
|
|
sb.append(FIELDNAME_PROTOCOL + DELIMITER + NanoFiles.PROTOCOL_ID + END_LINE);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
sb.append(END_LINE); // Marcamos el final del mensaje
|
|
return sb.toString();
|
|
}
|
|
|
|
}
|