01. Temática y Motivación
Contexto
El proyecto consiste en un sistema de gestión de inventario técnico para equipamiento de gimnasios, resolviendo la necesidad de un control preciso sobre máquinas y mantenimiento.
Muchos centros hoy dependen de documentación física desactualizada, dificultando la toma de decisiones sobre optimización de espacio y reposición.
Motivación Personal
02. Arquitectura de Entidades
Root Element
Gimnasio
Contenedor global XML
Main Object
Máquina
ID, Nombre, Marca, Categoria
Complex Type
Dimensiones
Ancho, Largo, Alto (decimal)
Restricted Type
Dificultad
SimpleType Range [1-3]
Diagrama Conceptual
Gimnasio
└── List maquinas // 1..N
└── Maquina
├── int id
├── String nombre
├── String marca
├── String modelo
├── String categoria
├── Dimensiones dimensiones
│ ├── double ancho
│ ├── double largo
│ └── double alto
├── int dificultad // valores permitidos: 1..3
└── List listaMusculos // 1..N
03. Implementación de Métodos
cargarDatos()
public void cargarDatos() throws JAXBException {
JAXBContext context = JAXBContext.newInstance(Gimnasio.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
File file = new File(rutaXML);
if (file.exists()) {
this.miGimnasio = (Gimnasio) unmarshaller.unmarshal(file);
}
}
guardarDatos()
public void guardarDatos() throws JAXBException {
JAXBContext context = JAXBContext.newInstance(Gimnasio.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB\_FORMATTED\_OUTPUT, true);
marshaller.marshal(miGimnasio, new File(rutaXML));
}
aniadirMaquina()
public void aniadirMaquina(TipoMaquina m) {
miGimnasio.getMaquina().add(m);
}
eliminarMaquina(int id)
public boolean eliminarMaquina(int id) {
return miGimnasio.getMaquina().removeIf(m -> m.getId() == id);
}
buscarPorDificultad(int nivel)
public List<TipoMaquina> buscarPorDificultad(int nivel) {
return miGimnasio.getMaquina().stream()
.filter(m -> m.getDificultad() == nivel)
.collect(Collectors.toList());
}
contarPorMusculo(String musculo)
public long contarPorMusculo(String musculo) {
return miGimnasio.getMaquina().stream()
.filter(m -> m.getListaMusculos().getMusculo().contains(musculo))
.count();
}
filtrarPorAnchoMaximo(double ancho)
public List filtrarPorAnchoMaximo(double ancho) {
return miGimnasio.getMaquina().stream()
.filter(m -> m.getDimensiones().getAncho().doubleValue() <= ancho)
.collect(Collectors.toList());
}
ActualizarPorDificultad(int id, int nuevaDificultad)
public void actualizarDificultad(int id, int nuevaDificultad) {
miGimnasio.getMaquina().stream()
.filter(m -> m.getId() == id)
.findFirst()
.ifPresent(m -> m.setDificultad(nuevaDificultad));
}
}
Se han implementado 8 métodos CRUD y estadísticos utilizando Java Streams.
04. Esquema XSD
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Elemento Raíz -->
<xs:element name="gimnasio">
<xs:complexType>
<xs:sequence>
<xs:element name="maquina" type="tipoMaquina" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- Entidad Principal -->
<xs:complexType name="tipoMaquina">
<xs:sequence>
<xs:element name="id" type="xs:int"/>
<xs:element name="nombre" type="xs:string"/>
<xs:element name="marca" type="xs:string"/>
<xs:element name="modelo" type="xs:string"/>
<xs:element name="categoria" type="xs:string"/>
<xs:element name="dimensiones" type="tipoDimensiones"/>
<xs:element name="dificultad" type="tipoDificultad"/>
<xs:element name="listaMusculos" type="tipoMusculos"/>
</xs:sequence>
</xs:complexType>
<!-- Tipos Complejos -->
<xs:complexType name="tipoDimensiones">
<xs:sequence>
<xs:element name="ancho" type="xs:decimal"/>
<xs:element name="largo" type="xs:decimal"/>
<xs:element name="alto" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="tipoMusculos">
<xs:sequence>
<xs:element name="musculo" type="xs:string" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- Tipo Simple con Restricciones -->
<xs:simpleType name="tipoDificultad">
<xs:restriction base="xs:int">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="3"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
05. Esquema XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<gimnasio>
<maquina>
<id>1</id>
<nombre>Prensa de Piernas Pro</nombre>
<marca>Matrix</marca>
<modelo>G7-S70</modelo>
<categoria>Fuerza</categoria>
<dimensiones>
<ancho>1.20</ancho>
<largo>2.10</largo>
<alto>1.50</alto>
</dimensiones>
<dificultad>3</dificultad>
<listaMusculos>
<musculo>Cuádriceps</musculo>
<musculo>Glúteo</musculo>
</listaMusculos>
</maquina>
<maquina>
<id>2</id>
<nombre>Cinta de Correr Skillrun</nombre>
<marca>Technogym</marca>
<modelo>SK-2024</modelo>
<categoria>Cardio</categoria>
<dimensiones>
<ancho>0.90</ancho>
<largo>2.00</largo>
<alto>1.70</alto>
</dimensiones>
<dificultad>1</dificultad>
<listaMusculos>
<musculo>Corazón</musculo>
<musculo>Gemelos</musculo>
</listaMusculos>
</maquina>
</gimnasio>
06. Clase Main
package org.example;
import java.util.List;
public class Main {
public static void main(String[] args) {
try {
UtilGimnasio gestor = new UtilGimnasio();
// Cargar lo que haya en el XML
gestor.cargarDatos();
System.out.println("--- DATOS CARGADOS DEL XML ---");
// Probar búsqueda (Método 5)
System.out.println("\nMáquinas de dificultad nivel 3:");
gestor.buscarPorDificultad(3)
.forEach(m -> System.out.println("- " + m.getNombre()));
// Probar estadística (Método 6)
System.out.println("\nNúmero de máquinas para 'Glúteo': "
+ gestor.contarPorMusculo("Glúteo"));
// Probar modificación (Método 8)
gestor.actualizarDificultad(1, 3);
System.out.println("\nDificultad de la máquina ID 1 actualizada.");
// Guardar los cambios de vuelta al XML
gestor.guardarDatos();
System.out.println("\nCambios guardados correctamente en gimnasio.xml");
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
}
07. Resultados Esperados
La ejecución del Main produce la siguiente salida:
--- DATOS CARGADOS DEL XML --- Máquinas de dificultad nivel 3: - Jaula de Potencia MultiRack Número de máquinas para 'Glúteo': 1 Dificultad de la máquina ID 1 actualizada. Cambios guardados correctamente en gimnasio.xml
08. IA & Autoría
Uso de Claude (IA)
"Se ha utilizado como asistente para lluvia de ideas en funcionalidades y revisión de sintaxis de Streams. El modelado XSD y la lógica JAXB han sido desarrollados íntegramente de forma manual."
Declaración de Autoría
- Comprendo cada línea de código.
- Capaz de explicar cualquier método.
- Trabajo académico genuino.
Conclusiones Finales
XML y JAXB demuestran ser tecnologías robustas en escenarios que requieren estructura formal y validación estricta. El dominio de equipamiento deportivo permite aplicar complejidad técnica en un caso de uso práctico y real.