Skip to content
Snippets Groups Projects
Commit ec4592fc authored by Javier Calvo's avatar Javier Calvo
Browse files

Puerto estructurado correctamente

Falta los test
parent 02e889ae
No related branches found
No related tags found
No related merge requests found
......@@ -12,163 +12,60 @@ import java.util.List;
* @author victorm
*/
public class Contenedor {
private String codigo;
private final List<Trayecto> trayectos = new ArrayList<>();
private ISO6346 codigo;
private float pesoTara;
private float maximaCargaUtil;
private float volumen;
private boolean techo;
private List<Trayecto> trayectos = new ArrayList<>();
private boolean recogida;
private boolean transito;
private boolean apilado = false;
//Seleccion del estado y de las medidas
private enum estados{ REGOGIDA, TRANSITO }
private enum pesos{ KILOS, LIBRAS}
private enum volumenes{ METROS, PIES }
private estados estadoActual;
private final pesos pesoSeleccionado;
private final volumenes volumenSeleccionado;
//Parametros para el paso de unas medidas a otras
private final float KILOS_A_LIBRAS = 2.20462f;
private final float LIBRAS_A_KILOS = 0.453592f;
private final float METROS_A_PIES = 35.3147f;
private final float PIES_A_METROS= 0.0283168f;
/**
* Constructor del Objeto Contenedor
* @param codigoDueno codigo de 3 letras mayusculas del dueño
* @param equipamiento Una letra U, J o Z que indica el equipamiento
* @param numeroSerie El Numero de serie de 6 digitos
* @param pesoContenedor El peso del contenedor en kilogramos
* @param maximaCargaUtil La carga util del contenedor dada en kilogramos
* @param volumen El volumen dado en metros cúbicos
* @param transito Indica si esta en transito (true) o en recogida (false)
* @param techo indica si tiene techo (true) o no (false)
*/
public Contenedor(String codigoDueno, char equipamiento, String numeroSerie, float pesoTara, float maximaCargaUtil, float volumen, boolean transito, boolean techo) {
validarCodigoDueno(codigoDueno);
validarEquipamiento(equipamiento);
comprobarPesos(pesoTara, maximaCargaUtil, volumen);
validarNumeroSerie(numeroSerie);
public Contenedor(ISO6346 codigo, float pesoTara, float maximaCargaUtil, float volumen, estados estadoActual, pesos pesoSeleccionado, volumenes volumenSeleccionado, boolean techo) {
if (pesoTara<0 || maximaCargaUtil <0 || volumen<0)
throw new IllegalArgumentException("Los pesos no puedne ser menores a 0");
this.codigo = codigo;
this.pesoTara = pesoTara;
this.maximaCargaUtil = maximaCargaUtil;
this.volumen = volumen;
this.transito = transito;
this.recogida = !transito;
this.estadoActual = estadoActual;
this.pesoSeleccionado = pesoSeleccionado;
this.volumenSeleccionado = volumenSeleccionado;
this.techo = techo;
String digitoControl = String.valueOf(calcularDigitoControl(codigoDueno, equipamiento, numeroSerie));
this.codigo = codigoDueno.toUpperCase() + equipamiento + numeroSerie + digitoControl;
}
/**
* Metodo que compara e codigo del dueño para ver si es correcto
* @param codigoDueno Cadena de 3 letras mayusculas
* @throws IllegalArgumentException Si el codigoDueno no coincide con el patron correcto
*/
private void validarCodigoDueno(String codigoDueno) {
if (codigoDueno == null) throw new IllegalArgumentException("El código del dueño debe tener 3 letras mayúsculas.");
if (codigoDueno.length() != 3 || !codigoDueno.matches("[A-Za-z]{3}"))
throw new IllegalArgumentException("El código del dueño debe tener 3 letras mayúsculas.");
}
/**
* Metodo que sirve para comparar si el equipamiento es uno de los correctos
* @param equipamiento Es un caracter que indica el equipamiento
* @throws IllegalArgumentException si el equipamiento no es correcto (no es ni U ni J ni Z)
*/
private void validarEquipamiento(char equipamiento) {
if (equipamiento != 'U' && equipamiento != 'J' && equipamiento != 'Z') {
throw new IllegalArgumentException("Equipamiento debe ser 'U', 'J' o 'Z'.");
}
}
/**
* metodo para comparar si el numero de serie es correcto
* @param numeroSerie el numero de serie del contenedor
* @throws Si el numeroSerie no es correcto (no son 6 numeros) o si es nulo
*
*/
private void validarNumeroSerie(String numeroSerie) {
if (numeroSerie == null) throw new IllegalArgumentException("El numero de serie no puede ser nulo");
if (numeroSerie.length() != 6 || !numeroSerie.matches("\\d{6}")) {
throw new IllegalArgumentException("El número de serie debe tener 6 dígitos.");
}
}
/**
* Metodo qe comprueba los pesos de los contenedores
* @param pesoTara Peso del contenedor
* @param maximaCargaUtil Maxima carga util del contenedor
* @param volumen Volumen del contenedor
* @throws IllegalArgumentException si alguno de los pesos es menor que 1
*/
private void comprobarPesos(float pesoTara, float maximaCargaUtil, float volumen) {
if (pesoTara < 1 || maximaCargaUtil <1 || volumen < 1) {
throw new IllegalArgumentException("Los pesos deben ser igual o mayores a 1");
}
}
/**
* Metodo que sirve para calcular el diito de control mediante el codigo del dueño, el equipamiento y el
* numero de serie
* @return devuelve el digito de control
*/
private int calcularDigitoControl(String codigoDueno, char equipamiento, String numeroSerie) {
String codigoCompleto = codigoDueno + equipamiento + numeroSerie;
int[] valores = {10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38};
int suma = 0;
for (int i = 0; i < codigoCompleto.length(); i++) {
char c = codigoCompleto.charAt(i);
int valor;
if (Character.isLetter(c))valor = valores[c - 'A'];
else valor = Character.getNumericValue(c);
suma += valor*(int) Math.pow(2, i);
}
int resto = suma % 11;
return (resto == 10) ? 0 : resto;
}
/**
* Metodo que sirve para devolver el codigo del contenedor
* @return el codigo del contenedor (compelto)
*/
public String getCodigo() {
return this.codigo;
}
/**
* Metodo que devuelve si un contenedor tiene techo
* @return si tiene techo (true) o si no lo tiene (false)
*/
public boolean tieneTecho() {
return this.techo;
}
/**
* 1.1.13 Metodo que sirve para cambiar el estado a recogida de un contenedor
* Si esta apilado no puede estar en recogida
* @throws IllegalArgumentException si el contenedor esta apilado
*/
public void cambiarEstadoARecogida() {
if(this.estadoApilado()) throw new IllegalArgumentException("No puedes cambiar el estado a un contenedor apilado");
this.recogida = true;
this.transito = false;
this.estadoActual = estados.REGOGIDA;
}
/**
* 1.1.14 metodo que sirve para cambiar un contenedor a estado de transito
* Si esta apilado no puede estar en transito
* @throws IllegalArgumentException si el contenedor esta apilado
* 1.1.14 Metodo que sirve para cambiar un contenedor a estado de transito
*/
public void cambiarEstadoATransito() {
if(this.estadoApilado()) throw new IllegalArgumentException("No puedes cambiar el estado a un contenedor apilado");
this.recogida = false;
this.transito = true;
}
/**
* Metodo para cambiar estado a apilado
*/
public void cambiarEstadoApilado() {
this.apilado = true;
this.transito = false;
this.recogida = false;
}
/**
* Metodo para cmabiar el estado de apilado --> recogida
*/
public void cambiarEstadoDesapilado() {
this.apilado = false;
this.recogida = true;
this.estadoActual = estados.TRANSITO;
}
/**
......@@ -182,77 +79,66 @@ public class Contenedor {
* 1.1.16 Metodo que devuelve el volumen del contenedor en metros cubicos
* @return volumen en metros cubicos
*/
public float volumenEnMetrosCubicos() {
return this.volumen;
public double volumenEnMetrosCubicos() {
return (volumenSeleccionado == volumenes.METROS) ? this.volumen : this.volumen*this.PIES_A_METROS;
}
/**
* 1.1.17 metodo que devuelve el volumen del contenedor en pies cubicos
* @return volumen en pies cubicos
*/
public float volumenEnPiesCubicos() {
return this.volumen*35.3147f;
public double volumenEnPiesCubicos() {
return (volumenSeleccionado == volumenes.PIES) ? this.volumen : this.volumen*this.METROS_A_PIES;
}
/**
* 1.1.18 Metodo que devuelve el peso del contenedor en Kilogramos
* @return peso del contenedor en kilogramos
*/
public float obtenerPesoKilos() {
return this.pesoTara;
public double obtenerPesoKilos() {
return (this.pesoSeleccionado == pesos.KILOS ) ? this.pesoTara : this.pesoTara *this.LIBRAS_A_KILOS;
}
/**
* 1.1.19 Metodo que devuelve el peso del contenedor en Libras
* @return peso del contenedor en Libras
*/
public float obtenerPesoLibras() {
return this.pesoTara*2.20462f;
}
/**
* Metodo que devuelve la maxima carga util de un contenedor
* @return La maxima carga util de un contenedor
*/
public float cargaUtilContenedor() {
return this.maximaCargaUtil;
public double obtenerPesoLibras() {
return (this.pesoSeleccionado == pesos.LIBRAS ) ? this.pesoTara : this.pesoTara *this.KILOS_A_LIBRAS;
}
/**
* Metodo que devuelve el estado de recogida de un contenedor
* @return estado de recogida de un contenedor
* Metodo que calcula el costo total de los trayectos de un contenedor
* @param costeDiarioTrayecto El coste diario de un dia de trayecto
* @param costePorMilla El coste por milla recorrida en un trayecto
* @return el precio total del transporte del contenedor
*/
public boolean estadoRecogida() {
return this.recogida;
public double precioTransporteTotalContenedor(double costeDiarioTrayecto, double costePorMilla) {
if (this.trayectos.isEmpty())
return 0.0;
double precioTotal = 0.0;
for (Trayecto t : this.trayectos) {
precioTotal += t.precioTrayectoEnEuros(costeDiarioTrayecto, costePorMilla);
}
/**
* Metodo que devuelve el estado de transito de un contenedor
* @return estado de transito de un contenedor
*/
public boolean estadoTransito() {
return this.transito;
return precioTotal;
}
/**
* Metodo que devuelve el estado de apilamiento de un contenedor
* @return estado de apilamiento de un contenedor
*/
public boolean estadoApilado() {
return this.apilado;
}
/******************************
* EMPLEACION DE OTROS METODOS*
******************************/
/**
* Metodo que sirve para anyadir un trayecto al contenedor
* @param t El trayecto que se añade al contenedor
* @throws IllegalArgumentException si es trayecto es nulo, si la fecha fin del ultimo trayecto es superior
* a la de inicio del nuevo trayecto, o si el puerto/muelle destinos del ultimo trayecto no son los de origen
* del nuevo.
* @throws IllegalArgumentException si es trayecto es nulo,
* @throws IllegalArgumentException si la fecha fin del ultimo trayecto es superior a la de inicio del nuevo trayecto
* @throws IllegalArgumentException si el puerto/muelle destinos del ultimo trayecto no son los de origen del nuevo.
*/
public void anyadirTrayecto(Trayecto t) {
if (t == null) throw new IllegalArgumentException("El trayecto no puede ser nulo");
if (this.trayectos.size() == 0) this.trayectos.add(t);
if (t == null)
throw new IllegalArgumentException("El trayecto no puede ser nulo");
if (this.trayectos.size() == 0)
this.trayectos.add(t);
else {
Trayecto ultimoT = this.trayectos.get(this.trayectos.size() -1);
//Si la fecha fin es mayor a la de inicio del nuevo
......@@ -267,4 +153,43 @@ public class Contenedor {
this.trayectos.add(t);
}
}
/**
* Metodo que devuelve si un contenedor tiene techo
* @return si tiene techo (true) o si no lo tiene (false)
*/
public boolean tieneTecho() {
return this.techo;
}
/**
* Metodo que devuelve la maxima carga util de un contenedor
* @return La maxima carga util de un contenedor
*/
public float cargaUtilContenedor() {
return this.maximaCargaUtil;
}
/**
* Metodo que sirve para devolver el codigo del contenedor
* @return el codigo del contenedor (compelto)
*/
public String getCodigo() {
return this.codigo.codigoContenedor();
}
/**
* Metodo que sirve para devolver si el contenedor esta en transito
* @return true si esta en transito o false si no lo esta
*/
public boolean contenedorEnTransito() {
return (estadoActual == estados.TRANSITO) ? true : false;
}
/**
* Metodo que sirve para devolver si el contenedor esta en recogida
* @return true si esta en recogida o false si no lo esta
*/
public boolean contenedorEnRecogida() {
return (estadoActual == estados.REGOGIDA) ? true : false;
}
}
\ No newline at end of file
/**
* Copyright UVa 2024/2025
*/
package es.markse;
import java.util.regex.Pattern;
/**
* Implementacion de la clase ISO6346 para el codigo del contenedor
* @author javcalv
* @authro victorm
*/
public class ISO6346 {
private final String codigoDuenyo;
private char equipamiento;
private final int numeroSerie;
private int digitoControl;
private final Pattern CODIGO_DUENO = Pattern.compile("[A-Za-z]{3}");
/**
* Implementacion de la clase ISO6346
* @param codigoDuenyo Codigo del dueño de 3 letras (Mayusculas)
* @param equipamiento Equipamiento del contenedor --> U, J o Z
* @param numeroSerie Numero de serie del contenedor. De 0-999999
* @throws IllegalArgumentException si el codigo del dueño es nulo
* @throws IllegalArgumentException si el codigo del dueño no tiene el patron correcto
* @throws IllegalArgumentException si el equipamiento no es correcto
* @throws IllegalArgumentException si el numero de serie es incorrecto
*/
public ISO6346(String codigoDuenyo, char equipamiento, int numeroSerie) {
if(codigoDuenyo == null)
throw new IllegalArgumentException("El codigo del dueño no puede ser nulo");
if (!validarCodigoDueño(codigoDuenyo))
throw new IllegalArgumentException("El codigo del dueño no tiene el patron correcto (3 letras)");
if (!comprobarEquipamiento(equipamiento))
throw new IllegalArgumentException("Equipamiento debe ser 'U', 'J' o 'Z'");
if (numeroSerie<0 || numeroSerie>999999)
throw new IllegalArgumentException("El numero de serie debe ser entre 0-999999");
this.codigoDuenyo = codigoDuenyo.toUpperCase();
this.equipamiento = equipamiento;
this.numeroSerie = numeroSerie;
this.digitoControl = calcularDigitoControl(codigoDuenyo, equipamiento, numeroSerie);
}
/**
* Metodo que sirve para validar si el codigo del dueño tiene el patron correcto
* @param codigoDuenyo Codigo del dueño que se debe validar
* @return true si es correcto o falso si no lo es
*/
private boolean validarCodigoDueño(String codigoDuenyo) {
return (this.CODIGO_DUENO.matcher(codigoDuenyo).matches()) ? true : false;
}
/**
* Metodo que comprueba el equipamiento es correcto
* @param equipamiento Equipamiento que se comprobara
* @return true si es correcto o false si no lo es
*/
private boolean comprobarEquipamiento(char equipamiento) {
return (equipamiento == 'U' || equipamiento == 'J' || equipamiento == 'Z')? true: false;
}
/**
* Metodo que sirve para calcular el diito de control mediante el codigo del dueño, el equipamiento y el
* numero de serie
* @param codigoDuenyo Codigo del dueño
* @param equipamiento = equipamiento del contenedor
* @param numeroSerie numero de serie del contenedor
* @return devuelve el digito de control
*/
private int calcularDigitoControl(String codigoDueno, char equipamiento, int numeroSerie) {
String codigoCompleto = codigoDueno + equipamiento + numeroSerieString(numeroSerie);
int[] valores = {10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38};
int suma = 0;
for (int i = 0; i < codigoCompleto.length(); i++) {
char c = codigoCompleto.charAt(i);
int valor;
if (Character.isLetter(c))valor = valores[c - 'A'];
else valor = Character.getNumericValue(c);
suma += valor*(int) Math.pow(2, i);
}
int resto = suma % 11;
return (resto == 10) ? 0 : resto;
}
/**
* Metodo que pasa el numero de Serie a un String (con los 6 caracteres)
* @param numeroSerie Numero de serie a transformar
* @return numero de Serie transformado en String
*/
private String numeroSerieString(int numeroSerie) {
return String.format("%06d", numeroSerie);
}
/**
* Metodo que devuelve el codigo del dueño
* @return codigo del dueño
*/
public String codigoDuenyo() {
return this.codigoDuenyo;
}
/**
* Metodo que devuelve el equipamiento del codigo
* @return equipamiento
*/
public char equipamiento() {
return this.equipamiento;
}
/**
* Metodo que devuelve el numero de Serie del contenedor
* @return numero de Serie del contenedor
*/
public int numeroSerie() {
return this.numeroSerie;
}
/**
* Metodo que devuelve el codigo del Contenedor completo
* @return codigo del contenedor
*/
public String codigoContenedor() {
return (this.codigoDuenyo + this.equipamiento + numeroSerieString(numeroSerie) + this.digitoControl);
}
}
\ No newline at end of file
/**
* Copyright UVa 2024/2025
*/
......@@ -23,6 +22,7 @@ public class Muelle {
private estado estadoActual;
private final GPSCoordinate cord;
private final Pattern IDENTIFICADOR_REGUEX = Pattern.compile("^\\d{2}$");
private final Pattern CODIGO_CONTENEDOR = Pattern.compile("[A-Z]{4}\\d{7}");
private static class Plaza {
private int altura;
......@@ -37,20 +37,30 @@ public class Muelle {
}
/**
* Metodo que indica si un contenedor se encuentra en la plaza o no
* @param codigo Codigo del contenedor que queremos buscar
* @return true si contiene ese contenedor en la Plaza o false si no lo tiene
* 1.1.8 Metodo que devuelve si una plaza esta vacia o no
* @return true si esta vacia o false si no lo esta
*/
public boolean contieneContenedor(String codigo) {
return (this.nivelContenedor(codigo)!=-1) ? true : false;
public boolean plazaVacia() {
return (this.contenedores.size() == 0) ? true : false;
}
/**
* Metodo que indica el nivel que tiene un contenedor, dado un codigo.
* 1.1.8 Metodo que devuelve si una plaza esta llena o no
* @return true si la plaza esta llena o si no lo esta
*/
public boolean plazaLlena() {
return (this.contenedores.size() == this.altura || this.ultimoContenedor().tieneTecho()) ? true : false;
}
/**
* 1.1.10 Metodo que indica el nivel que tiene un contenedor, dado un codigo.
* @param codigo Codigo del contenedo que queremos ver su plaza
* @return la altura en la que se encuentra (del 1 que es la baja ahasta n, que es el máximo de contenedores apilabres)
* @throws IllegalArgumentException si el codigo es nulo
*/
public int nivelContenedor(String codigo) {
if (codigo == null)
throw new IllegalArgumentException("El codigo no puede ser nulo");
for (int i = 0; i < this.contenedores.size(); i++) {
if (this.contenedores.get(i).getCodigo().equals(codigo)) {
return i + 1;
......@@ -60,48 +70,41 @@ public class Muelle {
}
/**
*Metodo que sirve para colar el contenedor en una plaza (apilarlo si esppsible)
* 1.1.11 Metodo que sirve para colar el contenedor en una plaza (apilarlo si es posible)
* @param codigo: Codigo del contenedor
* @return true si se ha colodado, o false si no, ya que la plaza esta llena o el ultimo contenedor de esa plaza
* no tiene techo
* @return true si se ha colodado, o false si no
* @throws IllegalArgumentException si el contenedor es nulo
*/
public boolean colocarContenedor(Contenedor contenedor) {
if (this.contenedores.size() >= this.altura) {
return false;
}
if (this.contenedores.isEmpty() || this.ultimoContenedor().tieneTecho()) {
return this.contenedores.add(contenedor);
}
return false;
}
public void colocarContenedor(Contenedor contenedor) {
//Encapsulamos errores aunque para evitarlos en un futuro (si hay cambios)
if (contenedor == null)
throw new IllegalArgumentException("El contenedor no puede ser nulo");
/**
* Metodo que devuelve true o false si el contenedor que introducimos se encuentra en el nivel mas alto actual de la plaza, es decir, que
* es el ultimo contenedor apilado en esa plaza (sin necesidad que sea el maximo)
* @param codigoContenedor Codigo del contenedor que se comprueba si es el ultimo
* @return true si es el ultimo o false si no lo es.
*/
public boolean estaEnUltimoNivel(String codigoContenedor) {
return this.ultimoContenedor().getCodigo().equals(codigoContenedor);
if (contenedor.contenedorEnTransito())
throw new IllegalStateException("El Contenedor esta en transito, no se puede colocar");
if(this.contenedores.size() == this.altura)
throw new IllegalStateException("La plaza está llena");
if(!this.contenedores.get(this.contenedores.size()-1).tieneTecho())
throw new IllegalStateException("El ultimo contenedor no tiene techo");
if (this.contenedores.isEmpty() || (this.ultimoContenedor().tieneTecho() && this.contenedores.size() < this.altura)) {
this.contenedores.add(contenedor);
}
}
/**
* Metodo que desapila el contendor
* 1.1.12 Metodo que desapila el ultimo contendor
*/
public void desapilarContenedor() {
if(!this.contenedores.isEmpty())
this.contenedores.remove(contenedores.size() - 1);
}
/**
* Metod que devuelve el ultimo contenedor de la Plaza
* @return ultimo contenedor de la plaza o null si esta vacio
*/
public Contenedor ultimoContenedor() {
if (contenedores.isEmpty()) {
return null;
}
return contenedores.get(contenedores.size() -1);
}
/*********************************************
* OTROS METODOS DE LA PLAZA PARA SU GESTION *
*********************************************/
/**
* Metodo que devuelve el numero decontenedores
......@@ -120,19 +123,34 @@ public class Muelle {
}
/**
* Metodo que devuelve si una plaza esta vacia o no
* @return true si esta vacia o false si no lo esta
* Metodo que devuelve true o false si el contenedor que introducimos se encuentra en el nivel mas alto actual de la plaza, es decir, que
* es el ultimo contenedor apilado en esa plaza (sin necesidad que sea el maximo)
* @param codigoContenedor Codigo del contenedor que se comprueba si es el ultimo
* @return true si es el ultimo o false si no lo es.
*/
public boolean plazaVacia() {
return (this.contenedores.size() == 0) ? true : false;
public boolean estaEnUltimoNivel(String codigoContenedor) {
Contenedor c = this.ultimoContenedor();
return (c == null) ? false : c.getCodigo().equals(codigoContenedor);
}
/**
* Metodo que devuelve si una plaza esta llena o no
* @return true si la plaza esta llena o si no lo esta
* Metodo que indica si un contenedor se encuentra en la plaza o no
* @param codigo Codigo del contenedor que queremos buscar
* @return true si contiene ese contenedor en la Plaza o false si no lo tiene
*/
public boolean plazaLlena() {
return (this.contenedores.size() == this.altura || this.ultimoContenedor().tieneTecho()) ? true : false;
public boolean contieneContenedor(String codigo) {
return (this.nivelContenedor(codigo)!=-1) ? true : false;
}
/**
* Metod que devuelve el ultimo contenedor de la Plaza
* @return ultimo contenedor de la plaza o null si esta vacio
*/
public Contenedor ultimoContenedor() {
if (contenedores.isEmpty()) {
return null;
}
return contenedores.get(contenedores.size() -1);
}
}
......@@ -140,12 +158,11 @@ public class Muelle {
* Constructor del objeto Muelle
* @param identificador Identificador de 2 digitos (numeros)
* @param cord Punto GPS que lo localiza. Clase GPSCoordinate.
* @param operativo Estado del muelle.
* @param estadoActual Estado del muelle.
* @param plazas Numero de plazas totales que tiene el Muelle
* @param altura numero maximo de contenedores que se pueden apilar encima de otro
*/
//CHANGE BOOLEAN OPERATIVO FOR AN STATE OF ESTADO
public Muelle (String identificador, GPSCoordinate cord, boolean operativo, int plazas, int altura) {
public Muelle (String identificador, GPSCoordinate cord, estado estadoActual, int plazas, int altura) {
if(!comprobarValoresNulos(identificador, cord))
throw new IllegalArgumentException("Los valores del identificador y coordenada no pueden ser nulos");
if(!comprobarTamanyoAlturaPlazas(plazas, altura))
......@@ -156,13 +173,11 @@ public class Muelle {
this.identificador = identificador;
this.cord = cord;
this.plazas = new Plaza[plazas];
this.estadoActual = operativo ? estado.OPERATIVO : estado.FUERA_DE_SERVICIO;
this.estadoActual = estadoActual;
//Inicializamos el array de las plazas
for (int i = 0; i < plazas; i++) {
this.plazas[i] = new Plaza(altura);
}
}
/**
......@@ -251,7 +266,11 @@ public class Muelle {
* @return la plaza del contenedor o -1 si no se encuentra en ninguna plaza
*/
public int plazaActual(String codigo) {
this.comprobarCodigoContenedor(codigo);
if(codigo == null)
throw new IllegalArgumentException("El codigo no puede ser nulo");
if(!comprobarCodigoContenedor(codigo))
throw new IllegalArgumentException("El codigo de contenedor es incorrecto");
for (int i = 0; i < this.plazas.length; i++) {
if (this.plazas[i].numeroContenedores() != 0 && this.plazas[i].contieneContenedor(codigo)) {
return i;
......@@ -267,7 +286,10 @@ public class Muelle {
* @return el nivel en el que se encuentra el contenedor o -1 si no se encuentra
*/
public int nivelEnPlaza(String codigo) {
this.comprobarCodigoContenedor(codigo);
if(codigo == null)
throw new IllegalArgumentException("Codigo del contenedor no puede ser nulo");
if(!this.comprobarCodigoContenedor(codigo))
throw new IllegalArgumentException("El codigo de contenedor no tiene el formato correcto");
for (Plaza plaza : this.plazas) {
if (plaza.numeroContenedores() != 0 && plaza.contieneContenedor(codigo)) {
return plaza.nivelContenedor(codigo);
......@@ -280,52 +302,70 @@ public class Muelle {
* 1.1.11 Metodo para colocar un contenedor en una plaza y apilarlo si es posible
* @param codigo Codigo del contenedor que queremos colocar
* @param plaza La plaza del contenedor
* @throws IllegalArgumentException si el contenedor es nulo, si la plaza esta fuera de rango, si ese contenedor ya esta apilado
* Si ese contenedor essta en transito, si el contenedor donde se coloca encima no tiene techo o si la plaza
* esta llena
* @throws IllegalArgumentException si el contenedor es nulo
* @throws IllegalArgumentException si la plaza esta fuera de rango,
* @throws IllegalStateException si ese contenedor ya esta apilado
* @throws IllegalStateException si ese contenedor esta en transito,
* @throws IllegalStateException si el contenedor donde se coloca encima no tiene techo
* @throws IllegalStateException si la plaza esta llena
*/
public void colocarContenedorEnPlaza(Contenedor contenedor, int plaza) {
if (contenedor == null) throw new IllegalArgumentException("El Ccontenedor no puede ser nulo");
if (plaza < 0 || plaza > this.numeroDePlazasTotales()) throw new
IllegalArgumentException("La plaza debe de estar entre 0-"+ (this.plazas.length -1));
//Si ya esta apilado
if (contenedor.estadoApilado()) {
throw new IllegalArgumentException("El Contenedor ya esta apilado");
}
//Comprobamos si el contenedor es nulo o la plaza no pertenece al rango
if (contenedor == null)
throw new IllegalArgumentException("El Contenedor no puede ser nulo");
if (plaza < 0 || plaza > this.numeroDePlazasTotales())
throw new IllegalArgumentException("La plaza debe de estar entre 0-"+ (this.plazas.length -1));
//Si esta entransito
if (contenedor.estadoTransito()) {
throw new IllegalArgumentException("El Contenedor esta en transito, no se puede colocar");
if (contenedor.contenedorEnTransito()){
throw new IllegalStateException("El Contenedor esta en transito, no se puede colocar");
}
// Verificar si hay un último contenedor y si tiene techo
if (this.plazas[plaza].colocarContenedor(contenedor)) {
contenedor.cambiarEstadoApilado();
//Si ya se encuentra apilado el contenedor en el muelle
if (nivelEnPlaza(contenedor.getCodigo()) != -1) {
throw new IllegalStateException("El Contenedor ya esta apilado");
}
//Verificar si la plaza esta llena
Plaza p = this.plazas[plaza];
if(p.contenedores.size() == p.altura())
throw new IllegalStateException("La plaza está llena");
//Verificamos si el ultimo contenedor tiene techo
if(!p.ultimoContenedor().tieneTecho())
throw new IllegalStateException("El contenedor no tiene techo");
else{
if (!this.plazas[plaza].ultimoContenedor().tieneTecho())
throw new IllegalArgumentException("El contenedor no tiene techo");
throw new IllegalArgumentException("La plaza está llena");
this.plazas[plaza].colocarContenedor(contenedor);
}
}
/**
* 1.1.12 Metodo que sirve para sacar un contenedor de una Plaza y desapilarlo si es posible
* @param contenedor: Contenedor a desapilar de la plaza
* @throws IllegalArgumentException si el contenedor es nulo, si no se encuentra apilado en ningun sitio o
* si el contenedor no se encuentra en la ultima posicion (no se podria desapilar)
* @param contenedor Contenedor a desapilar de la plaza
* @throws IllegalArgumentException si el contenedor es nulo
* @throws IllegalStateException si el contenedor se encuentra en transito
* @throws IllegalStateException si el contenedor no se encuentra apilado en el muelle
* @throws IllegalStateException si el contenedor no se encuentra en la ultima plaza
*/
public void sacarContenedorDePlaza(Contenedor contenedor) {
if (contenedor == null) throw new IllegalArgumentException("El Ccontenedor no puede ser nulo");
if (!contenedor.estadoApilado()) throw new IllegalArgumentException("El Contenedor no esta en ninguna plaza. Se encuentra en transito o en recogida");
//Comprobamos que el contenedor no sea nulo o que esté en transito
if (contenedor == null)
throw new IllegalArgumentException("El Contenedor no puede ser nulo");
if (contenedor.contenedorEnTransito())
throw new IllegalStateException("El Contenedor se encuentra en transito");
String c = contenedor.getCodigo();
//Buscamos que el contenedor este en el muelle
if (plazaActual(c) == -1)
throw new IllegalStateException("El contenedor no se encuentra apilado en este muelle");
//Buscamos el contenedor y desapilamos el contenedor si se encuentra en el ultimo nivel
for (Plaza plaza : this.plazas) {
if (plaza.contieneContenedor(contenedor.getCodigo())) {
if (plaza.estaEnUltimoNivel(contenedor.getCodigo())) {
if (plaza.contieneContenedor(c)) {
if (plaza.estaEnUltimoNivel(c)) {
plaza.desapilarContenedor();
contenedor.cambiarEstadoDesapilado();
}
else {
throw new IllegalArgumentException("El Contenedor No esta en el ultimo nivel");
throw new IllegalStateException("El Contenedor no esta en el ultimo nivel, no se puede desapilar");
}
}
}
......@@ -341,11 +381,10 @@ public class Muelle {
/**
* Metodo que sirve para si un codigo de contenedor es correcto
* @param codigo Codigo del contenedor que se comprueba
* @throws IllegalArgumentException si el codigo es nulo o no corresponde a un codigo correcto
* @return true si el codigo es correcto o false si no lo es
*/
private void comprobarCodigoContenedor(String codigo) {
if (codigo == null) throw new IllegalArgumentException("Codigo no puede ser nulo");
if (!codigo.matches("[A-Z]{4}\\d{7}")) throw new IllegalArgumentException("El codigo no pertenece a un codigo de contenedor");
private boolean comprobarCodigoContenedor(String codigo) {
return (this.CODIGO_CONTENEDOR.matcher(codigo).matches()) ? true : false;
}
/**
......@@ -373,4 +412,3 @@ public class Muelle {
return this.cord;
}
}
\ No newline at end of file
......@@ -21,7 +21,7 @@ public class Puerto {
private final String ciudad;
private final List<Muelle> muelles = new ArrayList<>();
private final Pattern PAIS_REGUEX = Pattern.compile("[A-Za-z]{2}");
private final Pattern CIUDAD_REGUEX = Pattern.compile("[A-Za-z]{2}");
private final Pattern CIUDAD_REGUEX = Pattern.compile("[A-Za-z]{3}");
/**
......@@ -82,24 +82,6 @@ public class Puerto {
return this.muelles.removeIf(muelle -> muelle.getIdentificador().equals(id));
}
/**
* Metodo para comprobar si un muelle esta en ese puerto o no, para agregarle,
* ya que solo puede haber un muelle con el mismo identificador para cada puerto.
* @param m obtejo Muelle
* @return true si esta, y false si no se encuentra en el puerto
*/
public boolean comprobarMuelleEnPuerto(Muelle m) {
String id = m.getIdentificador();
GPSCoordinate cord = m.getGPSCoordinate();
//Para daca muelle comprobamos si hay alguno con el mismo id o las mismas coordenadas
for (Muelle muelle : this.muelles) {
if (id.equals(muelle.getIdentificador())|| (cord.getDistanceTo(muelle.getGPSCoordinate())==0)) {
return true;
}
}
return false;
}
/**
* 1.1.3 Metodo que comprueba si un puerto esta Lleno o no
* @return true (si esta lleno) o false (si no lo esta)
......@@ -169,6 +151,24 @@ public class Puerto {
return cercanos.toArray(new Muelle[0]);
}
/**
* Metodo para comprobar si un muelle esta en ese puerto o no, para agregarle,
* ya que solo puede haber un muelle con el mismo identificador para cada puerto.
* @param m obtejo Muelle
* @return true si esta, y false si no se encuentra en el puerto
*/
public boolean comprobarMuelleEnPuerto(Muelle m) {
String id = m.getIdentificador();
GPSCoordinate cord = m.getGPSCoordinate();
//Para daca muelle comprobamos si hay alguno con el mismo id o las mismas coordenadas
for (Muelle muelle : this.muelles) {
if (id.equals(muelle.getIdentificador())|| (cord.getDistanceTo(muelle.getGPSCoordinate())==0)) {
return true;
}
}
return false;
}
/**
* Metodo que devuelve el pais del puerto
* @return pais del perto
......
......@@ -3,6 +3,8 @@
*/
package es.markse;
import java.io.Serializable;
/**
* Implementacion de la clase Trayecto
* @author vicmtorm
......@@ -25,14 +27,31 @@ public class Trayecto {
* @param fechaFinTrayecto Fecha en la que finaliza un Trayecto
*/
public Trayecto (Muelle muelleOrigen, Puerto puertoOrigen, Fecha fechaInicioTrayecto, Muelle muelleDestino, Puerto puertoDestino, Fecha fechaFinTrayecto) {
disponibilidadMuelle(muelleOrigen);
disponibilidadMuelle(muelleDestino);
muellePerteneceAlPuerto(muelleOrigen,puertoOrigen);
muellePerteneceAlPuerto(muelleDestino,puertoDestino);
comprobacionMuellesDistintos(muelleOrigen, muelleDestino, puertoOrigen, puertoDestino);
comprobacionFecha(fechaInicioTrayecto);
comprobacionFecha(fechaFinTrayecto);
comprobacionOrdenFechas(fechaInicioTrayecto,fechaFinTrayecto);
//Comprobamos si los valores no son nulos
if(muelleOrigen == null || muelleDestino == null)
throw new IllegalArgumentException("Los muelles no pueden ser nulos");
if(puertoOrigen == null || puertoDestino == null)
throw new IllegalArgumentException("Los puertos no pueden ser nulos");
if(fechaInicioTrayecto == null || fechaFinTrayecto == null)
throw new IllegalArgumentException("Las fechas no pueden ser nulas");
//Comprobamos si los muelles estan operativos
if (!muelleOrigen.estaOperativo() || !muelleDestino.estaOperativo())
throw new IllegalStateException("El muelle de origen esta fuera de servicio");
if (!muelleDestino.estaOperativo())
throw new IllegalStateException("El muelle de destino esta fuera de servicio");
//Comprobamos si los muelles pertenecen al puerto
if (!puertoOrigen.comprobarMuelleEnPuerto(muelleOrigen))
throw new MuelleNoPerteneceAlPuertoException("El muelle no pertenece al puerto");
if (!puertoDestino.comprobarMuelleEnPuerto(muelleDestino))
throw new MuelleNoPerteneceAlPuertoException("El muelle no pertenece al puerto");
if (!comprobacionMuellesDistintos(muelleOrigen, muelleDestino, puertoOrigen, puertoDestino))
throw new IllegalStateException("El muelle de origen no puede ser igual al de destino");
if(comprobacionOrdenFechas(fechaInicioTrayecto,fechaFinTrayecto))
throw new IllegalArgumentException ("La Fecha del Inicio del Trayecto no puede ser posterior a la fecha del Fin del Trayecto");
this.muelleOrigen=muelleOrigen;
this.puertoOrigen=puertoOrigen;
this.fechaInicioTrayecto=fechaInicioTrayecto;
......@@ -41,123 +60,39 @@ public class Trayecto {
this.fechaFinTrayecto = fechaFinTrayecto;
}
/**
* Método que Devuelve el Muelle de Origen
* @return muelleOrigen
*/
public Muelle getMuelleOrigen() {
return this.muelleOrigen;
}
/**
* Método que Devuelve el Muelle de Destino
* @return muelleDestino
*/
public Muelle getMuelleDestino() {
return this.muelleDestino;
}
/**
* Método que Devuelve el Puerto de Origen
* @return puertoOrigen
*/
public Puerto getPuertoOrigen() {
return this.puertoOrigen;
}
/**
* Método que Devuelve el Puerto de Destino
* @return puertoDestino
*/
public Puerto getPuertoDestino() {
return this.puertoDestino;
}
/**
* Método que Devuelve la Fecha del Inicio del Trayecto
* @return fechaInicioTrayecto
*/
public Fecha getFechaInicioTrayecto() {
return this.fechaInicioTrayecto;
}
/**
* Método que Devuelve la Fecha del Fin del Trayecto
* @return fechaFinTrayecto
*/
public Fecha getFechaFinTrayecto() {
return this.fechaFinTrayecto;
}
/**
* Método que comprueba si un Muelle está Operativo o está Fuera de Servicio
* @param muelle Muelle para el que queremos conocer su disponibilidad
* @throws Illegal Argument Exception En el caso de que el Muelle se encuentre Fuera de Servicio
*/
private void disponibilidadMuelle(Muelle muelle) {
if (!muelle.estaOperativo()) throw new IllegalArgumentException ("¡El Muelle Introducido está Fuera de Servicio!");
}
/**
* Método que comprueba si un Muelle Introducido pertenece al Puerto Introducido
* @param muelle Tipo Muelle
* @param puerto Tipo Puerto
* @throws Illegal Argument Exception En el caso de que el Muelle no se encuentre en ese Puerto
*/
private void muellePerteneceAlPuerto(Muelle muelle, Puerto puerto) {
if (!puerto.comprobarMuelleEnPuerto(muelle))throw new IllegalArgumentException ("¡El Muelle Introducido no Pertenece al Puerto Introducido!");
}
/**
* Método que Comprueba si los Muelles Introducidos son Distintos o no
* @param muelleOrigen Muelle desde el que comienza el Trayecto
* @param muelleDestino Muelle en el que finaliza el Trayecto
* @throws IllegalArgumentException Si el Muelle de Origen y el Muelle de Destino son el Mismo
* @return true si los muelles son distintos o false si son los mismos
*/
private void comprobacionMuellesDistintos(Muelle muelleOrigen, Muelle muelleDestino, Puerto puertoOrigen, Puerto puertoDestino) {
private boolean comprobacionMuellesDistintos(Muelle muelleOrigen, Muelle muelleDestino, Puerto puertoOrigen, Puerto puertoDestino) {
if (muelleOrigen.getIdentificador() == muelleDestino.getIdentificador() && puertoOrigen.identificadorPuerto().equals(puertoDestino.identificadorPuerto())) {
throw new IllegalArgumentException ("¡El Muelle de Origen no puede ser igual al Muelle de Destino!");
}
}
/**
* Método que Comprueba si la Fecha Introducida al Declarar un nuevo Trayecto es válida o no
* @param fechaDada Fecha Introducida por el Usuario
* @throws IllegalArgumentException Si la Fecha a Comprobar es Nula
*/
private void comprobacionFecha(Fecha fechaDada) {
if (fechaDada == null) {
throw new IllegalArgumentException ("La Fecha introducida no puede ser nula");
return false;
}
return true;
}
/**
* Método que Comprueba si el Orden de las Fechas de Inicio y del Final del Trayecto es el adecuado.
* @throws IllegalArgumentException Si la Fecha del Inicio del Trayecto es Posterior a la Fecha del Fin del Trayecto, lo cual es Imposible.
*/
private void comprobacionOrdenFechas(Fecha fechaInicioTrayecto, Fecha fechaFinTrayecto) {
private boolean comprobacionOrdenFechas(Fecha fechaInicioTrayecto, Fecha fechaFinTrayecto) {
if (fechaInicioTrayecto.getDiasDesdeEpoch()>fechaFinTrayecto.getDiasDesdeEpoch()){
throw new IllegalArgumentException ("La Fecha del Inicio del Trayecto no puede ser posterior a la fecha del Fin del Trayecto");
return false;
}
return true;
}
/*********************************************
* IMPLEMENTACION DE FUNCIONALIDADES BASICAS *
*********************************************/
/**
* Método que indica si la Fecha de Fin de Trayecto es superior a una Fecha Dada
* 1.1.21 Método que indica si la Fecha de Fin de Trayecto es superior a una Fecha Dada
* @param fechaDada Fecha de Introducida por el usuario
* @return True si la Fecha de Fin de Trayecto es Superior, y False si la Fecha de Fin de Trayecto no es Superior
*/
public boolean FechaFinTrayectoSuperior(Fecha fechaDada) {
if (fechaDada == null) throw new IllegalArgumentException("Fecha no puede ser nula");
if (fechaFinTrayecto.getDiasDesdeEpoch()>fechaDada.getDiasDesdeEpoch()) {
......@@ -166,16 +101,14 @@ public class Trayecto {
else {
return true;
}
}
/**
* todo que, introduciendo el coste diario y el coste por milla, devuelve el precio calculado en Euros de un Trayecto
* 1.1.22. Metodo que, introduciendo el coste diario y el coste por milla, devuelve el precio calculado en Euros de un Trayecto
* @param costeDiarioTrayecto Valor en Euros del Coste Diario de un Trayecto
* @param costePorMilla Valor en Euros del Coste por Milla de un Trayecto
* @return Precio del Trayecto Calculado en Euros
*/
public double precioTrayectoEnEuros(double costeDiarioTrayecto, double costePorMilla) {
if (costeDiarioTrayecto <= 0) {
throw new IllegalArgumentException ("El Coste Diario del Trayecto no es válido");
......@@ -183,26 +116,23 @@ public class Trayecto {
else if(costePorMilla <= 0) {
throw new IllegalArgumentException ("El Coste por Milla del Trayecto no es válido");
}
int dias = (fechaFinTrayecto.getDiasDesdeEpoch()-fechaInicioTrayecto.getDiasDesdeEpoch())+1;
int dias = numeroDeDiasDeTrayceto();
double dist = distanciaMillasMarinas();
return ((dias*costeDiarioTrayecto)+(dist*costePorMilla));
}
/**
* Método que devuelve la Distancia calculada en Millas Marinas entre 2 Muelles Distintos
* 1.1.23 Método que devuelve la Distancia calculada en Millas Marinas entre 2 Muelles Distintos
* @return Distancia entre 2 Muelles Distintos calculada en Millas Marinas
*
*/
public double distanciaMillasMarinas() {
return muelleOrigen.getGPSCoordinate().getDistanceTo(muelleDestino.getGPSCoordinate());
}
/**
* Método que Proporciona Información acerca del Trayecto: Localidad y País de los Puertos de Origen y Destino, y Fechas de Inicio y Fin del Trayecto
* 1.1.24 Método que Proporciona Información acerca del Trayecto: Localidad y País de los Puertos de Origen y Destino, y Fechas de Inicio y Fin del Trayecto
* @return Información Sobre el Origen (Ciudad, Pais, Fecha Inicio) y el Destino (Ciudad, Pais, Fecha Fin)
*/
public String inforTrayecto() {
String ciudadOrig = this.puertoOrigen.ciudadDelPuerto();
String paisOrig = this.puertoOrigen.paisDelPuerto();
......@@ -210,8 +140,77 @@ public class Trayecto {
String ciudadDest = this.puertoDestino.ciudadDelPuerto();
String paisDest = this.puertoDestino.paisDelPuerto();
String FechaFin = this.fechaFinTrayecto.aCadena();
return"INFORMACION SOBRE EL ORIGEN: \nCiudad Origen: "+ciudadOrig+"\nPais Origen: "+paisOrig+"\nInicio del Trayecto: "+FechaInicio+
"\n\nINFORMACION SOBRE EL DESTINO: \nCiudad Destino: "+ciudadDest+"\nPais Destino: "+paisDest+"\nFin del Trayecto: "+FechaFin+"\n";
}
/*************************
* OTRAS FUNCIONALIDADES *
*************************/
/**
* Metodo que devuelve el numero de dias de un trayecto
*/
public int numeroDeDiasDeTrayceto(){
return (this.fechaFinTrayecto.getDiasDesdeEpoch()- this.fechaInicioTrayecto.getDiasDesdeEpoch()) +1;
}
/**
* Método que Devuelve el Muelle de Origen
* @return muelleOrigen
*/
public Muelle getMuelleOrigen() {
return this.muelleOrigen;
}
/**
* Método que Devuelve el Muelle de Destino
* @return muelleDestino
*/
public Muelle getMuelleDestino() {
return this.muelleDestino;
}
/**
* Método que Devuelve el Puerto de Origen
* @return puertoOrigen
*/
public Puerto getPuertoOrigen() {
return this.puertoOrigen;
}
/**
* Método que Devuelve el Puerto de Destino
* @return puertoDestino
*/
public Puerto getPuertoDestino() {
return this.puertoDestino;
}
/**
* Método que Devuelve la Fecha del Inicio del Trayecto
* @return fechaInicioTrayecto
*/
public Fecha getFechaInicioTrayecto() {
return this.fechaInicioTrayecto;
}
/**
* Método que Devuelve la Fecha del Fin del Trayecto
* @return fechaFinTrayecto
*/
public Fecha getFechaFinTrayecto() {
return this.fechaFinTrayecto;
}
/**
* Excpcion lanzada para indicar que un muelle no pertenece al puerto
* @author javcalv
* @author victorm
*/
public class MuelleNoPerteneceAlPuertoException extends RuntimeException implements Serializable{
private static final long serialVersionUID = 1L;
public MuelleNoPerteneceAlPuertoException(String m) {
super(m);
}
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment