Java tutorial
/* * Copyright 2015 (C) Manuel Domnguez Dorado - ingeniero@ManoloDominguez.com. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package simMPLS.scenario; import simMPLS.protocols.TAbstractPDU; import simMPLS.hardware.timer.TTimerEvent; import simMPLS.hardware.timer.ITimerEventListener; import simMPLS.hardware.ports.TPortSet; import simMPLS.utils.TMonitor; import simMPLS.utils.TLongIDGenerator; import java.awt.*; import java.util.*; import org.jfree.data.*; import org.jfree.chart.*; /** * Esta calse es abstracta y representa a un enlace de la topologa. * @author <B>Manuel Domnguez Dorado</B><br><A * href="mailto:ingeniero@ManoloDominguez.com">ingeniero@ManoloDominguez.com</A><br><A href="http://www.ManoloDominguez.com" target="_blank">http://www.ManoloDominguez.com</A> * @version 1.0 */ public abstract class TLink extends TTopologyElement implements Comparable, ITimerEventListener, Runnable { /** * Este mtodo es el constructor de la clase. Crea una nueva instancia de * TEnlaceTopologia. * @param identificador Identificador nico del enlace. * @param il Generador de identificadores para los eventos emitidos por el enlace. * @param t Topologa a la que pertenece el enlace. * @since 1.0 */ public TLink(int identificador, TLongIDGenerator il, TTopology t) { super(TTopologyElement.LINK, il); id = identificador; extremo1 = null; extremo2 = null; mostrarNombre = false; nombre = ""; delay = 1; puertoExtremo1 = -1; puertoExtremo2 = -1; buffer = Collections.synchronizedSortedSet(new TreeSet()); bufferLlegadosADestino = new TreeSet(); cerrojo = new TMonitor(); cerrojoLlegados = new TMonitor(); topologia = t; enlaceCaido = false; } /** * Este mtodo averigua si el enlace est caido o no. * @return TRUE, si el enlace est caido. FALSE en caso contrario. * @since 1.0 */ public boolean isBroken() { return enlaceCaido; } /** * Este mtodo compara la instancia actual con otro objeto del mismo tipo, para * averiguar la posicin ordinal de uno con respecto al otro. * @param o Enlace de la topologa con el que se va a comparar la instancia actual. * @return -1, 0 1, dependiendo de si la instancia actual es menor, igual o mayor que la * pasada por parmetro, en trminos de orden. * @since 1.0 */ public int compareTo(Object o) { TLink e = (TLink) o; if (getID() < e.getID()) return -1; else if (getID() == e.getID()) return 0; return 1; } /** * Este mtodo calcula qu porcentaje de trnsito le queda a un paquete concreto, * sabiendo que ha recorrido ya un porcentaje determinado. * @param cienxcien Cien por cien. * @param xxcien Equis por ciento. * @return Valor calculado. * @since 1.0 */ public long obtenerPorcentajeTransito(long cienxcien, long xxcien) { return ((cienxcien - xxcien) * 100) / cienxcien; } /** * Este mtodo calcula las coordenadas donde debe dibujarse un paquete que ha * recorrido ya un porcentaje concreto de su trnsito. * @since 1.0 * @param porcentaje Porcentaje recorrido ya por el paquete en el enlace. * @return Coordenadas donde dibujar el paquete. */ public Point obtenerCoordenadasPaquete(long porcentaje) { Point coordenadas = new Point(0, 0); int x1 = extremo1.obtenerPosicion().x + 24; int y1 = extremo1.obtenerPosicion().y + 24; int x2 = extremo2.obtenerPosicion().x + 24; int y2 = extremo2.obtenerPosicion().y + 24; coordenadas.x = x1; coordenadas.y = y1; int distanciaX = (x2 - x1); int distanciaY = (y2 - y1); coordenadas.x += (int) ((double) distanciaX * (double) porcentaje / (double) 100); coordenadas.y += (int) ((double) distanciaY * (double) porcentaje / (double) 100); return coordenadas; } /** * Este mtodo permite establecer la topologia a la que pertenece el enlace. * @param t Topologa a la que pertenece el enlace. * @since 1.0 */ public void ponerTopologia(TTopology t) { topologia = t; } /** * Este mtodo permite obtener la topologia a la que pertenece el enlace. * @return La topologa a la que pertenece el enlace. * @since 1.0 */ public TTopology obtenerTopologia() { return topologia; } /** * Este mtodo configura el enlace. * @since 1.0 * @param recfg TRUE, si se est reconfigurando el enlace. FALSE si se est configurando por * primera vez. * @param tcenlace Objeto de configuracin del enlace que contiene una configuracin para * el mismo. * @param topo Topologa a la que pertenece ele enlace. */ public void configurar(TLinkConfig tcenlace, TTopology topo, boolean recfg) { this.ponerNombre(tcenlace.obtenerNombre()); this.ponerMostrarNombre(tcenlace.obtenerMostrarNombre()); this.ponerDelay(tcenlace.obtenerDelay()); if (!recfg) { this.ponerExtremo1(topo.setFirstNodeNamed(tcenlace.obtenerNombreExtremo1())); this.ponerExtremo2(topo.setFirstNodeNamed(tcenlace.obtenerNombreExtremo2())); this.desconectarDePuertos(); this.ponerPuertoExtremo1(tcenlace.obtenerPuertoExtremo1()); TPortSet p1 = extremo1.getPorts(); if (p1 != null) { p1.connectLinkToPort(this, this.puertoExtremo1); } this.ponerPuertoExtremo2(tcenlace.obtenerPuertoExtremo2()); TPortSet p2 = extremo2.getPorts(); if (p2 != null) { p2.connectLinkToPort(this, this.puertoExtremo2); } } } /** * Este mtodo obtiene un objeto con la configuracin completa del enlace. * @return Configuracin completa del enlace. * @since 1.0 */ public TLinkConfig obtenerConfiguracion() { TLinkConfig tce = new TLinkConfig(); tce.ponerNombre(this.obtenerNombre()); tce.ponerMostrarNombre(this.obtenerMostrarNombre()); if (this.getEnd1() != null) tce.ponerNombreExtremo1(this.getEnd1().getName()); if (this.getEnd2() != null) tce.ponerNombreExtremo2(this.getEnd2().getName()); tce.ponerDelay(this.obtenerDelay()); tce.ponerPuertoExtremo1(this.obtenerPuertoExtremo1()); tce.ponerPuertoExtremo2(this.obtenerPuertoExtremo2()); return tce; } /** * Este mtodo libera el enlace, desconectndolo de los posibles nodos a los que * est "enganchado". * @since 1.0 */ public void desconectarDePuertos() { if (extremo1 != null) { TPortSet p1 = extremo1.getPorts(); if (p1 != null) { p1.disconnectLinkFromPort(this.puertoExtremo1); } } if (extremo2 != null) { TPortSet p2 = extremo2.getPorts(); if (p2 != null) { p2.disconnectLinkFromPort(this.puertoExtremo2); } } } /** * Este mtodo establece el retardo del enlace. * @param d Retardo del enlace. * @since 1.0 */ public void ponerDelay(int d) { if (d <= 0) { delay = 1; } else { delay = d; } } /** * Este mtodo obtiene el retardo del enlace. * @return Retardo del enlace. * @since 1.0 */ public int obtenerDelay() { return delay; } /** * Este mtodo establece el identificador nico del enlace. * @param identificador Identificador del enlace. * @since 1.0 */ public void ponerIdentificador(int identificador) { id = identificador; } /** * Este mtodo permite obtener el identificador nico del enlace. * @return Identificador unico del enlace. * @since 1.0 */ public int getID() { return id; } /** * Este mtodo permite establecer el nombre del enlace. * @param nom Nombre del enlace. * @since 1.0 */ public void ponerNombre(String nom) { nombre = nom; } /** * Este mtodo permite obtener el nombre del enlace. * @return Nombre del enlace. * @since 1.0 */ public String obtenerNombre() { return nombre; } /** * Este mtodo permite especificar si el nombre del enlace se ha de ver o no. * @param m TRUE, si el nombre debe mostrarse. FALSE en caso contrario. * @since 1.0 */ public void ponerMostrarNombre(boolean m) { mostrarNombre = m; } /** * Este mtodo permite obtener si el nombre del enlace se ha de ver o no. * @return TRUE, si el nombre se esta mostrando. FALSE en caso contrario. * @since 1.0 */ public boolean obtenerMostrarNombre() { return mostrarNombre; } /** * Este mtodo obtiene el nodo que est al final del extremo izquierdo del enlace. * @return El nodo extremo izquierdo del enlace. * @since 1.0 */ public TNode getEnd1() { return extremo1; } /** * Este mtodo permite establecer el nodo que estar conectado al extremo izquierdo * del enlace. * @param e1 Nodo que estar conectado al extremo izquierdo del enalace. * @since 1.0 */ public void ponerExtremo1(TNode e1) { extremo1 = e1; } /** * Este mtodo obtiene el nodo que est al final del extremo derecho del enlace. * @return El nodo del extremo derecho del enlace. * @since 1.0 */ public TNode getEnd2() { return extremo2; } /** * Este mtodo permite establecer el nodo que estar conectado al extremo derecho * del enlace. * @param e2 Nodo del extremo derecho del enlace. * @since 1.0 */ public void ponerExtremo2(TNode e2) { extremo2 = e2; } /** * Este mtodo obtiene la posicin del extremo izquierdo del enlace. * @return Posicion del extremo izquierdo del enlace. * @since 1.0 */ public Point obtenerPosicion1() { return extremo1.obtenerPosicion(); } /** * Este mtodo establece el puerto del nodo extremo izquierdo al que est conectado * el enlace. * @param p Puerto del nodo extremo izquierdo. * @since 1.0 */ public void ponerPuertoExtremo1(int p) { puertoExtremo1 = p; } /** * Este mtodo permite obtener el puerto del nodo extremo izquierdo al que est * conectado el enlace. * @return Puerto del nodo extremo izquierdo. * @since 1.0 */ public int obtenerPuertoExtremo1() { return puertoExtremo1; } /** * Este mtodo establece el puerto del nodo extremo derecho al que est conectado * el enlace. * @param p Puerto del nodo extremo derecho. * @since 1.0 */ public void ponerPuertoExtremo2(int p) { puertoExtremo2 = p; } /** * Este mtodo permite obtener el puerto del nodo extremo derecho al que est * conectado el enlace. * @return Puerto del nodo extremo derecho. * @since 1.0 */ public int obtenerPuertoExtremo2() { return puertoExtremo2; } /** * Este mtodo obtiene la posicin del nodo extremo derecho del enlace. * @return Posicin del nodo extremo derecho del enlace. * @since 1.0 */ public Point obtenerPosicion2() { return extremo2.obtenerPosicion(); } /** * Este mtodo comprueba si el enlace est conectad a un nodo concreto. * @param extremo Nodo al que se desea saber si el enlace est conectado o no. * @return TRUE, si est conectado. FALSE en caso contrario. * @since 1.0 */ public boolean conectadoA(TNode extremo) { if (extremo1.getID() == extremo.getID()) return true; if (extremo2.getID() == extremo.getID()) return true; return false; } /** * Este mtodo comprueba si el enlace est conectad a un nodo concreto. * @param idExtremo Identificador del nodo al que se desea saber si el enlace est conectado o no. * @return TRUE, si est conectado. FALSE en caso contrario. * @since 1.0 */ public boolean conectadoA(int idExtremo) { if (extremo1.getID() == idExtremo) return true; if (extremo2.getID() == idExtremo) return true; return false; } /** * Este mtodo coloca un paquete desde el enlace al nodo destino. * @param paquete Paquete que se desea trasladar. * @param destino Nodo destino del paquete en el enlace. * @since 1.0 */ public void carryPacket(TAbstractPDU paquete, int destino) { cerrojo.lock(); getBuffer().add(new TLinkBufferEntry(paquete, this.obtenerDelay(), destino)); cerrojo.unLock(); } /** * Este mtodo comprueba si dada unas coordenadas, el enlace pasa por dicha posicin. * @param p Posicin. * @return TRUE, si el enlace pasa por esa posicin. FALSE en caso contrario. * @since 1.0 */ public boolean estaEnPosicion(Point p) { int x1 = extremo1.obtenerPosicion().x + 24; int y1 = extremo1.obtenerPosicion().y + 24; int x2 = extremo2.obtenerPosicion().x + 24; int y2 = extremo2.obtenerPosicion().y + 24; int dx, dy, pasos, k; double incrementox, incrementoy, x, y; if ((x1 == x2) && (y1 == y2)) // Para lneas que son slo un punto. { if ((p.x == x1) && (p.y == y1)) return true; } else // Para el resto de lneas. { dx = x2 - x1; dy = y2 - y1; if (Math.abs(dx) > Math.abs(dy)) pasos = Math.abs(dx); else pasos = Math.abs(dy); incrementox = (float) dx / pasos; incrementoy = (float) dy / pasos; x = x1; y = y1; if ((x >= p.x - 3) && (x <= p.x + 3) && (y >= p.y - 3) && (y <= p.y + 3)) { return true; } for (k = 1; k <= pasos; k++) { x += incrementox; y += incrementoy; if ((x >= p.x - 3) && (x <= p.x + 3) && (y >= p.y - 3) && (y <= p.y + 3)) { return true; } } } return false; } /** * Este mtodo devuelve el cerrojo del enlace. * @return El cerrojo del enlace. * @since 1.0 */ public TMonitor obtenerCerrojo() { return this.cerrojo; } /** * Este mtodo comprueba cul de los dos extremos del enlace es el nodo pasado por * parmetro. * @param n Nodo que realiza la consulta. * @return END_NODE_1, si el nodo es el extremo 1. END_NODE_2 si es el extremo 2. * @since 1.0 */ public int queExtremoSoyYo(TNode n) { if (n.getID() == extremo1.getID()) return TLink.END_NODE_1; return TLink.END_NODE_2; } /** * Este mtodo calcula a qu extremo del enlace se debe enviar un paquete dado el * nodo quelo enva. * @param n Nodo que enva el paquete y que hace la consulta. * @return END_NODE_1 si el paquete debe ir al extremo 1. EXTREMO 2 si debe ir al extremo 2. * @since 1.0 */ public int getTargetNodeIDOfTrafficSentBy(TNode n) { if (n.getID() == extremo1.getID()) return TLink.END_NODE_2; return TLink.END_NODE_1; } /** * Este mtodo calcula a qu extremo del enlace se debe enviar un paquete dado el * nodo quelo enva. * @param n Nodo que enva el paquete y que hace la consulta. * @return END_NODE_1 si el paquete debe ir al extremo 1. EXTREMO 2 si debe ir al extremo 2. * @since 1.0 */ public TNode getTargetNodeOfTrafficSentBy(TNode n) { if (n.getID() == extremo1.getID()) return extremo2; return extremo1; } /** * @return the buffer */ public SortedSet getBuffer() { return buffer; } /** * @param buffer the buffer to set */ public void setBuffer(SortedSet buffer) { this.buffer = buffer; } /** * Este mtodo devuelve el tipo del enlace. * @return Ser redefinido por las subclases. * @since 1.0 */ public abstract int getLinkType(); /** * Este mtodo captura un evento de reloj lo que pone en funcionamiento al enlace. * @param evt Evento de reloj. * @since 1.0 */ public abstract void receiveTimerEvent(TTimerEvent evt); /** * Ncleo del enlace. Aqu se codificar (en las subclases) toda la funcionalidad. * @since 1.0 */ public abstract void run(); /** * Este mtodo obtiene el peso del enlace. Que ser usado por los algoritmos de * encaminamiento. * @return Peso del enlace. * @since 1.0 */ public abstract long obtenerPeso(); /** * Este mtodo obtiene el peso del enlace. Que ser usado por el algoritmos de * encaminamiento RABAN. El peso incluye diversos factores y no exclusivamente * el retardo del enlace. * @return Peso del enlace. * @since 1.0 */ public abstract long obtenerPesoRABAN(); /** * Este mtodo calcula si est bien configurado el enlace. * @return TRUE, si est bien configurado. FALSE en caso contrario. * @since 1.0 */ public abstract boolean isWellConfigured(); /** * Este metodo devolver un mensaje de error asociado a un codigo de error. * @param e Codigo de error. * @return Representacin textual del cdigo de error. * @since 1.0 */ public abstract String getErrorMessage(int e); /** * Este mtodo serializa el enlace; es decir, lo convierte a texto para ser volcado * a disco. * @return Representacin textual del enlace. * @since 1.0 */ public abstract String marshall(); /** * Este mtodo deserializa un enlace y lo construye en memoria. * @param elemento Enlace serializado. * @return TRUE, si todo va bien. FALSE si no se ha podido deserializar el enlace. * @since 1.0 */ public abstract boolean unMarshall(String elemento); /** * Este mtodo establece si el enlace est cao o no. * @param ec TRUE, si el enlace debe aparecer como caido. FALSE en caso contrario. * @since 1.0 */ public abstract void ponerEnlaceCaido(boolean ec); /** * Este mtodo reinicia los atributos de la clase, dejando el enlace como recien * creado por el constructor. * @since 1.0 */ public abstract void reset(); /** * Esta constante identifica a un enlace interno al dominio MPLS. * @since 1.0 */ public static final int INTERNAL = 0; /** * Est constante identifica a un enlace externo al dominio MPLS. * @since 1.0 */ public static final int EXTERNAL = 1; /** * Esta constante se usa para identificar el extremo inicial del enlace. * @since 1.0 */ public static final int END_NODE_1 = 1; /** * Esta constante se usa para identificar el extremo final del enlace. * @since 1.0 */ public static final int END_NODE_2 = 2; private int id; private TNode extremo1; private TNode extremo2; private int puertoExtremo1; private int puertoExtremo2; private String nombre; private boolean mostrarNombre; private int delay; /** * Este atributo almacena los paquetes en el enlace para simular su recorrido por * el mismo. * @since 1.0 */ private SortedSet buffer; /** * Este atributo almacena temporalmente los paquetes que han llegado al destinio. * @since 1.0 */ protected TreeSet bufferLlegadosADestino; /** * Este atributo es el monitor de la clase que permite sincronizaciones. * @since 1.0 */ protected TMonitor cerrojo; /** * Este atributo es el monitor de la clase que permite sincronizaciones en el * buffer de paquetes lelgados al destino. * @since 1.0 */ protected TMonitor cerrojoLlegados; /** * Topologa a la cual pertenece el enlace. * @since 1.0 */ protected TTopology topologia; /** * Indica si el enlace est funcionando o est caido. * @since 1.0 */ protected boolean enlaceCaido; /** * Esta constante se usa para indicar que la configuracin del enlace es correcta. * @since 1.0 */ public static final int CORRECTA = 0; /** * Esta constante se usa para indicar que la configuracin del enlace es incorrecta. * Falta el nombre. * @since 1.0 */ public static final int SIN_NOMBRE = 1; /** * Esta constante se usa para indicar que la configuracin del enlace es incorrecta. * El nombre solo est formado por espacios. * @since 1.0 */ public static final int SOLO_ESPACIOS = 2; /** * Esta constante se usa para indicar que la configuracin del enlace es incorrecta. * Ya hay un elemento con el nombre de este enlace. * @since 1.0 */ public static final int NOMBRE_YA_EXISTE = 3; /** * Esta constante se usa para indicar que la configuracin del enlace es incorrecta. * no se ha especificado el puerto de origen. * @since 1.0 */ public static final int FALTA_PUERTO_1 = 4; /** * Esta constante se usa para indicar que la configuracin del enlace es incorrecta. * No se ha especificado el puerto de destino. * @since 1.0 */ public static final int FALTA_PUERTO_2 = 5; /** * Esta constante se usa para indicar que la configuracin del enlace es incorrecta. * No se ha especificado el nodo origen. * @since 1.0 */ public static final int FALTA_EXTREMO_1 = 6; /** * Esta constante se usa para indicar que la configuracin del enlace es incorrecta. * No se ha especificado el nodo destino. * @since 1.0 */ public static final int FALTA_EXTREMO_2 = 7; }