Agregada documentacion a las clases del framework

This commit is contained in:
Daniel Cortés
2019-07-07 17:34:35 -04:00
parent 137bb7c9e1
commit 66f0c20276
14 changed files with 205 additions and 48 deletions

View File

@@ -2,7 +2,15 @@ package xyz.danielcortes.framework;
import javax.swing.JPanel; import javax.swing.JPanel;
/**
* Clase que deben extender todo los paneles de paneles
*/
public abstract class BasePanel { public abstract class BasePanel {
/**
* Entrega el panel que contiene todo el contenido de la vista
*
* @return JPanel con el contenido de la vista
*/
public abstract JPanel getContentPane(); public abstract JPanel getContentPane();
} }

View File

@@ -1,27 +1,50 @@
package xyz.danielcortes.framework; package xyz.danielcortes.framework;
import java.util.Collection;
import java.util.List; import java.util.List;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.PersistenceException; import javax.persistence.PersistenceException;
import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaQuery;
/**
* Repositorio generico que implementa la funcionalidad basica de obtener, guardar, editar y eliminar un modelo
*
* @param <E> Modelo sobre el cual trabaja
* <p>
* TODO Seria bueno que al mismo tiempo como ahora se crean transacciones en cada operacion, el que la clase permite crear transacciones manualmente
* cuando se vea necesario
*/
public abstract class BaseRepository<E> { public abstract class BaseRepository<E> {
protected EntityManager em; protected EntityManager em;
private Class<E> entityClass; private Class<E> entityClass;
/**
* Crea un repositorio que desarrollara queries con la entityClass entregada
*
* @param entityClass Clase a la que pertenece el modelo con el que se trabajara
*/
public BaseRepository(Class<E> entityClass) { public BaseRepository(Class<E> entityClass) {
this.em = PersistenceManager.getEntityManager(); this.em = PersistenceManager.getEntityManager();
this.entityClass = entityClass; this.entityClass = entityClass;
} }
/**
* Realiza la query que obtiene todos los elementos existentes de la <code>entity</code
*
* @return La lista con todos los elementos de la entidad <code>E</code>
*/
public List<E> getAll() { public List<E> getAll() {
CriteriaQuery<E> criteriaQuery = this.em.getCriteriaBuilder().createQuery(this.entityClass); CriteriaQuery<E> criteriaQuery = this.em.getCriteriaBuilder().createQuery(this.entityClass);
criteriaQuery.select(criteriaQuery.from(this.entityClass)); criteriaQuery.select(criteriaQuery.from(this.entityClass));
return this.em.createQuery(criteriaQuery).getResultList(); return this.em.createQuery(criteriaQuery).getResultList();
} }
/**
* Guarda una entidad dentro de una transaccion
*
* @param entity Entidad a guardar
*/
public void save(E entity) { public void save(E entity) {
this.em.getTransaction().begin(); this.em.getTransaction().begin();
@@ -35,6 +58,12 @@ public abstract class BaseRepository<E> {
this.em.getTransaction().commit(); this.em.getTransaction().commit();
} }
/**
* Guarda una lista de entidades dentro de una transaccion
*
* @param entities Lista de entidades a guardar
*/
public void save(List<E> entities) { public void save(List<E> entities) {
this.em.getTransaction().begin(); this.em.getTransaction().begin();
@@ -48,6 +77,12 @@ public abstract class BaseRepository<E> {
this.em.getTransaction().commit(); this.em.getTransaction().commit();
} }
/**
* Actualiza una entidad dentro de una transaccion
*
* @param entity Entidad a actualizar
*/
public void update(E entity) { public void update(E entity) {
this.em.getTransaction().begin(); this.em.getTransaction().begin();
@@ -61,6 +96,11 @@ public abstract class BaseRepository<E> {
this.em.getTransaction().commit(); this.em.getTransaction().commit();
} }
/**
* Actualiza una lista de entidades dentro de una transaccion
*
* @param entities Lista de entidades a guardar
*/
public void update(List<E> entities) { public void update(List<E> entities) {
this.em.getTransaction().begin(); this.em.getTransaction().begin();
@@ -74,6 +114,11 @@ public abstract class BaseRepository<E> {
this.em.getTransaction().commit(); this.em.getTransaction().commit();
} }
/**
* Elimina una entidad dentro de una transaccion
*
* @param entity Entidad a guardar
*/
public void delete(E entity) { public void delete(E entity) {
this.em.getTransaction().begin(); this.em.getTransaction().begin();
@@ -87,6 +132,11 @@ public abstract class BaseRepository<E> {
this.em.getTransaction().commit(); this.em.getTransaction().commit();
} }
/**
* Elimina una lista de entidades dentro de una transaccion
*
* @param entities Lista de entidades a guardar
*/
public void delete(List<E> entities) { public void delete(List<E> entities) {
this.em.getTransaction().begin(); this.em.getTransaction().begin();
@@ -99,19 +149,4 @@ public abstract class BaseRepository<E> {
this.em.getTransaction().commit(); this.em.getTransaction().commit();
} }
public void delete(Collection<E> entities) {
this.em.getTransaction().begin();
try {
for (E e : entities) {
this.em.remove(e);
}
} catch (PersistenceException e) {
e.printStackTrace();
this.em.getTransaction().rollback();
}
this.em.getTransaction().commit();
}
} }

View File

@@ -21,13 +21,16 @@ public class BaseTableModel<T> extends AbstractTableModel {
* posicion de la tabla. * posicion de la tabla.
* *
* @param columns Lista de columnas que tendra la tabla de la forma: {"Columna 1", "Columna 2", "Columna 3"}; * @param columns Lista de columnas que tendra la tabla de la forma: {"Columna 1", "Columna 2", "Columna 3"};
* @param valueAt TriFunction la cual recibe por parametros: - La lista de filas de la tabla - Un Integer indicando la fila del que se necesita el * @param valueAt TriFunction la cual recibe por parametros:
* valor - Un Integer indicando la columna de la que se necesita el valor Y esta debe retornar un objeto con toString para poder ser mostrado en la
* tabla
* <p> * <p>
* Se sugiere el siguiente tipo de implementacion para la funcion (row, rowIndex, colIndex) -> { switch (colIndex) { case 0: return * - La lista de filas de la tabla - Un Integer indicando la fila del que se necesita el valor - Un Integer indicando la columna de la que se
* row.get(rowIndex).getColumn1(); case 1: return row.get(rowIndex).getColumn2(); case 2: return row.get(rowIndex).getColumn3(); case 3: return * necesita el valor Y esta debe retornar un objeto con toString para poder ser mostrado en la tabla
* row.get(rowIndex).getColumn4(); } return null; } * <p>
* Se sugiere el siguiente tipo de implementacion para la funcion
* <code>
* (row, rowIndex, colIndex) -> { switch (colIndex) { case 0: return row.get(rowIndex).getColumn1(); case 1: return row.get(rowIndex).getColumn2();
* case 2: return row.get(rowIndex).getColumn3(); case 3: return row.get(rowIndex).getColumn4(); } return null; }
* </code>
*/ */
public BaseTableModel(String[] columns, TriFunction<List<T>, Integer, Integer, Object> valueAt) { public BaseTableModel(String[] columns, TriFunction<List<T>, Integer, Integer, Object> valueAt) {
super(); super();
@@ -41,6 +44,11 @@ public class BaseTableModel<T> extends AbstractTableModel {
return this.columns[index]; return this.columns[index];
} }
/**
* Añade una nueva fila a la tabla
*
* @param item Objeto a añadir
*/
public void addRow(T item) { public void addRow(T item) {
this.rows.add(item); this.rows.add(item);
this.fireTableRowsInserted(this.getRowCount() - 1, this.getRowCount() - 1); this.fireTableRowsInserted(this.getRowCount() - 1, this.getRowCount() - 1);
@@ -61,11 +69,21 @@ public class BaseTableModel<T> extends AbstractTableModel {
return this.valueAt.apply(this.rows, rowIndex, columnIndex); return this.valueAt.apply(this.rows, rowIndex, columnIndex);
} }
/**
* Remueve una fila dada su index en la tabla
*
* @param row Fila a remover
*/
public void removeRow(int row) { public void removeRow(int row) {
this.rows.remove(row); this.rows.remove(row);
this.fireTableRowsDeleted(row, row); this.fireTableRowsDeleted(row, row);
} }
/**
* Remueve una fila de la tabla
*
* @param t item a eliminar
*/
public void removeRow(T t) { public void removeRow(T t) {
int removed = this.rows.indexOf(t); int removed = this.rows.indexOf(t);
if (removed != -1) { if (removed != -1) {
@@ -74,6 +92,12 @@ public class BaseTableModel<T> extends AbstractTableModel {
} }
} }
/**
* Obtiene el objeto que contiene la row
*
* @param row fila de la que se quiere obtener el objeto
* @return El objeto contenido en la fila
*/
public T getRow(int row) { public T getRow(int row) {
if (row > -1 && row < this.getRowCount()) { if (row > -1 && row < this.getRowCount()) {
return this.rows.get(row); return this.rows.get(row);
@@ -82,16 +106,27 @@ public class BaseTableModel<T> extends AbstractTableModel {
} }
} }
/**
* @return Todas las filas existentes
*/
public List<T> getRows() { public List<T> getRows() {
return this.rows; return this.rows;
} }
/**
* En vez de agregar las filas una por una agrega todas en una sola funcion
*
* @param items Lista de objetos a agregar
*/
public void setRows(List<T> items) { public void setRows(List<T> items) {
this.removeRows(); this.removeRows();
this.rows.addAll(items); this.rows.addAll(items);
this.fireTableRowsInserted(0, this.getRowCount() - 1); this.fireTableRowsInserted(0, this.getRowCount() - 1);
} }
/**
* Remueve todas las filas de la tabla
*/
public void removeRows() { public void removeRows() {
int rowCount = this.getRowCount(); int rowCount = this.getRowCount();
if (rowCount > 0) { if (rowCount > 0) {

View File

@@ -3,6 +3,12 @@ package xyz.danielcortes.framework;
import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener; import javax.swing.event.DocumentListener;
/**
* <code>Listener</code>que extiende de <code>DocumentListener</code>, delegando todos los metodos que tiene este a uno solo
* Es mas que nada para comodidad de implementacion con un solo lambda
*
* @see DocumentListener
*/
public interface ChangeListener extends DocumentListener { public interface ChangeListener extends DocumentListener {
@Override @Override
@@ -20,5 +26,8 @@ public interface ChangeListener extends DocumentListener {
this.changed(e); this.changed(e);
} }
/**
* <code>Listener</code> que se ejecutara en cualquier tipo de cambio en un <code>Document</code>
*/
void changed(DocumentEvent e); void changed(DocumentEvent e);
} }

View File

@@ -3,6 +3,9 @@ package xyz.danielcortes.framework;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.util.Properties; import java.util.Properties;
/**
* Clase que carga la configuracion desde el properties <code>configuration.properties</code>
*/
public class Config { public class Config {
private static Properties defaultProps = new Properties(); private static Properties defaultProps = new Properties();
@@ -20,6 +23,12 @@ public class Config {
private Config() { private Config() {
} }
/**
* Obtiene una propiedad dada su key
*
* @param key nombre de la propiedad
* @return La propiedad entregada o null si no existe
*/
public static String get(String key) { public static String get(String key) {
return defaultProps.getProperty(key); return defaultProps.getProperty(key);
} }

View File

@@ -8,15 +8,6 @@ public class GeneralValidator {
private GeneralValidator() { private GeneralValidator() {
} }
public static boolean isLong(String number) {
try {
Long.parseLong(number);
} catch (NumberFormatException e) {
return false;
}
return true;
}
public static boolean isInteger(String number) { public static boolean isInteger(String number) {
try { try {
Integer.parseInt(number); Integer.parseInt(number);

View File

@@ -4,11 +4,20 @@ import java.util.List;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.ListModel; import javax.swing.ListModel;
/**
* Clase que existe como helper para <code>JList</code>
*/
public class JListUtils { public class JListUtils {
private JListUtils() { private JListUtils() {
} }
/**
* Setea una serie de items seleccionados dentro de la jlist entregada
*
* @param list JList en la que se seleccionaran los elementos
* @param values La lista de elementos que se seleccionaran
*/
public static void setSelectedValues(JList list, List values) { public static void setSelectedValues(JList list, List values) {
list.clearSelection(); list.clearSelection();
for (Object value : values) { for (Object value : values) {
@@ -20,6 +29,13 @@ public class JListUtils {
list.ensureIndexIsVisible(list.getSelectedIndex()); list.ensureIndexIsVisible(list.getSelectedIndex());
} }
/**
* Obtiene el index del objeto entregado dentro de la jlist
*
* @param model ListModel que tiene el objeto buscado
* @param value El objeto al cual se le busca el index
* @return El index del elemento, si no existe, se retornara -1
*/
private static int getIndex(ListModel model, Object value) { private static int getIndex(ListModel model, Object value) {
if (value == null) { if (value == null) {
return -1; return -1;

View File

@@ -12,7 +12,7 @@ public class LoggedEvent extends EventObject {
/** /**
* Crea el objeto y almacena los datos entregados * Crea el objeto y almacena los datos entregados
* * <p>
* El metodo lanza un {@code IllegalArgumentException} en caso que {@code source} y {@code user} sean nulos. * El metodo lanza un {@code IllegalArgumentException} en caso que {@code source} y {@code user} sean nulos.
* *
* @param source El objeto en el que el evento se origino * @param source El objeto en el que el evento se origino
@@ -24,6 +24,9 @@ public class LoggedEvent extends EventObject {
this.user = user; this.user = user;
} }
/**
* @return El usuario que fue logeado
*/
public Usuario getUser() { public Usuario getUser() {
return this.user; return this.user;
} }

View File

@@ -1,5 +1,8 @@
package xyz.danielcortes.framework; package xyz.danielcortes.framework;
/**
* Enum que lista todos los paneles existentes en la aplicacion
*/
public enum PanelName { public enum PanelName {
EMPTY, EMPTY,

View File

@@ -8,6 +8,9 @@ import java.util.Random;
import javax.crypto.SecretKeyFactory; import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEKeySpec;
/**
* Clase encargada de crear y comparar contraseñas de forma segura
*/
public class Passwords { public class Passwords {
private static final Random RANDOM = new SecureRandom(); private static final Random RANDOM = new SecureRandom();
@@ -17,12 +20,25 @@ public class Passwords {
private Passwords() { private Passwords() {
} }
/**
* Genera aleatoriamente un <code>byte[]</code> de tamaño 16
*
* @return El <code>byte[]</code> generados
*/
public static byte[] getNextSalt() { public static byte[] getNextSalt() {
byte[] salt = new byte[16]; byte[] salt = new byte[16];
RANDOM.nextBytes(salt); RANDOM.nextBytes(salt);
return salt; return salt;
} }
/**
* Compara 2 constraseñas, la primera sin hashear aun y la segunda ya hasheada
*
* @param password <code>char[]</code> que contiene la contraseña sin hashear aun
* @param salt <code>byte[]</code> que contiene la sal con la que juntar la contraseña al momento de hashearla
* @param expectedHash <code>byte[]</code> con una contraseña ya hasheada con la que comprar
* @return un boleano indicando que las constraseñas son iguales o no
*/
public static boolean isExpectedPassword(char[] password, byte[] salt, byte[] expectedHash) { public static boolean isExpectedPassword(char[] password, byte[] salt, byte[] expectedHash) {
byte[] pwdHash = hash(password, salt); byte[] pwdHash = hash(password, salt);
Arrays.fill(password, Character.MIN_VALUE); Arrays.fill(password, Character.MIN_VALUE);
@@ -35,6 +51,13 @@ public class Passwords {
return true; return true;
} }
/**
* Hashea una contraseña.
*
* @param password <code>char[]</code> con la contraseña a hashear
* @param salt <code>byte[]</code> con la salt que se le aplicara a la contraseña
* @return <code>byte[]</code> con la constraseña hasheada
*/
public static byte[] hash(char[] password, byte[] salt) { public static byte[] hash(char[] password, byte[] salt) {
PBEKeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, KEY_LENGHT); PBEKeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, KEY_LENGHT);
Arrays.fill(password, Character.MIN_VALUE); Arrays.fill(password, Character.MIN_VALUE);

View File

@@ -4,6 +4,9 @@ import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence; import javax.persistence.Persistence;
/**
* Clase que inicia el PersistenceManager
*/
public class PersistenceManager { public class PersistenceManager {
private static EntityManagerFactory factory; private static EntityManagerFactory factory;
@@ -17,17 +20,10 @@ public class PersistenceManager {
private PersistenceManager() { private PersistenceManager() {
} }
/**
* @return El <code>EntityManager</code>
*/
public static EntityManager getEntityManager() { public static EntityManager getEntityManager() {
return em; return em;
} }
public static void close() {
if (factory != null) {
factory.close();
}
if (em != null) {
em.close();
}
}
} }

View File

@@ -1,5 +1,13 @@
package xyz.danielcortes.framework; package xyz.danielcortes.framework;
/**
* Interfaz funcional que puede tomar 3 valores como input
*
* @param <A> Clase del primer valor
* @param <B> Clase del segundo valor
* @param <C> Clase del tercer valor
* @param <D> Clase del valor a retornar
*/
public interface TriFunction<A, B, C, D> { public interface TriFunction<A, B, C, D> {
D apply(A a, B b, C c); D apply(A a, B b, C c);

View File

@@ -9,24 +9,26 @@ public class ValidationResult {
private String title; private String title;
private boolean hasError; private boolean hasError;
/**
* Crea una instancia con valores por default, estos indican que no existe error en la validacion
*/
private ValidationResult() { private ValidationResult() {
this.hasError = false; this.hasError = false;
this.message = "No hubo error"; this.message = "No hubo error";
this.title = "Info"; this.title = "Info";
} }
/**
* Crea una instancia con un mensaje entregado, el resto de los campos indican que existe un error
*
* @param message Mensaje que corresponde con el error
*/
public ValidationResult(String message) { public ValidationResult(String message) {
this.title = "Error"; this.title = "Error";
this.message = message; this.message = message;
this.hasError = true; this.hasError = true;
} }
public ValidationResult(String message, String title) {
this.title = title;
this.message = message;
this.hasError = true;
}
public String getMessage() { public String getMessage() {
return this.message; return this.message;
} }
@@ -39,6 +41,9 @@ public class ValidationResult {
return this.hasError; return this.hasError;
} }
/**
* Muestra con <code>JOptionPane:showMessageDialog</code> el mensaje indicado al momento de la creacion de la instancia
*/
public void showErrorDialog() { public void showErrorDialog() {
if (this.hasError) if (this.hasError)
JOptionPane.showMessageDialog( JOptionPane.showMessageDialog(

View File

@@ -3,9 +3,18 @@ package xyz.danielcortes.framework;
import java.time.Year; import java.time.Year;
import javax.persistence.AttributeConverter; import javax.persistence.AttributeConverter;
/**
* Converter para JPA Convierte un entre <code>Year</code> y <code>Integer</code>
*/
public class YearAttributeConverter implements AttributeConverter<Year, Integer> { public class YearAttributeConverter implements AttributeConverter<Year, Integer> {
/**
* Convierte un <code>Year</code> en un Integer
*
* @param year Año a transformar
* @return el año reperesentado en un integer
*/
@Override @Override
public Integer convertToDatabaseColumn(Year year) { public Integer convertToDatabaseColumn(Year year) {
if (year != null) if (year != null)
@@ -14,6 +23,13 @@ public class YearAttributeConverter implements AttributeConverter<Year, Integer>
return null; return null;
} }
/**
* Convierte un integer en un <code>Year</code>
*
* @param integer Integer a transformar
* @return El <code>Year</code> correspondiente al integer entregado
*/
@Override @Override
public Year convertToEntityAttribute(Integer integer) { public Year convertToEntityAttribute(Integer integer) {
if (integer != null) if (integer != null)