chore(java): consolidate mss-failsafe to single canonical copy
Replace the stale multi-module java/mss-failsafe skeleton (old user-management prototype) with the active single-module machine-safety inspection app that was living in its own standalone repo at the repo root. - Remove old java/mss-failsafe/ multi-module tree (mss, userdata, userManagement, mssfailsafe.datalayer, mssfailsafeWeblayer) incl. committed build artifacts - Add the active app (PrimeFaces 11 / JSF 2.3 / Hibernate 5.6 / iText / POI) flattened into java/mss-failsafe/ as the only mss-failsafe in git - Working tree captured = master tip 2a142b5 + in-progress uncommitted work (incl. .github/*.instructions.md AI-context files) - Archive the standalone repo's 33-commit history in GIT_HISTORY_ARCHIVE.md since its .git was not migrated This is the source of truth / base for the upcoming upgraded rewrite.
This commit is contained in:
+84
@@ -0,0 +1,84 @@
|
|||||||
|
# AI Context Instructions
|
||||||
|
|
||||||
|
## Essentials
|
||||||
|
- Base Classes: AbstractEntity, AbstractManager<T>, AbstractController<E>
|
||||||
|
- Fake ID Mechanismus für neue Objekte
|
||||||
|
- Hibernate.initialize für Lazy Collections
|
||||||
|
# Architecture Instructions
|
||||||
|
## Typical Generation Tasks
|
||||||
|
1. Neue Domain (Entity/Manager/Controller/XHTML)
|
||||||
|
2. PDF Utility Erweiterung (iText7)
|
||||||
|
3. Sammel-Speichern (saveAll) bereitstellen
|
||||||
|
4. Klon-Operationen (IDs null setzen, Collections duplizieren kontrolliert)
|
||||||
|
5. Fragebogen Zuordnung (add/remove, available list)
|
||||||
|
|
||||||
|
## Edge Cases
|
||||||
|
- Null Entities im save -> return false
|
||||||
|
- Negative IDs beim remove -> zuerst persistieren oder aus UI entfernen
|
||||||
|
- Concurrency Refresh: Nach batch Änderungen refreshSelected()
|
||||||
|
|
||||||
|
## Do / Don't
|
||||||
|
- DO: Logging bei jeder Exception
|
||||||
|
- DO: Konsistente Nutzung von @Transactional bei Schreiboperationen
|
||||||
|
- DON'T: System.out oder ungefangene Exceptions durchreichen ohne Logging
|
||||||
|
- DON'T: Business Logik direkt in XHTML Event Handler schreiben
|
||||||
|
|
||||||
|
## Upgrade Ideas
|
||||||
|
- Exception Layer
|
||||||
|
- Bean Validation
|
||||||
|
- Service Layer zwischen Controller und Manager falls Logik wächst
|
||||||
|
|
||||||
|
---
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
Verdichtete Architekturhinweise für automatische Code-Generierung und schnelle Orientierung.
|
||||||
|
|
||||||
|
## Stack
|
||||||
|
- Java EE 8 (javax), WAR
|
||||||
|
- JSF 2.3 + PrimeFaces 11 + PrimeFlex 2.0
|
||||||
|
- Hibernate JPA (Persistence Unit: pu_person)
|
||||||
|
- Log4j2
|
||||||
|
|
||||||
|
## Layer
|
||||||
|
1. View (XHTML)
|
||||||
|
2. Controller (JSF/CDI Beans, extends AbstractController<E>)
|
||||||
|
3. Business (Stateless EJB Manager, extends AbstractManager<T>)
|
||||||
|
4. Persistence (JPA Entities, extends AbstractEntity)
|
||||||
|
|
||||||
|
## Base Classes
|
||||||
|
- AbstractManager<T>: CRUD (save, saveAll, refresh, remove), flush nach Persist/Merge.
|
||||||
|
- AbstractController<E>: UI State (selected, created, entities), Messages, PDF Utilities, Fake-ID-Erzeugung.
|
||||||
|
|
||||||
|
## Entity Lifecycle UI
|
||||||
|
- Neue Objekte: erhalten negative Fake-ID
|
||||||
|
- Vor Persist: negative IDs -> null setzen
|
||||||
|
- save/saveAll entscheidet anhand id == null zwischen persist/merge
|
||||||
|
|
||||||
|
## Lazy Loading
|
||||||
|
- Refresh via AbstractManager.refresh(entity) + Hibernate.initialize(entity)
|
||||||
|
- Für Collections: dedizierte reload Methoden (z.B. SecurityAreaManager.reloadWithQuestionnaires)
|
||||||
|
|
||||||
|
## PDF
|
||||||
|
- iText7 bevorzugt; Altbestand iText5 (itextpdf 5.5.13) kann später entfernt werden.
|
||||||
|
|
||||||
|
## Logging & Fehler
|
||||||
|
- LOGGER.error(e) bei Fehlern
|
||||||
|
- Aktuell viele bool Rückgaben; Verbesserungspotential: BusinessException
|
||||||
|
|
||||||
|
## Erweiterung Pattern
|
||||||
|
Entity -> Manager -> Controller -> XHTML
|
||||||
|
|
||||||
|
## Schulden / Verbesserungen
|
||||||
|
- Mischung iText5/7
|
||||||
|
- Inkonsistente Fehlerbehandlung
|
||||||
|
- Kein DTO Layer
|
||||||
|
- Wenige Tests
|
||||||
|
|
||||||
|
## Empfehlungen für Generator
|
||||||
|
- Bestehende Signaturen unverändert lassen
|
||||||
|
- @Transactional nur bei Schreibmethoden hinzufügen
|
||||||
|
- Collections initialisieren bevor darauf iteriert wird
|
||||||
|
|
||||||
|
---
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
+75
@@ -0,0 +1,75 @@
|
|||||||
|
# Architecture Instructions
|
||||||
|
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
|
|
||||||
|
## Überblick
|
||||||
|
Das System folgt einer klassischen 4-Layer Struktur:
|
||||||
|
1. View: JSF 2.3 / PrimeFaces 11 / XHTML Seiten (Formulare, Tabellen, Dialoge)
|
||||||
|
2. Controller: CDI/JSF Managed Beans, Zustandsverwaltung & UI-Aktionen (extends AbstractController<E>)
|
||||||
|
3. Business: Stateless EJB Manager mit CRUD + Fachlogik (extends AbstractManager<T>)
|
||||||
|
4. Persistence: JPA Entities (extends AbstractEntity)
|
||||||
|
|
||||||
|
## Basisklassen Rollen
|
||||||
|
- AbstractEntity: Basis-ID (Long, Identity), Timestamps, outdated Flag, equals/hashCode nur über ID.
|
||||||
|
- AbstractManager<T>: CRUD, save vs saveAll, remove / removeAllIn, refresh (Hibernate.initialize), Fehlerlogging.
|
||||||
|
- AbstractController<E>: UI State (selected, created, entities), Fake-ID-Erzeugung für neue temporäre Objekte, Messaging, PDF Utilities.
|
||||||
|
|
||||||
|
## Lebenszyklus eines neuen Objekts
|
||||||
|
1. UI erzeugt neues Objekt (id == null) -> Controller kann negative Fake-ID setzen falls in Collections benötigt.
|
||||||
|
2. Vor persist: Falls id < 0 -> setId(null) damit JPA Identity funktioniert.
|
||||||
|
3. save(): id == null => persist + flush, sonst merge + flush.
|
||||||
|
4. refresh(): sorgt für Managed Entity + Initialisierung Lazy Properties.
|
||||||
|
|
||||||
|
## Negative Fake IDs
|
||||||
|
- Zweck: Temporäre Unterscheidung mehrerer neu angelegter Einträge im UI bevor persist.
|
||||||
|
- Erzeugung: createFakeID(Collection<E>) nimmt kleinste vorhandene negative ID - 1.
|
||||||
|
- Vor persist unbedingt auf null setzen.
|
||||||
|
|
||||||
|
## Lazy Loading & Refresh
|
||||||
|
- Manager.refresh(entity) -> merge + Hibernate.initialize(entity) für Entität.
|
||||||
|
- Für Collections: spezielle Reload-Methoden in fachlichen Managern (z.B. reloadWithQuestionnaires).
|
||||||
|
- Nach Batch-Operationen Controller.refrehSelected() (Tippfehler) nutzen; perspektivisch in refreshSelected() umbenennen.
|
||||||
|
|
||||||
|
## Transaktionen
|
||||||
|
- Schreiboperationen annotiert mit @Transactional (Container-managed) in AbstractManager.save / saveAll.
|
||||||
|
- Fachmethoden, die persistieren oder mergen, sollten ebenfalls @Transactional erhalten (Konsistenz).
|
||||||
|
|
||||||
|
## Fehlerbehandlung
|
||||||
|
- Aktuell: Logging (LOGGER.error) + bool Rückgabe.
|
||||||
|
- Geplant: Einführung BusinessException für differenzierte Fehlerpfade.
|
||||||
|
|
||||||
|
## Erweiterungsmuster (Domain hinzufügen)
|
||||||
|
1. Entity erstellen (extends AbstractEntity). Optional Named Queries.
|
||||||
|
2. Manager: @Stateless extends AbstractManager<NewEntity>; spezifische Queries / Reload Methoden.
|
||||||
|
3. Controller: @Named + Scope (ViewScoped/SessionScoped) extends AbstractController<NewEntity>.
|
||||||
|
4. XHTML Seite inkl. Referenzen zu Controller (DataTable, Dialoge, Commands).
|
||||||
|
5. Tests: CRUD & fachliche Spezialfunktionen.
|
||||||
|
|
||||||
|
## Typische Fachfunktionen
|
||||||
|
- Klonen: Quelle re-laden + initialisieren; neue Instanz mit Copy-Konstruktor; Child IDs null; Collections duplizieren kontrolliert.
|
||||||
|
- Zuordnungen (z.B. Fragebogen): Add/Remove Pattern über Wrapper Entity.
|
||||||
|
|
||||||
|
## PDF-Erstellung
|
||||||
|
- iText7 Nutzung über Hilfsmethoden in AbstractController (Tabellen, Inner Cells, Paginierung).
|
||||||
|
- Keine neuen Features mehr mit iText5 API implementieren.
|
||||||
|
|
||||||
|
## Querschnittsthemen & Roadmap
|
||||||
|
- Vereinheitlichte Exception Layer.
|
||||||
|
- Bean Validation (javax.validation) für Eingaben & persistente Konsistenz.
|
||||||
|
- Test Suite (JUnit + ggf. Arquillian / Integrationstests) ausbauen.
|
||||||
|
- Migration nach Jakarta EE (Namespace Wechsel javax -> jakarta) perspektivisch.
|
||||||
|
|
||||||
|
## Edge Cases & Hinweise
|
||||||
|
- save(null) => false zurückgeben.
|
||||||
|
- remove(entity) ohne persistierte ID => false.
|
||||||
|
- Batch Speichern: leere Liste => true (no-op) statt Fehler.
|
||||||
|
- Collections initialisieren vor Iteration (Avoid LazyInitializationException).
|
||||||
|
|
||||||
|
## Generator Leitplanken
|
||||||
|
- Bestehende Signaturen respektieren.
|
||||||
|
- Keine neuen Frameworks ohne Notwendigkeit.
|
||||||
|
- Logging immer via LOGGER, niemals System.out.
|
||||||
|
- Für neue Write-Methoden @Transactional hinzufügen.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
# Cloning Instructions
|
||||||
|
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
|
|
||||||
|
## Ziel
|
||||||
|
Sicheres Klonen von komplexen Domains (z.B. SecurityArea inkl. Sub-Entities) ohne ID-Kollisionen oder versehentliches Persistieren historischer Referenzen.
|
||||||
|
|
||||||
|
## Grundprinzipien
|
||||||
|
- Nur persistente Quelle klonen (ID > 0) -> Vorher `refresh` zur Initialisierung Lazy Collections.
|
||||||
|
- Neue Instanzen erhalten `id = null` (oder negative Fake-ID falls im UI direkt angezeigt).
|
||||||
|
- Child-Entitäten ebenfalls mit `id = null` erzeugen.
|
||||||
|
|
||||||
|
## Vorgehen (Muster)
|
||||||
|
1. Quelle laden (Manager.find) & `refresh`.
|
||||||
|
2. Copy-Konstruktor oder Factory-Methode: Primitive Felder kopieren, Collections iterieren.
|
||||||
|
3. Collections: Neue Collection erzeugen, für jedes Kind tiefes Copy erstellen (kein Reuse Managed Instanz!).
|
||||||
|
4. IDs aller Kinder null setzen.
|
||||||
|
5. Optionale Anpassungen (Name -> "Kopie von <original>").
|
||||||
|
6. Rückgabe unverpersistiertes Root-Objekt an Controller.
|
||||||
|
|
||||||
|
## Tiefe vs. Flache Kopie
|
||||||
|
- Tiefe Kopie: Notwendig wenn Kinder eigenständige persistente Entities sind.
|
||||||
|
- Flache Kopie: Ausreichend falls nur Referenzen (Read-Only) erhalten bleiben sollen; aktuell bevorzugt tiefe Kopie für isolierte Bearbeitung.
|
||||||
|
|
||||||
|
## Edge Cases
|
||||||
|
- Quelle == null -> abort.
|
||||||
|
- Quelle mit Lazy Collections nicht initialisiert -> Gefahr LazyInitializationException.
|
||||||
|
- Zyklische Referenzen -> sorgfältig verhindern Endlosschleifen (ggf. bereits geklonte Instanzen in Map tracken).
|
||||||
|
|
||||||
|
## Fake IDs
|
||||||
|
- Wenn Klon direkt in UI Collection erscheint: negative ID via `createFakeID` generieren.
|
||||||
|
- Vor persist -> ID auf null setzen.
|
||||||
|
|
||||||
|
## Verbesserungen
|
||||||
|
- Einführung eines generischen `CloneService` mit rekursiver Strategie und Zyklus-Erkennung.
|
||||||
|
- Annotation @SkipClone für Felder die nicht übernommen werden sollen.
|
||||||
|
|
||||||
|
## Generator Leitplanken
|
||||||
|
- Keine Reflection-Magie für tiefe Kopien; lieber explizite Copy-Konstruktoren für Lesbarkeit.
|
||||||
|
- Reihenfolge: zuerst Root, dann Kinder.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
# Coding Guidelines Instructions
|
||||||
|
|
||||||
|
## Naming
|
||||||
|
- Manager: *Manager
|
||||||
|
- Controller: *Controller
|
||||||
|
- Entities: Singular Substantive
|
||||||
|
- Negative IDs: temporäre Objekte
|
||||||
|
|
||||||
|
## Style
|
||||||
|
- 4 Spaces
|
||||||
|
- Logger statt System.out
|
||||||
|
- Deutsche UI-Texte, Englisch im Code
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
- Log + Rückgabe (bestehend); für neue komplexe Logik optional BusinessException
|
||||||
|
|
||||||
|
## Persistenz
|
||||||
|
- Neue Entity: id == null vor persist
|
||||||
|
- refresh(entity) nutzen um Lazy Collections zu initialisieren
|
||||||
|
|
||||||
|
## Transaktionen
|
||||||
|
- Schreibmethoden: @Transactional (oder rely auf EJB Container)
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
- Sammeloperationen: saveAll(Collection<T>)
|
||||||
|
|
||||||
|
## UI
|
||||||
|
- PrimeFaces Dialoge schließen mit closeDialogs
|
||||||
|
- Negative IDs in Listen bis Sammelspeichern
|
||||||
|
|
||||||
|
## PDF
|
||||||
|
- Neue Funktionen nur mit iText7 API
|
||||||
|
|
||||||
|
## Tests (Empfehlung)
|
||||||
|
- CRUD Manager Tests
|
||||||
|
- Klon & Fragebogen Zuordnung
|
||||||
|
|
||||||
|
## Anti-Pattern
|
||||||
|
- Logik nicht direkt im Controller wenn generell wiederverwendbar
|
||||||
|
- Keine duplizierten Query Strings -> Named Queries
|
||||||
|
|
||||||
|
---
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
# Error Handling Instructions
|
||||||
|
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
|
|
||||||
|
## Aktueller Zustand
|
||||||
|
- Fehler werden in Managern primär über `LOGGER.error(e)` geloggt.
|
||||||
|
- Rückgabe bool (true/false) signalisiert Erfolg/Misserfolg.
|
||||||
|
- Keine differenzierte Fehlerklassifikation (Business vs. System).
|
||||||
|
|
||||||
|
## Ziele
|
||||||
|
- Konsistente Behandlung & klare Trennung der Fehlerarten.
|
||||||
|
- Verbesserte Diagnose für Nutzer & Logs.
|
||||||
|
|
||||||
|
## Kategorien
|
||||||
|
1. Validation Errors (Bean Validation zukünftig) -> Nutzerfeedback.
|
||||||
|
2. Business Rule Violations -> eigene Exception (z.B. `BusinessException`).
|
||||||
|
3. System Errors (DB Down, Hibernate Exceptions) -> Logging + generische Fehlermeldung.
|
||||||
|
|
||||||
|
## Kurzfristige Empfehlungen
|
||||||
|
- Bei allen catch-Blöcken: `LOGGER.error("<Kontext>", e)` statt nur `LOGGER.error(e)`.
|
||||||
|
- Controller: Nach boolean false -> `errorMessage()` anzeigen.
|
||||||
|
|
||||||
|
## Einführung BusinessException (geplant)
|
||||||
|
- Checked oder Runtime? Vorschlag: Runtime zur vereinfachten Nutzung.
|
||||||
|
- Manager Methoden können `throw new BusinessException("Message")` statt false.
|
||||||
|
- Controller fängt BusinessException und zeigt spezifische Nachricht.
|
||||||
|
|
||||||
|
## Log Format
|
||||||
|
- Kontext + Entity-ID + Operation.
|
||||||
|
Beispiel: `LOGGER.error("Failed to persist SecurityArea id={} name={}", area.getId(), area.getName(), e);`
|
||||||
|
|
||||||
|
## Edge Cases
|
||||||
|
- Null Übergaben -> früh validieren & BusinessException werfen (später) / false zurückgeben (jetzt).
|
||||||
|
- Sammeloperation: Teilfehler -> aktuell Abort bei erstem Fehler. Optional Sammeln & Aggregatfehler.
|
||||||
|
|
||||||
|
## Verbesserungen
|
||||||
|
- Central Exception Mapper (JSF PhaseListener / CDI Interceptor).
|
||||||
|
- Korrelation IDs in Logs (Request ID, User ID).
|
||||||
|
|
||||||
|
## Generator Leitplanken
|
||||||
|
- Logging immer, auch bei ignorable Exceptions.
|
||||||
|
- Keine System.out Nutzung.
|
||||||
|
- Fehler nicht stillschweigend verschlucken (mindestens loggen).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
# Extend Project Instructions
|
||||||
|
|
||||||
|
## Pattern
|
||||||
|
Entity -> Manager -> Controller -> XHTML -> Navigation
|
||||||
|
|
||||||
|
## Steps (Template)
|
||||||
|
1. Entity: @Entity extends AbstractEntity
|
||||||
|
2. Manager: @Stateless extends AbstractManager<Entity>
|
||||||
|
3. Controller: @Named + Scope extends AbstractController<Entity>
|
||||||
|
4. UI: xhtml mit #{controller}
|
||||||
|
5. Tests: CRUD + Spezialmethoden
|
||||||
|
|
||||||
|
## Fake IDs
|
||||||
|
- Neue Objekte in Collections: negative ID (createFakeID)
|
||||||
|
- Vor Persist: setId(null)
|
||||||
|
|
||||||
|
## Klonen
|
||||||
|
- Quelle laden & initialisieren
|
||||||
|
- Copy-Konstruktor
|
||||||
|
- Child IDs null
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
- [ ] Named Queries falls benötigt
|
||||||
|
- [ ] Logging bei Fehlern
|
||||||
|
- [ ] @Transactional bei Schreibmethoden
|
||||||
|
- [ ] Keine System.out
|
||||||
|
|
||||||
|
## Common Pitfalls
|
||||||
|
- LazyInitializationException -> refresh
|
||||||
|
- Vergessen negative IDs zurückzusetzen -> Persist fehlschlägt
|
||||||
|
|
||||||
|
---
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
# General Project Instructions
|
||||||
|
|
||||||
|
## Quick Facts
|
||||||
|
- Java EE 8 (javax) / Java 11 / WAR
|
||||||
|
- JSF + PrimeFaces + PrimeFlex
|
||||||
|
- Persistence Unit: pu_person
|
||||||
|
- Logging: Log4j2
|
||||||
|
|
||||||
|
## Build
|
||||||
|
mvn clean package -> target/mss-1.0-SNAPSHOT.war
|
||||||
|
|
||||||
|
## Core Patterns
|
||||||
|
- Manager: CRUD + Fachmethoden (extends AbstractManager)
|
||||||
|
- Controller: UI State + Messages + PDF (extends AbstractController)
|
||||||
|
- Negative IDs für temporäre Objekte
|
||||||
|
|
||||||
|
## PDF
|
||||||
|
- iText7 bevorzugen; Legacy iText5 entfernen später
|
||||||
|
|
||||||
|
## Improvements Roadmap
|
||||||
|
- Vereinheitlichte Exception Strategie
|
||||||
|
- Test Suite aufbauen
|
||||||
|
- Migration nach Jakarta EE (Namespace Wechsel)
|
||||||
|
|
||||||
|
## AI Generation Hints
|
||||||
|
- Halte Signaturen stabil
|
||||||
|
- Keine neuen Frameworks
|
||||||
|
- Initialisiere Lazy Collections vor Nutzung
|
||||||
|
|
||||||
|
---
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
# Index Instructions
|
||||||
|
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
|
|
||||||
|
Zentraler Überblick über alle *.instructions.md Dateien im Ordner `.github` für automatische Nutzung.
|
||||||
|
|
||||||
|
## Übersicht Bestehend
|
||||||
|
- Architektur: `architecture.instructions.md`
|
||||||
|
- Coding Guidelines: `coding_guidelines.instructions.md`
|
||||||
|
- Domain (Security Area): `security_area_domain.instructions.md`
|
||||||
|
- Fragebogen Workflow: `questionnaire_workflow.instructions.md`
|
||||||
|
- Projekt Erweiterung: `extend_project.instructions.md`
|
||||||
|
- Refresh & Fake-ID Mechanismus: `refresh_fake_id.instructions.md`
|
||||||
|
- Allgemeine Projektinfo: `general_project.instructions.md`
|
||||||
|
- AI Kontext / Generatorhinweise: `ai_context.instructions.md`
|
||||||
|
|
||||||
|
## Neue Spezial-Themen
|
||||||
|
- Persistence Layer: `persistence.instructions.md`
|
||||||
|
- PDF Generierung (iText7): `pdf_generation.instructions.md`
|
||||||
|
- Klon-Strategien: `cloning.instructions.md`
|
||||||
|
- Fehler & Logging: `error_handling.instructions.md`
|
||||||
|
- Test-Strategie: `testing_strategy.instructions.md`
|
||||||
|
- Transaktionen: `transactions.instructions.md`
|
||||||
|
- Manager/Controller Muster: `manager_controller_pattern.instructions.md`
|
||||||
|
|
||||||
|
## Verwendung (Automatisierung)
|
||||||
|
1. Start: `general_project.instructions.md` + `architecture.instructions.md` lesen.
|
||||||
|
2. Bei neuen Entities: `extend_project.instructions.md` + `persistence.instructions.md`.
|
||||||
|
3. Bei UI/Business Verkettung: `manager_controller_pattern.instructions.md`.
|
||||||
|
4. Für Fragebogenfunktionen: `questionnaire_workflow.instructions.md` + `security_area_domain.instructions.md`.
|
||||||
|
5. Für temporäre IDs & Refresh: `refresh_fake_id.instructions.md`.
|
||||||
|
6. Für PDF Features: `pdf_generation.instructions.md`.
|
||||||
|
7. Für Klon-Operationen: `cloning.instructions.md`.
|
||||||
|
8. Für Fehlerstrategie: `error_handling.instructions.md`.
|
||||||
|
9. Für Transaktionsregeln: `transactions.instructions.md`.
|
||||||
|
10. Für Qualitätsstil: `coding_guidelines.instructions.md`.
|
||||||
|
|
||||||
|
## Priorität bei Unklarheiten
|
||||||
|
1. `general_project.instructions.md`
|
||||||
|
2. `architecture.instructions.md`
|
||||||
|
3. `coding_guidelines.instructions.md`
|
||||||
|
4. Spezialthema betreffende Datei
|
||||||
|
|
||||||
|
## Pflegehinweise
|
||||||
|
- Beim Ändern von Basisklassen (AbstractManager / AbstractController / AbstractEntity) entsprechende Dateien aktualisieren.
|
||||||
|
- Tippfehler Methode `refrehSelected()` bei Umbenennung in Code auch in `refresh_fake_id.instructions.md` und `architecture.instructions.md` anpassen.
|
||||||
|
- Neue fachliche Domains erhalten eigene `<domain>.instructions.md` Datei mit Operations-, Entity- und Edge Case Liste.
|
||||||
|
|
||||||
|
## Roadmap Dokumentation
|
||||||
|
- Nach Einführung eines Exception Layers: `error_handling.instructions.md` erweitern.
|
||||||
|
- Nach Migration zu Jakarta: Alle Dateien Namespace Hinweis aktualisieren.
|
||||||
|
|
||||||
|
---
|
||||||
+102
@@ -0,0 +1,102 @@
|
|||||||
|
# Manager/Controller Pattern Instructions
|
||||||
|
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
|
|
||||||
|
## Ziele
|
||||||
|
Klare Trennung zwischen UI-Zustand (Controller) und Geschäftslogik/Persistenz (Manager).
|
||||||
|
|
||||||
|
## Verantwortlichkeiten
|
||||||
|
Controller:
|
||||||
|
- Zustände: selected, created, entities.
|
||||||
|
- UI Nachrichten (FacesMessage).
|
||||||
|
- Dialogsteuerung (PrimeFaces Widgets schließen).
|
||||||
|
- Hilfsfunktionen (PDF, Fake-ID-Erzeugung).
|
||||||
|
|
||||||
|
Manager:
|
||||||
|
- CRUD Operationen (create, edit, save, saveAll, remove, removeAllIn, find, findAll).
|
||||||
|
- Fachspezifische Queries / Reload.
|
||||||
|
- Fehlerlogging.
|
||||||
|
|
||||||
|
## Interaktion
|
||||||
|
- Controller ruft Manager.save / saveAll auf für Persistenz.
|
||||||
|
- Nach Änderungen: Controller.refrehSelected() (Tippfehler) -> aktualisiert ausgewähltes Objekt.
|
||||||
|
- Kein direkter EntityManager Zugriff im Controller.
|
||||||
|
|
||||||
|
## Fake-ID Ablauf
|
||||||
|
1. Controller erzeugt neue Entität (id == null).
|
||||||
|
2. Falls Sammlung benötigt: setzt negative ID über createFakeID.
|
||||||
|
3. Bei Save: Manager erkennt id < 0 (nach vorherigem Nullsetzen) -> persist.
|
||||||
|
|
||||||
|
## Methoden-Namenskonventionen
|
||||||
|
- Manager: Verb + Domänenobjekt (addQuestionnaireToSecurityArea, removeQuestionnaireFromSecurityArea).
|
||||||
|
- Controller: UI Aktionen (saveSelected, createNew, openDialog, closeDialogs).
|
||||||
|
|
||||||
|
## Edge Cases
|
||||||
|
- selected == null bei refresh -> no-op.
|
||||||
|
- entities Liste leer -> UI Tabelle zeigt keine Einträge; Null vermeiden (immer leere Liste).
|
||||||
|
|
||||||
|
## Messaging
|
||||||
|
- Erfolg: `successMessage()`; Fehler: `errorMessage()`.
|
||||||
|
- Spezifische Warnungen über `sendWarnMessage`.
|
||||||
|
|
||||||
|
## Verbesserungen
|
||||||
|
- Umbenennung `refrehSelected()` -> `refreshSelected()` in Basisklasse + alle Verwendungen.
|
||||||
|
- Einführung eines BasePDFController oder Utility zur Auslagerung PDF Logik.
|
||||||
|
|
||||||
|
## Generator Leitplanken
|
||||||
|
- Zusätzliche Logik (berechnete Felder, Validierungen) zuerst im Manager statt im Controller (besser testbar, wiederverwendbar).
|
||||||
|
- Controller schlank halten: keine komplexe Businessregeln.
|
||||||
|
|
||||||
|
---
|
||||||
|
# Persistence Instructions
|
||||||
|
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
|
|
||||||
|
## Ziele
|
||||||
|
Konsistente JPA Nutzung (Java EE 8, Hibernate Provider) mit klaren Regeln für IDs, Lazy Loading und Flush.
|
||||||
|
|
||||||
|
## Grundsätze
|
||||||
|
- Entities extend `AbstractEntity` (Long id, creationDate, changedDate, outdated Flag).
|
||||||
|
- Identity Generation: `@GeneratedValue(strategy = GenerationType.IDENTITY)` -> Kein manuelles Setzen positiver IDs.
|
||||||
|
- Equals/HashCode nur auf ID (Basis-Klasse bereitgestellt).
|
||||||
|
|
||||||
|
## ID & Fake-ID Handling
|
||||||
|
- Temporäre neue Objekte können negative IDs erhalten (Fake) zur UI-Differenzierung.
|
||||||
|
- Vor persist: if id != null && id < 0 -> `setId(null)` damit JPA eine echte ID generiert.
|
||||||
|
- Niemals persist mit negativer ID ausführen.
|
||||||
|
|
||||||
|
## Lebenszyklus
|
||||||
|
1. Konstruktor setzt creationDate & changedDate.
|
||||||
|
2. Bei Änderungen Fachlogik: changedDate aktualisieren (TODO: zentralisieren via EntityListener).
|
||||||
|
3. Persist -> flush direkt in `AbstractManager.save` / `saveAll`.
|
||||||
|
|
||||||
|
## Lazy Loading
|
||||||
|
- Vermeide direkte Iteration über nicht initialisierte Collections außerhalb Transaktion.
|
||||||
|
- Nutzung `AbstractManager.refresh(entity)` initialisiert das Entity (Hibernate.initialize(entity)).
|
||||||
|
- Für Collections eigene Reload-Methoden in spezialisierten Managern implementieren.
|
||||||
|
|
||||||
|
## Named Queries & Criteria
|
||||||
|
- Bevorzugt Criteria API für dynamische Filter.
|
||||||
|
- Häufig verwendete, statische Abfragen als `@NamedQuery` in der Entity definieren.
|
||||||
|
|
||||||
|
## Performance Hinweise
|
||||||
|
- `saveAll(Collection<T>)` nutzt einen Flush am Ende; reduziert DB Roundtrips.
|
||||||
|
- Bulk Delete oder Update lieber über JPQL statt Einzelloops (aktuell: removeAllIn loop; Optimierungspotential).
|
||||||
|
|
||||||
|
## Edge Cases
|
||||||
|
- `save(null)` => false (kein Fehlerwurf, Logging im Manager).
|
||||||
|
- Leere Collections in `saveAll` => true (no-op).
|
||||||
|
- `remove(entity)` mit `entity.getId()==null` => false; vorher persistieren oder ignorieren.
|
||||||
|
|
||||||
|
## Verbesserungs-Ideen
|
||||||
|
- EntityListener für Timestamps.
|
||||||
|
- Soft Delete (outdated Flag) statt physischem Löschen für Audit.
|
||||||
|
- Einführung eines Version-Feldes für Optimistic Locking.
|
||||||
|
|
||||||
|
## Generator Leitplanken
|
||||||
|
- Keine Änderung der ID-Strategie ohne umfassende Migration.
|
||||||
|
- Bei neuen Entities standardisierte Felder aus `AbstractEntity` nutzen.
|
||||||
|
- Collections initialisieren (z.B. `new ArrayList<>()`) im Entity-Konstruktor.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
# PDF Generation Instructions
|
||||||
|
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
|
|
||||||
|
## Kontext
|
||||||
|
PDF-Erstellung erfolgt aktuell über Hilfsmethoden in `AbstractController` mittels iText7.
|
||||||
|
|
||||||
|
## Kern-Hilfsmethoden
|
||||||
|
- `loadCompanyLogo()` -> Lädt Logo aus LOGO_PATH.
|
||||||
|
- `generateSorroundingTable(String header, float maxWidth)` -> Einspaltige Rahmen-Tabelle mit Header.
|
||||||
|
- `generateInnerTable(Text header, boolean last, String... values)` -> 2-Spalten Tabelle mit alternierender Hintergrundfarbe.
|
||||||
|
- `generateInnerTable(Text header, int nrColumns, boolean last, String... values)` -> Generisch n-Spalten Tabelle.
|
||||||
|
- `addInnerCells(Table table, String name, String value, boolean isGray)` / Overload -> Fügt Datenzeilen hinzu.
|
||||||
|
- `addPagenumbers(Document document, String ticketNr, Image nextPagesCompanyLogo)` -> Fügt Seitenzahlen & Logo hinzu.
|
||||||
|
|
||||||
|
## Gestaltungsrichtlinien
|
||||||
|
- Fonts: Standard Helvetica / Bold (Konstanten `FONT_NORMAL`, `FONT_BOLD`).
|
||||||
|
- Schriftgrößen klein (8F Inhalte, 11F Header, 12F Hauptheader) für konsistente Layouts.
|
||||||
|
- Wechselnde Hintergrundfarbe (LIGHT_GRAY) zur besseren Lesbarkeit.
|
||||||
|
|
||||||
|
## Erweiterung
|
||||||
|
Neue Tabellen-/Layout-Funktionen:
|
||||||
|
1. Prüfen ob existierende Methoden erweiterbar statt neue Variante.
|
||||||
|
2. Konsistenz in Font & Spaltenbreiten wahren.
|
||||||
|
3. Kein Hardcode von absoluten Positionen außer bei Kopf-/Fußzeilen.
|
||||||
|
|
||||||
|
## Ressourcen Pfade
|
||||||
|
- LOGO_PATH statisch: `/rundata/logo.png`. Anpassungen zentral vornehmen.
|
||||||
|
|
||||||
|
## Fehlerhandhabung
|
||||||
|
- Aktuell wenige try/catch Blöcke; bei Erweiterung: Fehler loggen (`LOGGER.error(e)`) und Benutzer über Controller Messages informieren.
|
||||||
|
|
||||||
|
## Edge Cases
|
||||||
|
- Leere Werte -> `-/-` Platzhalter.
|
||||||
|
- Null Tabelleninstanz in addInnerCells -> early return.
|
||||||
|
|
||||||
|
## Verbesserungen
|
||||||
|
- Einführung eines PDFUtility Service zur Entkopplung vom Controller.
|
||||||
|
- Parameterobjekt für dynamische Tabellenkonfiguration (Spaltenbreiten, Farben, Größen).
|
||||||
|
|
||||||
|
## Generator Leitplanken
|
||||||
|
- iText7 API weiterverwenden; keine neuen PDF Libraries.
|
||||||
|
- Wiederverwendbare Logik nicht direkt im konkreten Controller implementieren -> Utility / Service.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
Vendored
Regular → Executable
+28
@@ -0,0 +1,28 @@
|
|||||||
|
# Questionnaire Workflow Instructions
|
||||||
|
|
||||||
|
## Add
|
||||||
|
areaManager.addQuestionnaireToSecurityArea(area, questionnaire)
|
||||||
|
- area ggf. re-laden
|
||||||
|
- Wrapper erzeugen
|
||||||
|
- Persist wrapper + merge area
|
||||||
|
- Rückgabe: aktualisierte Area
|
||||||
|
|
||||||
|
## Remove
|
||||||
|
areaManager.removeQuestionnaireFromSecurityArea(area, wrapper)
|
||||||
|
- area & wrapper re-laden
|
||||||
|
- Collection remove, em.remove(wrapper), em.merge(area)
|
||||||
|
|
||||||
|
## Available List
|
||||||
|
getAvailableQuestionnaires(area): SELECT q FROM Questionaire q ORDER BY q.name
|
||||||
|
- Filter: bereits zugeordnete Namen
|
||||||
|
|
||||||
|
## Edge Cases
|
||||||
|
- Null area/questionnaire -> Fehlermeldung
|
||||||
|
- Race condition -> nach Add/Remove refreshSelected()
|
||||||
|
|
||||||
|
## Verbesserungen
|
||||||
|
- ID statt Name für Filter
|
||||||
|
- Duplikatprüfung direkt im Manager
|
||||||
|
|
||||||
|
---
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
# Refresh & Fake ID Instructions
|
||||||
|
|
||||||
|
## Fake ID
|
||||||
|
- Negative Long Werte (<0) = temporär
|
||||||
|
- Sequenz: -1, -2, -3 ... (kleinste negative - 1)
|
||||||
|
- Erzeugung: AbstractController.createFakeID(Collection<E>)
|
||||||
|
|
||||||
|
## Persist
|
||||||
|
- Vor Speichern: if id < 0 -> setId(null)
|
||||||
|
- save/saveAll: id == null => persist, sonst merge
|
||||||
|
|
||||||
|
## Refresh
|
||||||
|
- AbstractController.refrehSelected() (Tippfehler) -> getManager().refresh(selected)
|
||||||
|
- AbstractManager.refresh(entity): if id == null -> save(entity); merge + Hibernate.initialize(entity)
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
- Nach Add/Remove Child Collections refresh
|
||||||
|
- Beim Klonen zuerst Quelle laden
|
||||||
|
|
||||||
|
## Verbesserungen
|
||||||
|
- Methode umbenennen zu refreshSelected()
|
||||||
|
- JavaDoc für createFakeID
|
||||||
|
|
||||||
|
---
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
# Security Area Domain Instructions
|
||||||
|
|
||||||
|
## Entities
|
||||||
|
- SecurityArea
|
||||||
|
- SecurityDevice / DangerPoint / SwitchingDevice
|
||||||
|
- SecurityAreaQuestionnaire (Wrapper) + Questionaire
|
||||||
|
|
||||||
|
## Operations
|
||||||
|
- cloneArea(SecurityArea)
|
||||||
|
- addQuestionnaireToSecurityArea(area, questionnaire)
|
||||||
|
- removeQuestionnaireFromSecurityArea(area, wrapper)
|
||||||
|
- getAvailableQuestionnaires(area)
|
||||||
|
- reloadWithQuestionnaires(area)
|
||||||
|
|
||||||
|
## Workflow (Add Questionnaire)
|
||||||
|
1. Area laden (falls id > 0)
|
||||||
|
2. Wrapper erstellen & area setzen
|
||||||
|
3. Persist Wrapper, merge Area
|
||||||
|
4. Refresh im Controller
|
||||||
|
|
||||||
|
## Deletion Pattern
|
||||||
|
- Beziehungen lösen (Kinder area = null setzen)
|
||||||
|
- Kinder entfernen (Manager.removeAllIn)
|
||||||
|
- Area per Named Query löschen
|
||||||
|
|
||||||
|
## Edge Cases
|
||||||
|
- Duplicate questionnaire by name -> aktuell Filter per Name
|
||||||
|
- Verbesserung: Filter per ID
|
||||||
|
|
||||||
|
## Klonen
|
||||||
|
- Persistente Quelle re-laden, initialisieren
|
||||||
|
- Copy-Konstruktor & alle Child IDs auf null
|
||||||
|
|
||||||
|
## Verbesserungen
|
||||||
|
- CascadeSettings prüfen
|
||||||
|
- Bean Validation einsetzen
|
||||||
|
|
||||||
|
---
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
+49
@@ -0,0 +1,49 @@
|
|||||||
|
# Testing Strategy Instructions
|
||||||
|
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
|
|
||||||
|
## Ziele
|
||||||
|
Testabdeckung für kritische Pfade: CRUD, Clone, Fragebogen Zuordnung, Fake-ID Mechanismus.
|
||||||
|
|
||||||
|
## Testarten
|
||||||
|
1. Unit Tests (reine Logik, z.B. createFakeID, Klon Copy-Konstruktoren).
|
||||||
|
2. Integration Tests (Persistence + Manager Methoden gegen Test-DB). Möglich mit in-memory H2 + angepasster persistence.xml.
|
||||||
|
3. UI/Controller Smoke Tests (Optional, z.B. mit Selenium/Arquillian Graphene).
|
||||||
|
|
||||||
|
## Prioritäten
|
||||||
|
- AbstractManager.save / saveAll Edge Cases.
|
||||||
|
- remove / removeAllIn (Null, nicht persistierte Entities).
|
||||||
|
- createFakeID Sequenz (-1, -2, -3 ...).
|
||||||
|
- Fragebogen Add/Remove Workflow (Wrapper Persistenz, Filterliste).
|
||||||
|
- Klonen tiefer Objektgraph.
|
||||||
|
|
||||||
|
## Beispiel Unit Test Fälle
|
||||||
|
- createFakeID(null) => -1.
|
||||||
|
- createFakeID(leere Liste) => -1.
|
||||||
|
- createFakeID([id=-1]) => -2.
|
||||||
|
- createFakeID([id=-3, id=-1]) => -4.
|
||||||
|
|
||||||
|
## Integration Tests (CRUD)
|
||||||
|
- Persist neue Entity -> ID != null.
|
||||||
|
- Merge vorhandene Entity -> unverändert Fachfelder korrekt übernommen.
|
||||||
|
- saveAll mit gemischten (neue + vorhandene) -> alle persistent.
|
||||||
|
|
||||||
|
## Fehlerpfade
|
||||||
|
- save(null) -> false.
|
||||||
|
- remove(null) -> false.
|
||||||
|
- remove(entity ohne ID) -> false.
|
||||||
|
|
||||||
|
## Klon Tests
|
||||||
|
- Quelle & Klon dürfen nicht gleiche ID haben.
|
||||||
|
- Child Collections tief kopiert (Referenzen ungleich, Werte gleich).
|
||||||
|
|
||||||
|
## Tooling Vorschlag
|
||||||
|
- JUnit 5, Mockito für isolierte Tests von Controller-Hilfsmethoden.
|
||||||
|
- Testcontainers (Optional später) für realistischere DB.
|
||||||
|
|
||||||
|
## Generator Leitplanken
|
||||||
|
- Für neue Fachlogik minimal 1-2 Unit Tests + 1 Integration Test.
|
||||||
|
- Keine Abhängigkeit auf Produktionspfade in Unit Tests; Test-spezifische Testdaten-Builder.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
# Transactions Instructions
|
||||||
|
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
|
|
||||||
|
## Kontext
|
||||||
|
Container-Managed Transaktionen (Java EE). Verwendung von `@Transactional` auf Manager-Methoden für Schreiboperationen.
|
||||||
|
|
||||||
|
## Grundsätze
|
||||||
|
- Jede persistierende Operation (create, edit, remove) innerhalb einer Transaktion.
|
||||||
|
- `save` und `saveAll` bereits mit `@Transactional` versehen.
|
||||||
|
- Leseoperationen können ohne Annotation auskommen (Default: kein Write-Lock nötig).
|
||||||
|
|
||||||
|
## Batch Operationen
|
||||||
|
- `saveAll(Collection<T>)`: Ein Transaktionskontext für gesamte Collection -> entweder komplett erfolgreich oder Abbruch beim Fehler.
|
||||||
|
- Optimierungspotential: Fehler sammeln, nicht sofort abbrechen.
|
||||||
|
|
||||||
|
## Refresh
|
||||||
|
- `refresh(entity)` führt merge aus; wenn `id == null` vorher persist -> bleibt innerhalb Transaktion falls aufgerufen durch `save`/`saveAll`.
|
||||||
|
|
||||||
|
## Remove
|
||||||
|
- `remove(entity)` ohne `@Transactional` in Basisklasse -> Empfehlung: Annotation hinzufügen in konkretem Manager wenn Delete-Fachlogik erweitert wird.
|
||||||
|
|
||||||
|
## Edge Cases
|
||||||
|
- Verschachtelte Aufrufe (save -> intern create/edit): Container handhabt Propagation (`REQUIRED`).
|
||||||
|
- LazyInitializationException vermeiden: innerhalb Transaktion initialisieren.
|
||||||
|
|
||||||
|
## Empfohlene Annotationen
|
||||||
|
- Zusätzliche fachliche Write-Methoden stets mit `@Transactional` versehen.
|
||||||
|
- Pure Read: Performancekritisch -> ggf. explizit `@Transactional(Transactional.TxType.SUPPORTS)` oder weglassen.
|
||||||
|
|
||||||
|
## Fehlerfall Verhalten
|
||||||
|
- Ungefangene RuntimeException -> Rollback durch Container.
|
||||||
|
- Aktuell Exceptions geloggt & boolean false -> verhindert Rollback. Verbesserung: BusinessException throw + Rollback.
|
||||||
|
|
||||||
|
## Generator Leitplanken
|
||||||
|
- Keine eigenen manuell geöffneten Transaktionen (kein `UserTransaction`).
|
||||||
|
- Konsistenz: Schreibmethoden annotieren, Leseoperationen nur bei Bedarf.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
Executable
+21
@@ -0,0 +1,21 @@
|
|||||||
|
# Maven Build-Verzeichnis
|
||||||
|
target/
|
||||||
|
/target/
|
||||||
|
|
||||||
|
# IDE-spezifische Dateien
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# OS-spezifische Dateien
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Temporäre Dateien
|
||||||
|
*.tmp
|
||||||
|
*.temp
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
# mss-failsafe — Git History Archive
|
||||||
|
|
||||||
|
> **Why this file exists**
|
||||||
|
>
|
||||||
|
> `mss-failsafe` was developed in its own standalone Git repository (no remote) on
|
||||||
|
> Patrick's workstation. On **2026-06-13** it was consolidated into the `pi_mcps`
|
||||||
|
> monorepo under [`java/mss-failsafe/`](.) as the single canonical copy. The
|
||||||
|
> standalone repo's `.git` directory was removed during the flatten, so the original
|
||||||
|
> per-commit history below is preserved here for reference.
|
||||||
|
>
|
||||||
|
> The **flattened working tree** captured at consolidation = tip of `master`
|
||||||
|
> (`2a142b5`, 2025-10-04) **plus all uncommitted working-tree changes** that were in
|
||||||
|
> progress at that time (notably the `.github/*.instructions.md` AI-context files and
|
||||||
|
> `.gitignore` updates). This snapshot is the source of truth and the base for the
|
||||||
|
> planned upgraded rewrite with Work Lumen.
|
||||||
|
|
||||||
|
## Repository Facts (at time of archival)
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|---|---|
|
||||||
|
| Standalone repo location | `~/pi_mcps/mss-failsafe/` (top-level, pre-consolidation) |
|
||||||
|
| New canonical location | `java/mss-failsafe/` (inside `pi_mcps` monorepo) |
|
||||||
|
| Default branch | `master` |
|
||||||
|
| Tip commit | `2a142b5` (2025-10-04) |
|
||||||
|
| Total commits (all branches) | 33 |
|
||||||
|
| First commit | `f2fa7b6` (2025-06-27) |
|
||||||
|
| Author | Patrick Plate |
|
||||||
|
| Remote | none (local-only repo) |
|
||||||
|
| Uncommitted changes at archival | 175 working-tree entries (preserved in the flatten) |
|
||||||
|
|
||||||
|
## Branches (at time of archival)
|
||||||
|
|
||||||
|
| Branch | Tip | Date | Note |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `master` | `2a142b5` | 2025-10-04 | Default; newest committed state |
|
||||||
|
| `bugfix/protocol-creation-speed` | `2a142b5` | 2025-10-04 | Same tip as master |
|
||||||
|
| `bugfix/overview-pdf-counting` | `0226952` | 2025-09-25 | |
|
||||||
|
| `feature/zusammenfassung-pdf` | `7e2dd63` | 2025-09-17 | Contains `7e2dd63` not on master |
|
||||||
|
| `feature/all-checklist-at-once` | `7f68bbf` | 2025-09-13 | |
|
||||||
|
|
||||||
|
### Commits not reachable from `master`
|
||||||
|
|
||||||
|
| Hash | Date | Branch | Subject |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `7e2dd63` | 2025-09-17 | `feature/zusammenfassung-pdf` | refactor(questionnaire): improve text handling in SecurityAreaQuestion |
|
||||||
|
| `b26b211` | 2025-09-15 | (dangling) | refactor: update UI text and logic for machine creation and editing |
|
||||||
|
|
||||||
|
## Full Commit Log (all branches, newest first)
|
||||||
|
|
||||||
|
| Hash | Date | Subject |
|
||||||
|
|---|---|---|
|
||||||
|
| `2a142b5` | 2025-10-04 | feat(ticket): optimize ticket fetching and indexing for protocol generation |
|
||||||
|
| `a28584b` | 2025-10-03 | feat(ticket): optimize protocol generation by reducing DB queries and enhancing ZIP creation logic |
|
||||||
|
| `0226952` | 2025-09-25 | feat(ticket): add alphabetical ordering for displayed lists and data tables |
|
||||||
|
| `06f1b0a` | 2025-09-25 | fix(ticket): handle null device roles in security device filtering |
|
||||||
|
| `5cba533` | 2025-09-17 | feat(ticket): enhance danger point and inspection data in overview protocol |
|
||||||
|
| `7e2dd63` | 2025-09-17 | refactor(questionnaire): improve text handling in SecurityAreaQuestion |
|
||||||
|
| `b26b211` | 2025-09-15 | refactor: update UI text and logic for machine creation and editing |
|
||||||
|
| `d535571` | 2025-09-15 | refactor(ticket): make DateTimeFormatter immutable in OverviewProtocolController |
|
||||||
|
| `593080e` | 2025-09-15 | refactor(ticket): remove unused imports in OverviewProtocolController |
|
||||||
|
| `44cb289` | 2025-09-15 | fix(ticket): correct typo in column header and reset flag in protocol generation |
|
||||||
|
| `1fd6bcf` | 2025-09-14 | feat(ticket): add overview protocol generation and integration |
|
||||||
|
| `7f68bbf` | 2025-09-13 | refactor(ticket): streamline PDF generation and file handling for machine protocols |
|
||||||
|
| `daeacc9` | 2025-09-13 | feat(ticket): add functionality to generate and download all machine protocols as ZIP |
|
||||||
|
| `0166206` | 2025-09-13 | feat(questionnaire): enhance UI and improve questionnaire management logic |
|
||||||
|
| `24da4a1` | 2025-08-29 | feat(questionnaire): improve questionnaire integration and UI enhancements |
|
||||||
|
| `913efbb` | 2025-08-29 | feat(questionnaire): enhance questionnaire handling with better UI and data loading |
|
||||||
|
| `b3782fc` | 2025-08-29 | feat(questionnaire): enhance question position management and text handling |
|
||||||
|
| `884cb80` | 2025-08-25 | fix(security-area): resolve lazy loading and eager collection conflict for questionnaires |
|
||||||
|
| `3fd6e2e` | 2025-08-24 | Admin: add System-Logs page and LogFileManager; update admin menu; set active RollingFile to /logs/application.log |
|
||||||
|
| `11d96cd` | 2025-08-16 | feat(admin): neue Admin-Views (password reset, user management) und Controller |
|
||||||
|
| `6238521` | 2025-07-26 | Refactor: UserRoleValidationManager als Startup-Service konfiguriert (@Singleton/@Startup, @PostConstruct validateRolesOnStartup) |
|
||||||
|
| `eeb329d` | 2025-07-26 | Feature: UserRoleValidationManager für automatische Rollenkorrektur |
|
||||||
|
| `2d72946` | 2025-07-26 | Dokumentation: Detaillierte Kommentare zur Person-Entität hinzugefügt |
|
||||||
|
| `66bb699` | 2025-07-20 | Implement hierarchical user role assignment system (UserRoleAssignmentHelper) |
|
||||||
|
| `8ee06b4` | 2025-07-20 | Add comprehensive JavaDoc comments to model classes |
|
||||||
|
| `3438bcb` | 2025-07-20 | Remove target directory from repository and improve .gitignore |
|
||||||
|
| `ed70e9f` | 2025-07-15 | Update .gitignore to include an empty /target/ directory |
|
||||||
|
| `7072410` | 2025-07-03 | Improve UI loading experience and update controller logic |
|
||||||
|
| `0d9c1fa` | 2025-06-27 | Update multiple controller classes across various modules |
|
||||||
|
| `0ab4495` | 2025-06-27 | Refactor controllers to remove session dependency and improve transaction management; add .gitignore for target directory |
|
||||||
|
| `f2fa7b6` | 2025-06-27 | Add initial project structure and configuration files |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Archived 2026-06-13 during the mss-failsafe consolidation into `pi_mcps`. The full
|
||||||
|
binary Git history of the original standalone repo was not migrated — only this
|
||||||
|
human-readable log plus the final flattened working tree.*
|
||||||
+199
@@ -0,0 +1,199 @@
|
|||||||
|
# Questionnaires für SecurityArea - Implementierungsplan
|
||||||
|
|
||||||
|
## Übersicht
|
||||||
|
Implementierung der Funktionalität zur Hinzufügung von Fragebögen (Questionnaires) zu SecurityArea-Entitäten in den Basisdaten. Dies ermöglicht es, Fragebögen bereits bei der Erstellung von Sicherheitsbereichen zu hinterlegen, anstatt erst bei der Ticket-Erstellung.
|
||||||
|
|
||||||
|
## Hintergrund
|
||||||
|
- **Aktueller Stand**: Questionnaires werden nur zu TicketSecurityArea hinzugefügt
|
||||||
|
- **Neues Ziel**: Questionnaires sollen auch zu SecurityArea (Basisdaten) hinzugefügt werden können
|
||||||
|
- **Grund**: Verbesserung des Workflows entsprechend Kundenwunsch
|
||||||
|
|
||||||
|
## Schritt-für-Schritt Implementierung
|
||||||
|
|
||||||
|
### 1. Datenbankmodell erweitern
|
||||||
|
|
||||||
|
#### 1.1 SecurityArea Entität anpassen
|
||||||
|
- **Datei**: `src/main/java/model/securityarea/SecurityArea.java`
|
||||||
|
- **Aufgabe**:
|
||||||
|
- Neue Beziehung zu Questionnaires hinzufügen
|
||||||
|
- `@OneToMany` Mapping für `SecurityAreaQuestionnaire` implementieren
|
||||||
|
- Ähnlich wie bei TicketSecurityArea → SecurityAreaQuestionnaire
|
||||||
|
|
||||||
|
#### 1.2 Neue Entität: SecurityAreaQuestionnaire
|
||||||
|
- **Datei**: `src/main/java/model/securityarea/SecurityAreaQuestionnaire.java` (neu erstellen)
|
||||||
|
- **Aufgabe**:
|
||||||
|
- Entität ähnlich zu `TicketSecurityAreaQuestionnaire` erstellen
|
||||||
|
- `@ManyToOne` Beziehung zu SecurityArea
|
||||||
|
- `@OneToMany` Beziehung zu SecurityAreaQuestion
|
||||||
|
- Konstruktor für Kopieren von Questionnaire → SecurityAreaQuestionnaire
|
||||||
|
|
||||||
|
#### 1.3 Neue Entität: SecurityAreaQuestion
|
||||||
|
- **Datei**: `src/main/java/model/securityarea/SecurityAreaQuestion.java` (neu erstellen)
|
||||||
|
- **Aufgabe**:
|
||||||
|
- Entität ähnlich zu `SecurityAreaQuestion` aus tickets package erstellen
|
||||||
|
- `@ManyToOne` Beziehung zu SecurityAreaQuestionnaire
|
||||||
|
- Alle notwendigen Felder für Fragen implementieren
|
||||||
|
|
||||||
|
### 2. Business Logic implementieren
|
||||||
|
|
||||||
|
#### 2.1 SecurityAreaManager erweitern
|
||||||
|
- **Datei**: `src/main/java/business/securityarea/SecurityAreaManager.java`
|
||||||
|
- **Aufgabe**:
|
||||||
|
- Methoden für Questionnaire-Management hinzufügen
|
||||||
|
- `addQuestionnaireToSecurityArea()`
|
||||||
|
- `removeQuestionnaireFromSecurityArea()`
|
||||||
|
- `getAvailableQuestionnaires()`
|
||||||
|
|
||||||
|
#### 2.2 QuestionnaireManager anpassen
|
||||||
|
- **Datei**: `src/main/java/business/questions/QuestionnaireManager.java`
|
||||||
|
- **Aufgabe**:
|
||||||
|
- Methoden für SecurityArea-Questionnaire Verknüpfung
|
||||||
|
- Validierung für Questionnaire-Zuordnung
|
||||||
|
|
||||||
|
### 3. Controller Layer erweitern
|
||||||
|
|
||||||
|
#### 3.1 SecurityAreaController anpassen
|
||||||
|
- **Datei**: `src/main/java/controller/securityarea/SecurityAreaController.java`
|
||||||
|
- **Aufgabe**:
|
||||||
|
- Properties für Questionnaire-Auswahl hinzufügen
|
||||||
|
- `selectedQuestionnaire`, `availableQuestionnaires`
|
||||||
|
- Methoden: `addQuestionnaireToArea()`, `removeQuestionnaireFromArea()`
|
||||||
|
- Integration in `save()` und `editSelected()` Methoden
|
||||||
|
|
||||||
|
#### 3.2 Neue Controller für SecurityAreaQuestionnaire
|
||||||
|
- **Datei**: `src/main/java/controller/securityarea/SecurityAreaQuestionnaireController.java` (optional)
|
||||||
|
- **Aufgabe**:
|
||||||
|
- Dedicated Controller für Questionnaire-Management
|
||||||
|
- Ähnlich zu bestehenden Questionnaire-Controllern
|
||||||
|
|
||||||
|
### 4. UI Implementation
|
||||||
|
|
||||||
|
#### 4.1 Hauptseite erweitern
|
||||||
|
- **Datei**: `src/main/webapp/resources/user/sec/create.xhtml`
|
||||||
|
- **Aufgabe**:
|
||||||
|
- Neue Sektion für Questionnaires in SecurityArea-Details hinzufügen
|
||||||
|
- Position: Nach den DangerPoints, vor dem Bottom-Bereich
|
||||||
|
- Accordion-Panel für Questionnaires ähnlich wie bei SecurityDevices
|
||||||
|
|
||||||
|
#### 4.2 Questionnaire-Management UI
|
||||||
|
- **Komponenten hinzufügen**:
|
||||||
|
- DataTable für angehängte Questionnaires
|
||||||
|
- Buttons: "Fragebogen hinzufügen", "Bearbeiten", "Entfernen"
|
||||||
|
- Dialog für Questionnaire-Auswahl
|
||||||
|
- Dialog für Questionnaire-Bearbeitung
|
||||||
|
|
||||||
|
#### 4.3 Dialog-Implementierung
|
||||||
|
- **Neue Dialogs in create.xhtml**:
|
||||||
|
- `dlgAddQuestionnaire`: Auswahl verfügbarer Questionnaires
|
||||||
|
- `dlgEditQuestionnaire`: Bearbeitung der Questions
|
||||||
|
- Ähnlich zu bestehenden Device/DangerPoint Dialogs
|
||||||
|
|
||||||
|
### 5. Integration und Workflow
|
||||||
|
|
||||||
|
#### 5.1 Ticket-Erstellung anpassen
|
||||||
|
- **Aufgabe**: Bei Ticket-Erstellung Questionnaires von SecurityArea automatisch kopieren
|
||||||
|
- **Dateien**:
|
||||||
|
- Ticket-Erstellungs-Controller
|
||||||
|
- TicketSecurityArea-Business-Logic
|
||||||
|
|
||||||
|
#### 5.2 Copy/Clone Funktionalität
|
||||||
|
- **Aufgabe**: Beim Kopieren von SecurityAreas auch Questionnaires mitkopieren
|
||||||
|
- **Betroffene Methoden**: `cloneToSelectedMachine()` in SecurityAreaController
|
||||||
|
|
||||||
|
### 6. UI/UX Details
|
||||||
|
|
||||||
|
#### 6.1 SecurityArea-Karte erweitern
|
||||||
|
```html
|
||||||
|
<!-- Nach DangerPoints Accordion hinzufügen -->
|
||||||
|
<div class="p-col-12">
|
||||||
|
<p:accordionPanel value="#{securityAreaController.selected.questionnaires}" var="questionnaire" activeIndex="#">
|
||||||
|
<p:tab title="Fragebogen: #{questionnaire.name}">
|
||||||
|
<!-- Questionnaire Details und Questions anzeigen -->
|
||||||
|
</p:tab>
|
||||||
|
</p:accordionPanel>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 6.2 Questionnaire-Management Buttons
|
||||||
|
- In das "Mehr"-Menü (dynaButton) integrieren
|
||||||
|
- Neue Menüpunkte: "Fragebogen hinzufügen", "Fragebögen verwalten"
|
||||||
|
|
||||||
|
### 7. Testing und Validierung
|
||||||
|
|
||||||
|
#### 7.1 Unit Tests
|
||||||
|
- **Neue Test-Klassen**:
|
||||||
|
- `SecurityAreaQuestionnaireTest`
|
||||||
|
- `SecurityAreaQuestionTest`
|
||||||
|
- `SecurityAreaManagerTest` (erweitern)
|
||||||
|
|
||||||
|
#### 7.2 Integration Tests
|
||||||
|
- Questionnaire-Zuordnung zu SecurityArea
|
||||||
|
- Kopieren von Questionnaires bei Ticket-Erstellung
|
||||||
|
- UI-Workflow Tests
|
||||||
|
|
||||||
|
#### 7.3 Datenbank-Migration
|
||||||
|
- **Aufgabe**: SQL-Scripts für neue Tabellen erstellen
|
||||||
|
- Tables: `SECURITY_AREA_QUESTIONNAIRE`, `SECURITY_AREA_QUESTION`
|
||||||
|
- Foreign Key Constraints definieren
|
||||||
|
|
||||||
|
## Reihenfolge der Implementierung
|
||||||
|
|
||||||
|
1. **Phase 1**: Datenbankmodell (SecurityAreaQuestionnaire, SecurityAreaQuestion)
|
||||||
|
2. **Phase 2**: Business Logic (Manager-Erweiterungen)
|
||||||
|
3. **Phase 3**: Controller Layer (SecurityAreaController erweitern)
|
||||||
|
4. **Phase 4**: UI Implementation (create.xhtml erweitern)
|
||||||
|
5. **Phase 5**: Integration (Ticket-Erstellung anpassen)
|
||||||
|
6. **Phase 6**: Testing und Finalisierung
|
||||||
|
|
||||||
|
## Wichtige Überlegungen
|
||||||
|
|
||||||
|
### Datenmodell-Konsistenz
|
||||||
|
- Questionnaires in SecurityArea müssen kompatibel zu TicketSecurityArea sein
|
||||||
|
- Beim Ticket-Erstellen: SecurityArea-Questionnaires → TicketSecurityArea kopieren
|
||||||
|
|
||||||
|
### UI-Konsistenz
|
||||||
|
- Gleiche Bedienung wie bei SecurityDevices/DangerPoints
|
||||||
|
- Accordion-Panel für übersichtliche Darstellung
|
||||||
|
- Standard CRUD-Operationen (Create, Read, Update, Delete)
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
- Lazy Loading für Questionnaires implementieren
|
||||||
|
- Effizienter Datentransfer bei Questionnaire-Kopierung
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
### Neue Dateien zu erstellen:
|
||||||
|
- `model/securityarea/SecurityAreaQuestionnaire.java`
|
||||||
|
- `model/securityarea/SecurityAreaQuestion.java`
|
||||||
|
- Controller-Erweiterungen
|
||||||
|
- UI-Erweiterungen in create.xhtml
|
||||||
|
|
||||||
|
### Bestehende Dateien zu modifizieren:
|
||||||
|
- `model/securityarea/SecurityArea.java`
|
||||||
|
- `controller/securityarea/SecurityAreaController.java`
|
||||||
|
- `business/securityarea/SecurityAreaManager.java`
|
||||||
|
- `resources/user/sec/create.xhtml`
|
||||||
|
|
||||||
|
## Zeitschätzung
|
||||||
|
- **Phase 1-2**: 2-3 Tage (Backend)
|
||||||
|
- **Phase 3-4**: 3-4 Tage (Controller + UI)
|
||||||
|
- **Phase 5-6**: 2-3 Tage (Integration + Testing)
|
||||||
|
- **Gesamt**: ~8-10 Arbeitstage
|
||||||
|
|
||||||
|
## Risiken und Mitigationen
|
||||||
|
|
||||||
|
### Datenbankmigrationen
|
||||||
|
- **Risiko**: Bestehende Daten könnten beeinträchtigt werden
|
||||||
|
- **Mitigation**: Backup vor Migration, schrittweise Einführung
|
||||||
|
|
||||||
|
### UI-Komplexität
|
||||||
|
- **Risiko**: UI wird zu überladen
|
||||||
|
- **Mitigation**: Accordion-Panel verwenden, ähnlich zu bestehenden Komponenten
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
- **Risiko**: Laden von vielen Questionnaires könnte langsam werden
|
||||||
|
- **Mitigation**: Lazy Loading, Paging implementieren
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Nächste Schritte**: Mit Phase 1 (Datenbankmodell) beginnen und die SecurityAreaQuestionnaire Entität implementieren.
|
||||||
Executable
+64
@@ -0,0 +1,64 @@
|
|||||||
|
# AI Instruktionen für Code-Generierung
|
||||||
|
|
||||||
|
Ziel: Ein konsistenter Kontext für zukünftige automatische Ergänzungen.
|
||||||
|
|
||||||
|
## Projekt-Kurzprofil
|
||||||
|
- Typ: Java EE 8 (javax), WAR, JSF + PrimeFaces, Hibernate JPA.
|
||||||
|
- Java Version: 11 (Compiler Plugin).
|
||||||
|
- Schichten: Model (Entities), Business (Manager), Controller (JSF Beans), View (XHTML).
|
||||||
|
|
||||||
|
## Wichtige Basisklassen
|
||||||
|
- `AbstractEntity`: Basisklasse aller Entities (enthält ID – Details nicht gezeigt, aber zentral).
|
||||||
|
- `AbstractManager<T>`: Generisches CRUD mit `save`, `saveAll`, etc.
|
||||||
|
- `AbstractController<E>`: UI State & Utilities.
|
||||||
|
|
||||||
|
## Konventionen (Kurz)
|
||||||
|
- Neue Entities: extend `AbstractEntity`, Named Queries definieren.
|
||||||
|
- Neue Manager: `@Stateless`, extends `AbstractManager<Entity>`, implementiert `getEntityManager()`.
|
||||||
|
- Neue Controller: `@Named`, Scope Annotation (`@ViewScoped` etc.), extends `AbstractController<Entity>`, implementiert `getManager()`.
|
||||||
|
- Temporäre (nicht persistierte) Objekte: negative ID (Fake) bis finalem Speichern.
|
||||||
|
|
||||||
|
## CRUD Muster (Beispiel)
|
||||||
|
```java
|
||||||
|
@Stateless
|
||||||
|
public class ExampleEntityManager extends AbstractManager<ExampleEntity> {
|
||||||
|
@PersistenceContext(name = "pu_person") EntityManager em;
|
||||||
|
public ExampleEntityManager(){ super(ExampleEntity.class); }
|
||||||
|
@Override protected EntityManager getEntityManager(){ return em; }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Typische Aufgaben für Generierung
|
||||||
|
1. Neue Domain + Entity + Manager + Controller + XHTML.
|
||||||
|
2. PDF-Ausgabe Erweiterung.
|
||||||
|
3. Batch-Speichern mehrerer neuer Entities.
|
||||||
|
4. Klon-Operationen: Copy-Konstruktor nutzen, Child-IDs auf `null` setzen, Referenzen neu knüpfen.
|
||||||
|
5. Fragebogen-Workflow: add/remove (siehe `QUESTIONNAIRE_WORKFLOW.md`).
|
||||||
|
|
||||||
|
## Qualitätssicherung
|
||||||
|
- Nach Code-Erzeugung: Prüfe Kompilierung (mvn -q test / package).
|
||||||
|
- Sicherstellen: Keine direkten System.out Prints in Produktionscode.
|
||||||
|
- Logging: `LOGGER.error(e)` bei Exceptions.
|
||||||
|
|
||||||
|
## Häufige Edge Cases
|
||||||
|
- Null Checks vor Persist/Remove.
|
||||||
|
- Negative ID Objekte dürfen nicht direkt gelöscht (erst persistieren oder aus Collection entfernen).
|
||||||
|
- Lazy Collections müssen initialisiert vor Iteration (via `refresh` oder `Hibernate.initialize`).
|
||||||
|
|
||||||
|
## Verbesserungsvorschläge (safe additions)
|
||||||
|
- Service Layer Einführen (wenn Logik Manager übersteigt).
|
||||||
|
- Bean Validation (@NotNull, @Size) auf Entities.
|
||||||
|
- Einheitliche Exception Klasse.
|
||||||
|
|
||||||
|
## Generierungs-Präferenzen
|
||||||
|
- Bevorzugt vorhandene Muster exakt replizieren.
|
||||||
|
- Keine neuen Frameworks ohne Bedarf.
|
||||||
|
- Code kommentieren nur bei komplexer Logik.
|
||||||
|
|
||||||
|
## Anti-Pattern vermeiden
|
||||||
|
- Business Logik direkt im Controller.
|
||||||
|
- Duplizierte Query Strings ohne Named Query.
|
||||||
|
|
||||||
|
---
|
||||||
|
Letzte Aktualisierung: 2025-10-20
|
||||||
|
|
||||||
Executable
+63
@@ -0,0 +1,63 @@
|
|||||||
|
# Architekturübersicht
|
||||||
|
|
||||||
|
## Layer
|
||||||
|
1. Präsentation: JSF 2.3 + PrimeFaces 11 (XHTML in `webapp/`).
|
||||||
|
2. Controller Layer: JSF Managed Beans (CDI `@Named`, Scopes) – koordiniert UI → Business.
|
||||||
|
3. Business Layer: Stateless EJB Manager (`business.*Manager`) – kapselt Datenzugriff + Fachlogik.
|
||||||
|
4. Persistenz Layer: JPA (Javax) + Hibernate Provider. Persistence Context Name: `pu_person`.
|
||||||
|
5. Ressourcen: `src/main/resources` für Log4j2, statische Texte, Checklisten.
|
||||||
|
|
||||||
|
## Zentrale Basisklassen
|
||||||
|
### AbstractManager<T extends AbstractEntity>
|
||||||
|
- Generisches CRUD: `save`, `saveAll`, `create`, `edit`, `remove`, `refresh`, `find`, `findAll`, `count`.
|
||||||
|
- Flush nach Persist/Merge (stellt zeitnah DB-Konsistenz sicher).
|
||||||
|
- Fehlerbehandlung: try/catch + Logging (Verbesserungspotential: Konsistente Exception).
|
||||||
|
|
||||||
|
### AbstractController<ENT extends AbstractEntity>
|
||||||
|
- UI State: `selected`, `created`, `entities`.
|
||||||
|
- Utility: Faces Messages, PDF Hilfsmethoden, Fake-ID Generator für neue Entities vor Persist.
|
||||||
|
- `refrehSelected()`: Re-merge & initialize Lazy Collections.
|
||||||
|
|
||||||
|
## Entity Lebenszyklus (UI Sicht)
|
||||||
|
1. Nutzer erstellt neues Objekt → Controller vergibt Fake-ID (negativ) mittels `createFakeID(Collection<ENT>)`.
|
||||||
|
2. Objekt wird in Listen angezeigt, kann editiert werden bevor persistiert.
|
||||||
|
3. Beim Speichern werden alle mit `id < 0` auf `null` gesetzt; `AbstractManager.saveAll()` persistiert.
|
||||||
|
4. Nach Persist: DB generiert positive ID.
|
||||||
|
|
||||||
|
## Sicherheitsbereich (SecurityArea)
|
||||||
|
- Enthält Listen: `SecurityDevices`, `DangerPoints`, `SwitchingDevices`, `Questionnaires`.
|
||||||
|
- Manager-Methoden: `cloneArea`, add/remove Questionnaire, `reloadWithQuestionnaires`.
|
||||||
|
- Klonen: Erst DB laden (falls persistent), dann Kopie via Copy-Konstruktor `new SecurityArea(area)`.
|
||||||
|
|
||||||
|
## Fragebogen-Zuordnung
|
||||||
|
- Hinzufügen: `SecurityAreaManager.addQuestionnaireToSecurityArea` erzeugt `SecurityAreaQuestionnaire` Wrapper (assoziative Entity) & persistiert.
|
||||||
|
- Entfernen: Entities werden aus Sammlung entfernt und via `em.remove(questionnaire)` gelöscht.
|
||||||
|
- Verfügbare Fragebögen: Alle `Questionaire` minus bereits zugeordnete (Filter per Namen – potentielles Verbesserungspotential: Verwendung IDs statt Name).
|
||||||
|
|
||||||
|
## Transaktionen
|
||||||
|
- Methoden mit Schreiboperationen annotiert `@Transactional` (EJB Container verwaltet JTA). In `AbstractManager` ebenfalls.
|
||||||
|
|
||||||
|
## Logging
|
||||||
|
- Log4j2 überall via `LogManager.getLogger(...)`. Konfiguration: `log4j2.xml`.
|
||||||
|
|
||||||
|
## PDF Generierung
|
||||||
|
- `AbstractController` Hilfsmethoden zur Tabellen-Erstellung (iText7) + gemischte Nutzung iText5 (itextpdf 5.5.13) – Migration empfohlen.
|
||||||
|
|
||||||
|
## Erweiterbarkeit
|
||||||
|
- Neue Fachbereiche folgen Pattern: Entity → Manager → Controller → UI.
|
||||||
|
- Reusable generische Methoden vermeiden Duplikate (Beispiel: `saveAll`, `refresh`).
|
||||||
|
|
||||||
|
## Bekannte technische Schulden
|
||||||
|
- Mischung iText5 & iText7.
|
||||||
|
- Fehlerbehandlung inkonsistent (bool Rückgaben + Logging).
|
||||||
|
- Kein einheitlicher DTO Layer – Controller arbeitet direkt auf Entities (Risk: Lazy Loading im View).
|
||||||
|
- Wenige Tests im `test/` Verzeichnis.
|
||||||
|
|
||||||
|
## Ideen für Refactoring
|
||||||
|
- Einführung Service Layer (falls Business Logik komplexer wird) zw. Controller und Manager.
|
||||||
|
- Exceptions mit Custom Runtime (`BusinessException`) statt stiller bool False.
|
||||||
|
- Verwendung Criteria / NamedQueries für Wiederverwendbarkeit (z.Z. direkte Query Strings in Manager).
|
||||||
|
|
||||||
|
---
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
|
|
||||||
Executable
+61
@@ -0,0 +1,61 @@
|
|||||||
|
# Coding Guidelines
|
||||||
|
|
||||||
|
## Allgemein
|
||||||
|
- Sprache: Deutsch in UI-Messages, Englisch im Code (Klassennamen etc.).
|
||||||
|
- Einrückung: 4 Spaces (NetBeans Standard). Keine Tab-Mischung.
|
||||||
|
- Zeilenlänge: Empfehlung max. 140 Zeichen.
|
||||||
|
- Vermeide überflüssige System.out.println – nutze Logger.
|
||||||
|
|
||||||
|
## Packages
|
||||||
|
- `business.<domain>` für Manager/Logik.
|
||||||
|
- `controller.<domain>` für JSF Backing Beans.
|
||||||
|
- `model.<domain>` für Entities/Enums.
|
||||||
|
|
||||||
|
## Benennung
|
||||||
|
- Manager endet auf `Manager` (CRUD + Fachlogik).
|
||||||
|
- Controller endet auf `Controller`.
|
||||||
|
- Entities nutzen Substantive singular (`SecurityArea`, `DangerPoint`).
|
||||||
|
- Enums nutzen PascalCase Konstanten (`APPROACH_SPEED`, hier bereits gemischt – beibehalten vorhandene Fälle, Konsistenz bei neuen).
|
||||||
|
|
||||||
|
## Fehlerbehandlung
|
||||||
|
- Aktuell: Logging + bool Rückgabe. Bei neuen komplexen Methoden: Ziehe eigene Exceptions in Betracht (`BusinessException`).
|
||||||
|
- Niemals stack trace verlieren – immer loggen. Falls Benutzerfeedback nötig → Message über Controller.
|
||||||
|
|
||||||
|
## Persistenz
|
||||||
|
- Vor Persist neuer Entity: ID muss `null` sein (oder negativ Fake-ID nur temporär). Setze beim finalen Speichern negative IDs auf `null`.
|
||||||
|
- Verwende `AbstractManager.refresh(entity)` um Lazy Collections zu initialisieren.
|
||||||
|
|
||||||
|
## Transaktionen
|
||||||
|
- Schreibmethoden erhalten `@Transactional`. Beim EJB Stateless reicht oft Container-Transaktion; Annotation verstärkt Klarheit.
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
- Sammel-Speicheroperationen bevorzugt `saveAll(Collection<T>)` statt Schleifen mit einzelnen Flushes.
|
||||||
|
- Beim Klonen großer Objektgraphen prüfen: Nur notwendige Collections initialisieren.
|
||||||
|
|
||||||
|
## UI / JSF
|
||||||
|
- Vermeide direkte Änderungen an listengebundenen Collections ohne Aktualisierung des Backing Beans (PrimeFaces kann sonst nicht updaten).
|
||||||
|
- Nutze klare Dialog-Helper (closeDialogs) statt roher JavaScript Strings.
|
||||||
|
|
||||||
|
## PDF
|
||||||
|
- Konsistenz: Verwende iText7 API für neue Funktionen. Markiere Altcode (iText5) für spätere Entfernung.
|
||||||
|
|
||||||
|
## Sicherheit
|
||||||
|
- Keine sensiblen Daten in Logs.
|
||||||
|
- Prüfe vor Löschaktionen, dass referenzielle Integrität gewährleistet (vor Entfernen Beziehungen lösen, wie im `deleteSelected()` umgesetzt).
|
||||||
|
|
||||||
|
## Tests (Empfehlung)
|
||||||
|
- JUnit + Arquillian für EJB/Entity Tests.
|
||||||
|
- Test-Namensschema: `<ClassName>Test`.
|
||||||
|
- Mindestens: CRUD, Klonen, Fragebogen hinzufügen/entfernen.
|
||||||
|
|
||||||
|
## Kommentar-Stil
|
||||||
|
- Klassenheader: Kurze Beschreibung Funktion/Zweck.
|
||||||
|
- Methoden: JavaDoc nur bei komplexer Logik / öffentlich verwendeten APIs.
|
||||||
|
|
||||||
|
## Anti-Pattern vermeiden
|
||||||
|
- "God Controller" – trenne Verantwortlichkeiten (nicht alles in einem Controller ansammeln).
|
||||||
|
- Direkte UI-Logik im Manager vermeiden.
|
||||||
|
|
||||||
|
---
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
|
|
||||||
Executable
+72
@@ -0,0 +1,72 @@
|
|||||||
|
# How-To: Projekt erweitern
|
||||||
|
|
||||||
|
## Neuer Fachbereich (Beispiel: InspectionReport)
|
||||||
|
|
||||||
|
### 1. Entity anlegen
|
||||||
|
- Paket: `model.report`.
|
||||||
|
- Klasse: `InspectionReport extends AbstractEntity`.
|
||||||
|
- Felder: `date`, `inspector`, `machine`, `remarks`.
|
||||||
|
- Named Queries definieren (z.B. `FIND_BY_MACHINE`).
|
||||||
|
|
||||||
|
### 2. Manager
|
||||||
|
```java
|
||||||
|
@Stateless
|
||||||
|
@Named
|
||||||
|
public class InspectionReportManager extends AbstractManager<InspectionReport> {
|
||||||
|
@PersistenceContext(name = "pu_person")
|
||||||
|
EntityManager em;
|
||||||
|
public InspectionReportManager() { super(InspectionReport.class); }
|
||||||
|
@Override protected EntityManager getEntityManager() { return em; }
|
||||||
|
// Fachmethoden: findByMachine(Long id)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Controller
|
||||||
|
```java
|
||||||
|
@ViewScoped
|
||||||
|
@Named
|
||||||
|
public class InspectionReportController extends AbstractController<InspectionReport> {
|
||||||
|
@EJB InspectionReportManager reportManager;
|
||||||
|
@Inject MachineController machineController;
|
||||||
|
public InspectionReportController() { setSelected(new InspectionReport()); setCreated(new InspectionReport()); }
|
||||||
|
@Override protected AbstractManager<InspectionReport> getManager() { return reportManager; }
|
||||||
|
@Override public void clearEntries() { setSelected(new InspectionReport()); setCreated(new InspectionReport()); getEntities().clear(); }
|
||||||
|
public void saveReport(){ reportManager.save(getSelected()); successMessage(); }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. UI Seite
|
||||||
|
- Pfad: `webapp/report/inspection.xhtml`.
|
||||||
|
- Binding: `#{inspectionReportController}`.
|
||||||
|
- Komponenten: Formular für Felder + Speichern Button.
|
||||||
|
|
||||||
|
### 5. Navigation
|
||||||
|
- Menüeintrag in globaler Navigationsstruktur (Tree oder Topbar) – analog `createMachineMenu()` Ansatz.
|
||||||
|
|
||||||
|
### 6. Tests
|
||||||
|
- Persistenz Test: Speichern + Laden.
|
||||||
|
- Manager Fachmethode Test.
|
||||||
|
|
||||||
|
## Erweiterung vorhandener Funktionalität
|
||||||
|
- Beispiel: Neue PDF Sektion → Ergänze Hilfsmethode in `AbstractController` (sofern allgemein). Falls spezifisch für eine Domäne, eher Hilfsklasse im Domain-Paket.
|
||||||
|
|
||||||
|
## Konsistenz-Checkliste
|
||||||
|
- [ ] Entity extends `AbstractEntity`
|
||||||
|
- [ ] Manager extends `AbstractManager`
|
||||||
|
- [ ] Controller extends `AbstractController`
|
||||||
|
- [ ] Negative IDs für neue Objekte vor Persist (falls in Listen)
|
||||||
|
- [ ] Internationale Zeichen (UTF-8) – POM setzt Encoding
|
||||||
|
- [ ] Logging bei Fehlern
|
||||||
|
|
||||||
|
## Deployment Hinweise
|
||||||
|
- Sicherstellen, dass neue Named Queries beim Serverstart verfügbar (Entity korrekt gescannt).
|
||||||
|
- Falls neue Ressourcen (Logos, Templates) → in `resources` pflegen.
|
||||||
|
|
||||||
|
## Typische Stolpersteine
|
||||||
|
- LazyInitializationException: Lösung `refresh(entity)` oder explizite Initialisierung im Manager.
|
||||||
|
- Doppelte Referenzen beim Klonen: IDs auf `null` setzen.
|
||||||
|
- Fehlende Transaktion: Sicherstellen `@Transactional` oder EJB Standard.
|
||||||
|
|
||||||
|
---
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
|
|
||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
# Workflow: Fragebögen in Sicherheitsbereichen
|
||||||
|
|
||||||
|
## Ziel
|
||||||
|
Zuordnung strukturiert erfassbarer Fragebögen (`Questionaire`) zu einem `SecurityArea` via `SecurityAreaQuestionnaire`.
|
||||||
|
|
||||||
|
## Beteiligte Klassen
|
||||||
|
- `SecurityAreaController` – UI Aktionen (add/remove, refresh).
|
||||||
|
- `SecurityAreaManager` – Persistenzoperationen (add/remove/reload, Verfügbarkeitsliste).
|
||||||
|
- `SecurityAreaQuestionnaire` – Assoziative Entity (enthält Name / ID des Fragebogens + Bezug zum Schutzbereich).
|
||||||
|
- `QuestionaireManager` (nicht gezeigt) – Verwaltung aller Fragebögen.
|
||||||
|
|
||||||
|
## Hinzufügen Ablauf
|
||||||
|
1. Nutzer wählt Schutzbereich + Fragebogen im Dialog.
|
||||||
|
2. Controller ruft `securityAreaManager.addQuestionnaireToSecurityArea(selectedArea, selectedQuestionnaire)`.
|
||||||
|
3. Manager:
|
||||||
|
- Lädt `area` (falls persistent) neu per `em.find`.
|
||||||
|
- Erzeugt neues `SecurityAreaQuestionnaire` Objekt.
|
||||||
|
- Setzt Relation (wrapper.setArea(area)).
|
||||||
|
- Persistiert Wrapper, merged Area.
|
||||||
|
4. Controller: `refrehSelected()` (Merge + Initialize Lazy Collections), zeigt Erfolgsmeldung.
|
||||||
|
|
||||||
|
## Entfernen Ablauf
|
||||||
|
1. Nutzer wählt zugeordneten Fragebogen (Wrapper-Objekt).
|
||||||
|
2. Controller ruft `securityAreaManager.removeQuestionnaireFromSecurityArea(area, wrapper)`.
|
||||||
|
3. Manager lädt Entities (falls notwendig), entfernt aus Collection, `em.remove(wrapper)`, `em.merge(area)`.
|
||||||
|
4. Controller aktualisiert Verfügbare Liste.
|
||||||
|
|
||||||
|
## Verfügbare Fragebögen
|
||||||
|
- Abfrage aller Fragebögen: `SELECT q FROM Questionaire q ORDER BY q.name`.
|
||||||
|
- Filter: Namen bereits zugeordneter Wrapper (Verbesserung: Filter per ID zur Sicherheit gegen Namensduplikate).
|
||||||
|
|
||||||
|
## Edge Cases
|
||||||
|
- Bereich / Fragebogen null: Controller zeigt Fehlermeldung.
|
||||||
|
- Concurrent Änderung: Nach Persist immer Refresh durchführen.
|
||||||
|
- Doppelte Zuordnung: Filter verhindert erneute Anzeige; Manager könnte zusätzlich prüfen (Collection enthält bereits Name).
|
||||||
|
|
||||||
|
## Verbesserungen
|
||||||
|
- Validierung auf Einzigartigkeit im Manager (statt nur UI Filter).
|
||||||
|
- Optimierte Fetch Strategie (JOIN FETCH) bei Reload.
|
||||||
|
- Nutzung eines Service zur Kapselung Geschäftslogik + Manager nur für CRUD.
|
||||||
|
|
||||||
|
## Beispiel Pseudocode (Hinzufügen)
|
||||||
|
```java
|
||||||
|
if (questionnaire != null && area != null) {
|
||||||
|
areaManager.addQuestionnaireToSecurityArea(area, questionnaire);
|
||||||
|
controller.refrehSelected();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
|
|
||||||
Regular → Executable
+97
@@ -0,0 +1,97 @@
|
|||||||
|
# Mechanismus: Refresh & Fake-ID
|
||||||
|
|
||||||
|
## Problemstellung
|
||||||
|
Im UI werden häufig neue Objekte in Collections angezeigt, bevor sie persistiert sind. Diese benötigen eine temporäre Identifikation (ID) für Auswahl/Operationen, ohne den Datenbankzustand zu verfälschen.
|
||||||
|
|
||||||
|
## Fake-ID Strategie
|
||||||
|
- Negative Long Werte (< 0) kennzeichnen nicht persistierte Objekte.
|
||||||
|
- Erzeugung: `AbstractController.createFakeID(Collection<ENT>)`:
|
||||||
|
- Startwert -1.
|
||||||
|
- Falls bereits negative IDs existieren → Nimmt die kleinste negative und subtrahiert 1.
|
||||||
|
- Ergebnis: Sequenz -1, -2, -3 ... (absteigend).
|
||||||
|
|
||||||
|
## Persistieren
|
||||||
|
Vor finalem Speichern (z.B. `SecurityAreaController.save()`):
|
||||||
|
1. Alle Entities mit `id < 0` → `setId(null)`.
|
||||||
|
2. `AbstractManager.saveAll()` unterscheidet durch `entity.getId() == null` zwischen Persist und Merge.
|
||||||
|
3. Datenbank vergibt positive ID (Auto Increment / Sequence).
|
||||||
|
|
||||||
|
## Vorteile
|
||||||
|
- Klare Unterscheidung UI-temporär vs. persistent.
|
||||||
|
- Verhindert versehentliches Auslösen von Merge bei noch nicht existierenden DB Zeilen.
|
||||||
|
|
||||||
|
## Risiken
|
||||||
|
- Verwechslung negativ gesetzter IDs mit echten IDs (nicht möglich, da DB positive IDs generiert).
|
||||||
|
- Direkte Verwendung negativer IDs in DB-Operationen (vermeiden: Prüfen auf `id > 0` vor `em.find`).
|
||||||
|
|
||||||
|
## Refresh
|
||||||
|
- Methode `AbstractController.refrehSelected()` (Tippfehler im Namen, historisch) ruft `getManager().refresh(selected)`.
|
||||||
|
- `AbstractManager.refresh(entity)`:
|
||||||
|
- Falls ID null → `save(entity)` (persistiert neues Objekt).
|
||||||
|
- `merge` für Managed Zustand und `Hibernate.initialize(entity)` zur Lazy Init.
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
- Nach komplexen Änderungen (Add/Remove Child Collections) Refresh durchführen wenn UI weitere Lazy Properties benötigt.
|
||||||
|
- Beim Klonen persistenter Objekte zuerst DB-Laden → danach Kopie erstellen.
|
||||||
|
|
||||||
|
## Potentielle Verbesserungen
|
||||||
|
- Korrektur Tippfehler `refrehSelected()` → `refreshSelected()` (Refactoring + Suchanpassungen).
|
||||||
|
- Kennzeichnung Fake-ID generierender Methoden mit JavaDoc für Klarheit.
|
||||||
|
|
||||||
|
---
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
|
# MSS Failsafe – Developer Einstieg
|
||||||
|
|
||||||
|
Dieses Verzeichnis bündelt technische Instruktionsdateien zur schnelleren Einarbeitung und zur Unterstützung automatischer Code-Generierung.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
1. Java Version: Quell-/Ziellevel im POM: 11 (Property 1.8 ist historisch, der Compiler-Plugin setzt auf 11). Nutze lokal JDK 11.
|
||||||
|
2. Application Server: Java EE 8 kompatibel (z.B. Payara 5 / WildFly 20 / GlassFish 5). Dependencies `javax.*` statt `jakarta.*`.
|
||||||
|
3. Build:
|
||||||
|
```cmd
|
||||||
|
mvn clean package
|
||||||
|
```
|
||||||
|
Ergebnis: `target/mss-1.0-SNAPSHOT.war`.
|
||||||
|
4. Deployment: WAR in kompatiblen EE 8 Server einspielen. Konfiguriere Datenquelle `pu_person` (JPA Persistence Unit – siehe `@PersistenceContext(name = "pu_person")`).
|
||||||
|
5. Logging: Log4j2 Konfiguration in `src/main/resources/log4j2.xml`.
|
||||||
|
6. Frontend: JSF 2.3 + PrimeFaces 11 + PrimeFlex 2.0.
|
||||||
|
|
||||||
|
## Wichtigste Schichten
|
||||||
|
- model: JPA Entities (`AbstractEntity` Basis – enthält ID).
|
||||||
|
- business: `*Manager` Klassen (Stateless EJBs) kapseln CRUD + Fachlogik.
|
||||||
|
- controller: View/Request/Session Scoped JSF Backing Beans (Interaktion UI ↔ Business Layer).
|
||||||
|
- webapp: XHTML Seiten (JSF Components + PrimeFaces).
|
||||||
|
- resources: Text-/Konfigurationsdateien, Checklisten.
|
||||||
|
|
||||||
|
## Kern-Patterns
|
||||||
|
- Manager erben von `AbstractManager<T>` (generisches CRUD mit `save`, `saveAll`, `remove`, `refresh`).
|
||||||
|
- Controller erben von `AbstractController<E>` (Message Handling, Fake-ID-Erzeugung für neue (noch nicht persistierte) Entities, PDF Hilfen, Auswahlzustand `selected/created`).
|
||||||
|
- Negative IDs (< 0) werden als temporäre (noch nicht persistierte) Objekte verwendet – wichtig bei UI-Listen vor Sammel-Speichern.
|
||||||
|
- Lazy Collections werden vor Nutzung mit `Hibernate.initialize(...)` initialisiert (Refresh/Reload Methoden).
|
||||||
|
|
||||||
|
## Erweiterung – Schnellanleitung
|
||||||
|
1. Neue Entity anlegen (JPA @Entity, extends `AbstractEntity`).
|
||||||
|
2. Manager erstellen: `@Stateless`, extends `AbstractManager<YourEntity>`, implementiert `getEntityManager()`. Zusätzliche Named Queries in Entity definieren.
|
||||||
|
3. Controller erstellen: `@Named`, Scope festlegen (`@ViewScoped`, `@SessionScoped`, etc.), extends `AbstractController<YourEntity>`, injiziere Manager mit `@EJB`.
|
||||||
|
4. XHTML Seite/Fragment erstellen und Controller referenzieren (`#{yourController}`) + PrimeFaces Komponenten.
|
||||||
|
5. Tests (optional, derzeit kaum vorhanden) – vorschlagen: Architektur-Test + Manager CRUD Test.
|
||||||
|
|
||||||
|
## Fragebögen / Sicherheitsbereiche
|
||||||
|
Ein ausführlicher Workflow liegt in `QUESTIONNAIRE_WORKFLOW.md` und `SECURITY_AREA_DOMAIN.md`.
|
||||||
|
|
||||||
|
## PDF-Erzeugung
|
||||||
|
- Verwendet iText (5.x + 7.x Module). Utilities liegen in `AbstractController` (Tabellen, Kopfzeilen, Seitennummern).
|
||||||
|
- Logo Pfad `LOGO_PATH = /rundata/logo.png` – stelle sicher, dass Datei beim Deployment verfügbar ist.
|
||||||
|
|
||||||
|
## Automatisierte Tools / AI Hinweise
|
||||||
|
Siehe `AI_INSTRUCTIONS.md` für formatierte Kontextbereitstellung.
|
||||||
|
|
||||||
|
## Nächste Verbesserungen (Empfehlungen)
|
||||||
|
- Konsolidierung auf iText7 (Legacy 5.x entfernen).
|
||||||
|
- Einheitliche Exception-Strategie (momentan Logging + bool Rückgabe).
|
||||||
|
- Mehr Unit Tests (Persistenz, Controller Interaktionen via Arquillian / Payara Micro).
|
||||||
|
- Migrationspfad Richtung Jakarta EE 9+ (Namespace Wechsel).
|
||||||
|
|
||||||
|
---
|
||||||
|
Letzte Aktualisierung: 2025-10-20
|
||||||
|
|
||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
# Domain: SecurityArea
|
||||||
|
|
||||||
|
## Zweck
|
||||||
|
Abbildung eines Schutzbereichs einer Maschine mit zugehörigen Schutzeinrichtungen, Gefahrenstellen und Schaltgeräten sowie Fragebögen zur Bewertung.
|
||||||
|
|
||||||
|
## Haupt-Entitäten (Ausschnitt)
|
||||||
|
- `SecurityArea`
|
||||||
|
- `SecurityDevice` (Liste in Area)
|
||||||
|
- `DangerPoint`
|
||||||
|
- `SwitchingDevice`
|
||||||
|
- `SecurityAreaQuestionnaire` (assoziative Entity zwischen Schutzbereich und `Questionaire`)
|
||||||
|
- `Questionaire`
|
||||||
|
|
||||||
|
## Lebenszyklus
|
||||||
|
1. Erstellung im UI: Neues `SecurityArea` Objekt mit Fake-ID (negativ).
|
||||||
|
2. Bearbeitung von Eigenschaften (Name, Typen/Enums: `ProtectionType`, `MountingPosition`, `OverrunMeasurementType`, `ApproachSpeed`).
|
||||||
|
3. Hinzufügen von Schutzeinrichtungen/Gefahrenstellen/Schaltgeräten (ebenfalls ggf. mit Fake-ID bis persistiert).
|
||||||
|
4. Speichern: Negative IDs der neuen Objekte werden auf `null` gesetzt → Persist durch `SecurityAreaManager.save` / Sammelspeicher.
|
||||||
|
5. Nach Persist: Re-Load (`refresh`/`reloadWithQuestionnaires`) vor weiterer Bearbeitung.
|
||||||
|
|
||||||
|
## Klonen
|
||||||
|
`SecurityAreaManager.cloneArea(SecurityArea area)`:
|
||||||
|
- Lädt persistente Quelle (falls ID > 0) vollständig.
|
||||||
|
- Erzeugt neue Kopie via Copy-Konstruktor.
|
||||||
|
- Controller passt Namen an (`Original (Kopie)`), setzt neue `null` IDs für untergeordnete Objekte.
|
||||||
|
|
||||||
|
## Fragebogen-Verknüpfung
|
||||||
|
### Hinzufügen
|
||||||
|
- Methode: `addQuestionnaireToSecurityArea(area, questionnaire)`.
|
||||||
|
- Erzeugt `SecurityAreaQuestionnaire` Wrapper.
|
||||||
|
- Persist Wrapper, merge Area.
|
||||||
|
- UI aktualisiert Liste und sendet Erfolgsmeldung.
|
||||||
|
|
||||||
|
### Entfernen
|
||||||
|
- `removeQuestionnaireFromSecurityArea(area, securityAreaQuestionnaire)` entfernt Element aus Sammlung & ruft `em.remove`.
|
||||||
|
|
||||||
|
### Verfügbare Fragebögen
|
||||||
|
- `getAvailableQuestionnaires(area)` holt alle `Questionaire` und filtert bereits zugeordnete anhand Name. Verbesserung: Nutzung ID statt Name zur Eindeutigkeit.
|
||||||
|
|
||||||
|
## Konsistenz / Referentielle Integrität
|
||||||
|
Beim Löschen eines Schutzbereichs (`deleteSelected()` im Controller):
|
||||||
|
1. Entfernen aus Maschine.
|
||||||
|
2. Auflösen aller Kind-Referenzen (SwitchingDevices, DangerPoints, SecurityDevices) durch Setzen der Area auf `null`.
|
||||||
|
3. Entfernen der Kindobjekte via entsprechende Manager (`removeAllIn`).
|
||||||
|
4. Löschen des `SecurityArea` via Named Query (`SecurityArea.DELETE`).
|
||||||
|
|
||||||
|
## Potentielle Verbesserungen
|
||||||
|
- Cascade Settings genauer prüfen (evtl. kann Teil der manuellen Löschlogik automatisiert werden).
|
||||||
|
- Validierung (Bean Validation) für Pflichtfelder (Name nicht leer, Enums nicht null soweit fachlich notwendig).
|
||||||
|
- Nutzung DTOs zur Entkopplung UI ↔ JPA (reduziert Lazy Probleme).
|
||||||
|
|
||||||
|
---
|
||||||
|
Aktualisiert: 2025-10-20
|
||||||
|
|
||||||
Executable
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scene Scope="Project" version="2">
|
||||||
|
<Scope Scope="Faces Configuration Only"/>
|
||||||
|
<Scope Scope="Project"/>
|
||||||
|
<Scope Scope="All Faces Configurations"/>
|
||||||
|
</Scene>
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<artifactId>mss-failsafe</artifactId>
|
|
||||||
<groupId>plate.software</groupId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
<groupId>plate.software</groupId>
|
|
||||||
<artifactId>mss</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
<packaging>war</packaging>
|
|
||||||
<name>mss-1.0-SNAPSHOT</name>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
|
||||||
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
|
||||||
<jakartaee>8.0</jakartaee>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax</groupId>
|
|
||||||
<artifactId>javaee-api</artifactId>
|
|
||||||
<version>${jakartaee}</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.glassfish.soteria</groupId>
|
|
||||||
<artifactId>javax.security.enterprise</artifactId>
|
|
||||||
<version>1.0</version> <!-- Stable version -->
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.omnifaces</groupId>
|
|
||||||
<artifactId>omnifaces</artifactId>
|
|
||||||
<version>3.11.1</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax</groupId>
|
|
||||||
<artifactId>javaee-web-api</artifactId>
|
|
||||||
<version>8.0</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.glassfish</groupId>
|
|
||||||
<artifactId>javax.faces</artifactId>
|
|
||||||
<version>2.3.0</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
|
||||||
<artifactId>log4j-api</artifactId>
|
|
||||||
<version>2.14.1</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
|
||||||
<artifactId>log4j-core</artifactId>
|
|
||||||
<version>2.14.1</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.primefaces</groupId>
|
|
||||||
<artifactId>primefaces</artifactId>
|
|
||||||
<version>10.0.0</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.webjars.npm</groupId>
|
|
||||||
<artifactId>primeflex</artifactId>
|
|
||||||
<version>2.0.0</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>3.1</version>
|
|
||||||
<configuration>
|
|
||||||
<source>1.8</source>
|
|
||||||
<target>1.8</target>
|
|
||||||
<compilerArguments>
|
|
||||||
<endorseddirs>${endorsed.dir}</endorseddirs>
|
|
||||||
</compilerArguments>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
|
||||||
<version>2.3</version>
|
|
||||||
<configuration>
|
|
||||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
|
||||||
<version>2.6</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>validate</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>copy</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<outputDirectory>${endorsed.dir}</outputDirectory>
|
|
||||||
<silent>true</silent>
|
|
||||||
<artifactItems>
|
|
||||||
<artifactItem>
|
|
||||||
<groupId>javax</groupId>
|
|
||||||
<artifactId>javaee-api</artifactId>
|
|
||||||
<version>${jakartaee}</version>
|
|
||||||
<type>jar</type>
|
|
||||||
</artifactItem>
|
|
||||||
</artifactItems>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</project>
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package business;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Patrick
|
|
||||||
* @param <T>
|
|
||||||
*/
|
|
||||||
public abstract class AbstractManager<T> {
|
|
||||||
|
|
||||||
private Class<T> entityClass;
|
|
||||||
|
|
||||||
public AbstractManager(Class<T> entityClass) {
|
|
||||||
this.entityClass = entityClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract EntityManager getEntityManager();
|
|
||||||
|
|
||||||
public void create(T entity) {
|
|
||||||
getEntityManager().persist(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void edit(T entity) {
|
|
||||||
getEntityManager().merge(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove(T entity) {
|
|
||||||
getEntityManager().remove(getEntityManager().merge(entity));
|
|
||||||
}
|
|
||||||
|
|
||||||
public T find(Object id) {
|
|
||||||
return getEntityManager().find(entityClass, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<T> findAll() {
|
|
||||||
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
|
|
||||||
cq.select(cq.from(entityClass));
|
|
||||||
return getEntityManager().createQuery(cq).getResultList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<T> findRange(int[] range) {
|
|
||||||
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
|
|
||||||
cq.select(cq.from(entityClass));
|
|
||||||
javax.persistence.Query q = getEntityManager().createQuery(cq);
|
|
||||||
q.setMaxResults(range[1] - range[0] + 1);
|
|
||||||
q.setFirstResult(range[0]);
|
|
||||||
return q.getResultList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int count() {
|
|
||||||
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
|
|
||||||
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
|
|
||||||
cq.select(getEntityManager().getCriteriaBuilder().count(rt));
|
|
||||||
javax.persistence.Query q = getEntityManager().createQuery(cq);
|
|
||||||
return ((Long) q.getSingleResult()).intValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package business.user;
|
|
||||||
|
|
||||||
import javax.ejb.EJB;
|
|
||||||
import javax.ejb.Startup;
|
|
||||||
import javax.enterprise.context.ApplicationScoped;
|
|
||||||
import javax.inject.Named;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Named(value = "DemoManager")
|
|
||||||
@ApplicationScoped
|
|
||||||
@Startup
|
|
||||||
public class DemoManager {
|
|
||||||
|
|
||||||
@EJB
|
|
||||||
PersonManager personManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new instance of NewJSFManagedBean
|
|
||||||
*/
|
|
||||||
public DemoManager() {
|
|
||||||
runDemos();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void runDemos(){
|
|
||||||
personManager.demo();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package business.user;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import static java.time.temporal.ChronoUnit.DAYS;
|
|
||||||
import static java.util.UUID.randomUUID;
|
|
||||||
import javax.ejb.Stateless;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.PersistenceContext;
|
|
||||||
|
|
||||||
import exception.InvalidEmailException;
|
|
||||||
import model.person.Token;
|
|
||||||
import model.person.enums.TokenType;
|
|
||||||
import model.person.Person;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import static java.time.Instant.now;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Patrick
|
|
||||||
*/
|
|
||||||
@Stateless
|
|
||||||
public class TokenManager {
|
|
||||||
|
|
||||||
@PersistenceContext(name = "pu_person")
|
|
||||||
private EntityManager em;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
PasswordManager passwordManager;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
PersonManager customerManager;
|
|
||||||
|
|
||||||
public String generate(final String email, final String ipAddress, final String description,
|
|
||||||
final TokenType tokenType) {
|
|
||||||
|
|
||||||
String rawToken = randomUUID().toString();
|
|
||||||
Instant expiration = now().plus(14, DAYS);
|
|
||||||
|
|
||||||
save(rawToken, email, ipAddress, description, tokenType, expiration);
|
|
||||||
|
|
||||||
return rawToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String generateFileToken(final String email, final String description) {
|
|
||||||
|
|
||||||
String rawToken = randomUUID().toString();
|
|
||||||
Instant expiration = now().plus(3, DAYS);
|
|
||||||
|
|
||||||
save(rawToken, email, null, description, TokenType.FILE, expiration);
|
|
||||||
|
|
||||||
return rawToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save(final String rawToken, final String email, final String ipAddress,
|
|
||||||
final String description, final TokenType tokenType, final Instant expiration) {
|
|
||||||
|
|
||||||
Person user = this.customerManager.getByEmail(email)
|
|
||||||
.orElseThrow(InvalidEmailException::new);
|
|
||||||
|
|
||||||
Token token = new Token();
|
|
||||||
|
|
||||||
token.setTokenHash(Arrays.toString(this.passwordManager.hashToken(rawToken)));
|
|
||||||
token.setExpiration(expiration);
|
|
||||||
token.setDescription(description);
|
|
||||||
token.setTokenType(tokenType);
|
|
||||||
token.setIpAddress(ipAddress);
|
|
||||||
|
|
||||||
user.addToken(token);
|
|
||||||
|
|
||||||
this.em.persist(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove(String token) {
|
|
||||||
this.em.createNamedQuery(Token.REMOVE_TOKEN)
|
|
||||||
.setParameter("tokenHash", token).executeUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeExpired() {
|
|
||||||
|
|
||||||
this.em.createNamedQuery(Token.REMOVE_EXPIRED_TOKEN)
|
|
||||||
.setParameter("timestamp", Instant.now())
|
|
||||||
.executeUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
package controller;
|
|
||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import javax.faces.application.FacesMessage;
|
|
||||||
import javax.faces.context.FacesContext;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Patrick
|
|
||||||
*/
|
|
||||||
public abstract class AbstractController implements Serializable{
|
|
||||||
private static final long serialVersionUID = -5908716187853409719L;
|
|
||||||
|
|
||||||
protected void sendInfoMessage(String title, String message){
|
|
||||||
FacesMessage facesMessage = new FacesMessage(
|
|
||||||
FacesMessage.SEVERITY_INFO, title, message);
|
|
||||||
addMessage(facesMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void sendWarnMessage(String title, String message){
|
|
||||||
FacesMessage facesMessage = new FacesMessage(
|
|
||||||
FacesMessage.SEVERITY_WARN, title, message);
|
|
||||||
addMessage(facesMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void sendErrorMessage(String title, String message){
|
|
||||||
FacesMessage facesMessage = new FacesMessage(
|
|
||||||
FacesMessage.SEVERITY_ERROR, title, message);
|
|
||||||
addMessage(facesMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void sendFatalMessage(String title, String message){
|
|
||||||
FacesMessage facesMessage = new FacesMessage(
|
|
||||||
FacesMessage.SEVERITY_FATAL, title, message);
|
|
||||||
addMessage(facesMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addMessage(FacesMessage message) {
|
|
||||||
FacesContext.getCurrentInstance().addMessage(null, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void errorMessage() {
|
|
||||||
String title = "Fehler!";
|
|
||||||
String info = "Es ist ein Fehler aufgetreten, bitte versuchen Sie es erneut!";
|
|
||||||
sendErrorMessage(title, info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package controller.person;
|
|
||||||
|
|
||||||
import controller.AbstractController;
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
|
||||||
import model.person.Person;
|
|
||||||
import model.person.enums.Call;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Named
|
|
||||||
@RequestScoped
|
|
||||||
public class PersonEditController extends AbstractController{
|
|
||||||
@Inject
|
|
||||||
PersonController personController;
|
|
||||||
|
|
||||||
private String email;
|
|
||||||
private Call call;
|
|
||||||
private String telefon;
|
|
||||||
private String password;
|
|
||||||
private String mobile;
|
|
||||||
private String fax;
|
|
||||||
private String firstname;
|
|
||||||
private String lastname;
|
|
||||||
private String title;
|
|
||||||
|
|
||||||
public PersonEditController() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
private void loadUserdata(){
|
|
||||||
Person activePerson = personController.getActiveUser();
|
|
||||||
|
|
||||||
email = activePerson.getEmail();
|
|
||||||
call = activePerson.getCall();
|
|
||||||
telefon = activePerson.getTelefon();
|
|
||||||
password = "********";
|
|
||||||
mobile = activePerson.getMobile();
|
|
||||||
fax = activePerson.getFax();
|
|
||||||
firstname = activePerson.getFirstname();
|
|
||||||
lastname = activePerson.getLastname();
|
|
||||||
title = activePerson.getTitle();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEmail() {
|
|
||||||
return email;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEmail(String email) {
|
|
||||||
this.email = email;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Call getCall() {
|
|
||||||
return call;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCall(Call call) {
|
|
||||||
this.call = call;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTelefon() {
|
|
||||||
return telefon;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTelefon(String telefon) {
|
|
||||||
this.telefon = telefon;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPassword() {
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPassword(String password) {
|
|
||||||
this.password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMobile() {
|
|
||||||
return mobile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMobile(String mobile) {
|
|
||||||
this.mobile = mobile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFax() {
|
|
||||||
return fax;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFax(String fax) {
|
|
||||||
this.fax = fax;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFirstname() {
|
|
||||||
return firstname;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFirstname(String firstname) {
|
|
||||||
this.firstname = firstname;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLastname() {
|
|
||||||
return lastname;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastname(String lastname) {
|
|
||||||
this.lastname = lastname;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTitle() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTitle(String title) {
|
|
||||||
this.title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package controller.person;
|
|
||||||
|
|
||||||
import business.user.PersonManager;
|
|
||||||
import business.user.UserPictureManager;
|
|
||||||
import controller.AbstractController;
|
|
||||||
import javax.ejb.EJB;
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
|
||||||
import model.files.Mime;
|
|
||||||
import model.files.UserPicture;
|
|
||||||
import model.person.Person;
|
|
||||||
import org.primefaces.event.FileUploadEvent;
|
|
||||||
import org.primefaces.model.file.UploadedFile;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Named
|
|
||||||
@RequestScoped
|
|
||||||
public class UserPictureController extends AbstractController {
|
|
||||||
|
|
||||||
private UserPicture picture;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
PersonController personController;
|
|
||||||
|
|
||||||
@EJB
|
|
||||||
UserPictureManager upManager;
|
|
||||||
|
|
||||||
@EJB
|
|
||||||
PersonManager personManager;
|
|
||||||
|
|
||||||
public void handleUserPictureUpload(FileUploadEvent event) {
|
|
||||||
UploadedFile file = event.getFile();
|
|
||||||
|
|
||||||
if (file != null && file.getContent() != null && file.getContent().length > 0 && file.getFileName() != null) {
|
|
||||||
|
|
||||||
if (createSaveUserPicture(file)) {
|
|
||||||
sendInfoMessage("Erfolg", this.picture.getName() + " wurde hochgeladen!");
|
|
||||||
} else {
|
|
||||||
sendErrorMessage("Fehler", "Es ist ein Fehler aufgetreten. Bitte Versuchen Sie es erneut!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean createSaveUserPicture(UploadedFile file) {
|
|
||||||
picture = null;
|
|
||||||
picture = personController.getActiveUser().getUserPicture();
|
|
||||||
boolean isNew = picture == null;
|
|
||||||
|
|
||||||
if (isNew) {
|
|
||||||
picture = new UserPicture();
|
|
||||||
}
|
|
||||||
|
|
||||||
setData(picture, file);
|
|
||||||
Person person = personManager.load(personController.getActiveUser());
|
|
||||||
person.setUserPicture(picture);
|
|
||||||
picture.setPerson(person);
|
|
||||||
|
|
||||||
if (isNew) {
|
|
||||||
upManager.create(picture);
|
|
||||||
} else {
|
|
||||||
upManager.edit(picture);
|
|
||||||
}
|
|
||||||
|
|
||||||
personManager.save(person);
|
|
||||||
personController.reloadActivePerson();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setData(UserPicture picture, UploadedFile file) {
|
|
||||||
picture.setName(file.getFileName());
|
|
||||||
picture.setFileData(file.getContent());
|
|
||||||
picture.setMime(Mime.getByMimeType(file.getContentType()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getMaxFileSize() {
|
|
||||||
return UserPicture.getSizeLimit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFileTypesRE() {
|
|
||||||
return UserPicture.getAllowedTypesRE();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package httpauthenticationmechanism;
|
|
||||||
|
|
||||||
import javax.enterprise.context.ApplicationScoped;
|
|
||||||
import javax.security.enterprise.credential.CallerOnlyCredential;
|
|
||||||
import javax.security.enterprise.credential.Credential;
|
|
||||||
import javax.security.enterprise.credential.UsernamePasswordCredential;
|
|
||||||
import javax.security.enterprise.identitystore.CredentialValidationResult;
|
|
||||||
import static javax.security.enterprise.identitystore.CredentialValidationResult.INVALID_RESULT;
|
|
||||||
import static javax.security.enterprise.identitystore.CredentialValidationResult.NOT_VALIDATED_RESULT;
|
|
||||||
import javax.security.enterprise.identitystore.IdentityStore;
|
|
||||||
|
|
||||||
import business.user.PersonManager;
|
|
||||||
import exception.InvalidCredentialException;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import javax.ejb.EJB;
|
|
||||||
import model.person.Person;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Patrick
|
|
||||||
*/
|
|
||||||
@ApplicationScoped
|
|
||||||
public class AppIdentityStore implements IdentityStore {
|
|
||||||
|
|
||||||
@EJB
|
|
||||||
PersonManager userManager;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int priority() {
|
|
||||||
return 90;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CredentialValidationResult validate(Credential credential) {
|
|
||||||
try {
|
|
||||||
|
|
||||||
// check if the credential was UsernamePasswordCredential
|
|
||||||
if (credential instanceof UsernamePasswordCredential) {
|
|
||||||
String username = ((UsernamePasswordCredential) credential).getCaller();
|
|
||||||
String password = ((UsernamePasswordCredential) credential).getPasswordAsString();
|
|
||||||
|
|
||||||
return validate(this.userManager.getByEmailAndPassword(username, password));
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the credential was CallerOnlyCredential
|
|
||||||
if (credential instanceof CallerOnlyCredential) {
|
|
||||||
String username = ((CallerOnlyCredential) credential).getCaller();
|
|
||||||
|
|
||||||
return validate(
|
|
||||||
this.userManager.getByEmail(username)
|
|
||||||
.orElseThrow(InvalidCredentialException::new)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (InvalidCredentialException e) {
|
|
||||||
return INVALID_RESULT;
|
|
||||||
}
|
|
||||||
return NOT_VALIDATED_RESULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
private CredentialValidationResult validate(Person person) {
|
|
||||||
Set<String> groups;
|
|
||||||
|
|
||||||
groups = person.getUserGroups().stream()
|
|
||||||
.map(gr -> gr.toString())
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
|
|
||||||
return new CredentialValidationResult(person.getEmail(), groups);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-85
@@ -1,85 +0,0 @@
|
|||||||
package httpauthenticationmechanism;
|
|
||||||
|
|
||||||
import business.user.PersonManager;
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import javax.ejb.EJB;
|
|
||||||
import javax.enterprise.context.ApplicationScoped;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.security.enterprise.AuthenticationStatus;
|
|
||||||
import javax.security.enterprise.authentication.mechanism.http.AutoApplySession;
|
|
||||||
import javax.security.enterprise.authentication.mechanism.http.CustomFormAuthenticationMechanismDefinition;
|
|
||||||
import javax.security.enterprise.authentication.mechanism.http.HttpAuthenticationMechanism;
|
|
||||||
import javax.security.enterprise.authentication.mechanism.http.HttpMessageContext;
|
|
||||||
import javax.security.enterprise.authentication.mechanism.http.LoginToContinue;
|
|
||||||
import javax.security.enterprise.authentication.mechanism.http.RememberMe;
|
|
||||||
import javax.security.enterprise.credential.Credential;
|
|
||||||
import javax.security.enterprise.identitystore.IdentityStore;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Patrick
|
|
||||||
*/
|
|
||||||
@AutoApplySession // For "Is user already logged-in?"
|
|
||||||
@RememberMe(
|
|
||||||
cookieMaxAgeSeconds = 60 * 60 * 24 * 14, // 14 days
|
|
||||||
cookieSecureOnly = false, // Remove this when login is served over HTTPS.
|
|
||||||
isRememberMeExpression = "#{self.isRememberMe(httpMessageContext)}"
|
|
||||||
)
|
|
||||||
@LoginToContinue(
|
|
||||||
loginPage = "/index.xhtml",
|
|
||||||
errorPage = "/error.xhtml",
|
|
||||||
useForwardToLogin = true
|
|
||||||
)
|
|
||||||
@ApplicationScoped
|
|
||||||
public class ApplicationConfig implements HttpAuthenticationMechanism{
|
|
||||||
|
|
||||||
final static Logger LOGGER = LogManager.getLogger(ApplicationConfig.class);
|
|
||||||
|
|
||||||
public ApplicationConfig() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private IdentityStore identityStore;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private ManagedPerson managedPerson;
|
|
||||||
|
|
||||||
@EJB
|
|
||||||
private PersonManager personManager;
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
private void init(){
|
|
||||||
managedPerson.getLogins();
|
|
||||||
personManager.demo();
|
|
||||||
|
|
||||||
System.out.println("PostConstruct DEMO");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AuthenticationStatus validateRequest(HttpServletRequest req, HttpServletResponse res, HttpMessageContext context) {
|
|
||||||
|
|
||||||
Credential credential = context.getAuthParameters().getCredential();
|
|
||||||
|
|
||||||
if (credential != null) {
|
|
||||||
return context.notifyContainerAboutLogin(this.identityStore.validate(credential));
|
|
||||||
} else {
|
|
||||||
return context.doNothing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// this was called on @RememberMe annotations
|
|
||||||
public Boolean isRememberMe(HttpMessageContext httpMessageContext) {
|
|
||||||
return httpMessageContext.getAuthParameters().isRememberMe();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cleanSubject(HttpServletRequest request, HttpServletResponse response, HttpMessageContext httpMessageContext) {
|
|
||||||
HttpAuthenticationMechanism.super.cleanSubject(request, response, httpMessageContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package httpauthenticationmechanism;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.enterprise.context.ApplicationScoped;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Patrick
|
|
||||||
*/
|
|
||||||
@Named(value = "managedPerson")
|
|
||||||
@ApplicationScoped
|
|
||||||
public class ManagedPerson {
|
|
||||||
|
|
||||||
private Set<String> logins;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new instance of ManagedCustomer
|
|
||||||
*/
|
|
||||||
public ManagedPerson() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<String> getLogins(){
|
|
||||||
if (this.logins == null) {
|
|
||||||
this.logins = new HashSet<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.logins;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addLogin(String user){
|
|
||||||
getLogins().add(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeLogin(String user){
|
|
||||||
getLogins().remove(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,214 +0,0 @@
|
|||||||
package model.adresses;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
import javax.persistence.MappedSuperclass;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import model.AbstractEntity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Patrick
|
|
||||||
*/
|
|
||||||
@MappedSuperclass
|
|
||||||
public class Address extends AbstractEntity{
|
|
||||||
|
|
||||||
//Land
|
|
||||||
@NotNull(message = "Land darf nicht null sein")
|
|
||||||
private String country;
|
|
||||||
|
|
||||||
//Straßenname
|
|
||||||
@NotNull(message = "Strasse darf nicht null sein")
|
|
||||||
private String street;
|
|
||||||
|
|
||||||
//Hausnummer
|
|
||||||
@NotNull(message = "Hausnummer darf nicht null sein")
|
|
||||||
private String number;
|
|
||||||
|
|
||||||
//Zusatz
|
|
||||||
private String extra;
|
|
||||||
|
|
||||||
//PLZ
|
|
||||||
@NotNull(message = "PLZ darf nicht null sein")
|
|
||||||
private Integer postnumber;
|
|
||||||
|
|
||||||
//Bundesland
|
|
||||||
@NotNull(message = "Bundesland darf nicht null sein")
|
|
||||||
private String county;
|
|
||||||
|
|
||||||
//Ort
|
|
||||||
@NotNull(message = "Ort darf nicht null sein")
|
|
||||||
private String place;
|
|
||||||
|
|
||||||
private String contact;
|
|
||||||
|
|
||||||
private String comment;
|
|
||||||
|
|
||||||
public Address() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Address(String street, String number, String extra, Integer postnumber, String county, String place) {
|
|
||||||
this.street = street;
|
|
||||||
this.number = number;
|
|
||||||
this.extra = extra;
|
|
||||||
this.postnumber = postnumber;
|
|
||||||
this.county = county;
|
|
||||||
this.place = place;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Address(String country, String street, String number, String extra, Integer postnumber, String county, String place) {
|
|
||||||
this.country = country;
|
|
||||||
this.street = street;
|
|
||||||
this.number = number;
|
|
||||||
this.extra = extra;
|
|
||||||
this.postnumber = postnumber;
|
|
||||||
this.county = county;
|
|
||||||
this.place = place;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Address(String country, String street, String number, String extra, Integer postnumber, String county, String place, String contact, String comment) {
|
|
||||||
this.country = country;
|
|
||||||
this.street = street;
|
|
||||||
this.number = number;
|
|
||||||
this.extra = extra;
|
|
||||||
this.postnumber = postnumber;
|
|
||||||
this.county = county;
|
|
||||||
this.place = place;
|
|
||||||
this.contact = contact;
|
|
||||||
this.comment = comment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Address(Address toCopyAddress){
|
|
||||||
this.country = toCopyAddress.getCountry();
|
|
||||||
this.street = toCopyAddress.getStreet();
|
|
||||||
this.number = toCopyAddress.getNumber();
|
|
||||||
this.extra = toCopyAddress.getExtra();
|
|
||||||
this.postnumber = toCopyAddress.getPostnumber();
|
|
||||||
this.county = toCopyAddress.getCounty();
|
|
||||||
this.place = toCopyAddress.getPlace();
|
|
||||||
this.contact = toCopyAddress.getContact();
|
|
||||||
this.comment = toCopyAddress.getComment();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int hash = 7;
|
|
||||||
hash = 83 * hash + Objects.hashCode(this.country);
|
|
||||||
hash = 83 * hash + Objects.hashCode(this.street);
|
|
||||||
hash = 83 * hash + Objects.hashCode(this.number);
|
|
||||||
hash = 83 * hash + Objects.hashCode(this.extra);
|
|
||||||
hash = 83 * hash + Objects.hashCode(this.postnumber);
|
|
||||||
hash = 83 * hash + Objects.hashCode(this.county);
|
|
||||||
hash = 83 * hash + Objects.hashCode(this.place);
|
|
||||||
hash = 83 * hash + Objects.hashCode(this.contact);
|
|
||||||
hash = 83 * hash + Objects.hashCode(this.comment);
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (getClass() != obj.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final Address other = (Address) obj;
|
|
||||||
if (!Objects.equals(this.country, other.country)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!Objects.equals(this.street, other.street)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!Objects.equals(this.number, other.number)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!Objects.equals(this.extra, other.extra)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!Objects.equals(this.county, other.county)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!Objects.equals(this.place, other.place)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!Objects.equals(this.comment, other.comment)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return Objects.equals(this.postnumber, other.postnumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStreet() {
|
|
||||||
return street;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStreet(String street) {
|
|
||||||
this.street = street;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNumber() {
|
|
||||||
return number;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNumber(String number) {
|
|
||||||
this.number = number;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getExtra() {
|
|
||||||
return extra;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setExtra(String extra) {
|
|
||||||
this.extra = extra;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getPostnumber() {
|
|
||||||
return postnumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPostnumber(Integer postnumber) {
|
|
||||||
this.postnumber = postnumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCounty() {
|
|
||||||
return county;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCounty(String county) {
|
|
||||||
this.county = county;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPlace() {
|
|
||||||
return place;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlace(String place) {
|
|
||||||
this.place = place;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCountry() {
|
|
||||||
return country;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCountry(String country) {
|
|
||||||
this.country = country;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getContact() {
|
|
||||||
return contact;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContact(String contact) {
|
|
||||||
this.contact = contact;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getComment() {
|
|
||||||
return comment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setComment(String comment) {
|
|
||||||
this.comment = comment;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.company;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.ManyToMany;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
import javax.persistence.OneToOne;
|
|
||||||
import model.AbstractEntity;
|
|
||||||
import model.adresses.LocationAddress;
|
|
||||||
import model.customer.Customer;
|
|
||||||
import model.machine.Machine;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
public class Location extends AbstractEntity{
|
|
||||||
|
|
||||||
@ManyToOne
|
|
||||||
private Company company;
|
|
||||||
|
|
||||||
@OneToOne
|
|
||||||
private LocationAddress address;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "location")
|
|
||||||
private Set<Machine> machines;
|
|
||||||
|
|
||||||
@ManyToMany
|
|
||||||
private Set<Customer> contacts;
|
|
||||||
|
|
||||||
public Location() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Company getCompany() {
|
|
||||||
return company;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCompany(Company company) {
|
|
||||||
this.company = company;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocationAddress getAddress() {
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAddress(LocationAddress address) {
|
|
||||||
this.address = address;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Machine> getMachines() {
|
|
||||||
return machines;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMachines(Set<Machine> machines) {
|
|
||||||
this.machines = machines;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Customer> getContacts() {
|
|
||||||
return contacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContacts(Set<Customer> contacts) {
|
|
||||||
this.contacts = contacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.customer;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.ManyToMany;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import model.person.Person;
|
|
||||||
import model.company.Company;
|
|
||||||
import model.company.Location;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
public class Customer extends Person{
|
|
||||||
|
|
||||||
@ManyToOne
|
|
||||||
private Company company;
|
|
||||||
|
|
||||||
@ManyToMany
|
|
||||||
private Set<Location> locations;
|
|
||||||
|
|
||||||
@Column(nullable = true, length = 210)
|
|
||||||
private String note;
|
|
||||||
|
|
||||||
public Customer() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer(Company company) {
|
|
||||||
this.company = company;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Company getCompany() {
|
|
||||||
return company;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCompany(Company company) {
|
|
||||||
this.company = company;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Location> getLocations() {
|
|
||||||
return locations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLocations(Set<Location> locations) {
|
|
||||||
this.locations = locations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNote() {
|
|
||||||
return note;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNote(String note) {
|
|
||||||
this.note = note;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.machine;
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import model.AbstractEntity;
|
|
||||||
import model.company.Location;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
public class Machine extends AbstractEntity {
|
|
||||||
|
|
||||||
@ManyToOne
|
|
||||||
private Location location;
|
|
||||||
|
|
||||||
public Machine() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Location getLocation() {
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLocation(Location location) {
|
|
||||||
this.location = location;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.ticket;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.Objects;
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import model.AbstractEntity;
|
|
||||||
import model.person.Person;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Patrick
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
public class Comment extends AbstractEntity implements Comparable<Comment> {
|
|
||||||
|
|
||||||
@Column(columnDefinition = "longblob")
|
|
||||||
private String message;
|
|
||||||
|
|
||||||
@ManyToOne
|
|
||||||
private Person writer;
|
|
||||||
|
|
||||||
private boolean edited;
|
|
||||||
|
|
||||||
@ManyToOne
|
|
||||||
private Ticket ticket;
|
|
||||||
|
|
||||||
public Comment() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Comment(Person writer, String message) {
|
|
||||||
this.writer = writer;
|
|
||||||
this.edited = false;
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMessage() {
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMessage(String message) {
|
|
||||||
this.message = message;
|
|
||||||
edited = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getLastEditedDate() {
|
|
||||||
return getChangedDate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEdited() {
|
|
||||||
return edited;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEdited(boolean edited) {
|
|
||||||
this.edited = edited;
|
|
||||||
setChangedDate(LocalDateTime.now());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Ticket getTicket() {
|
|
||||||
return ticket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTicket(Ticket ticket) {
|
|
||||||
this.ticket = ticket;
|
|
||||||
setChangedDate(LocalDateTime.now());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Person getWriter() {
|
|
||||||
return writer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int hash = 7;
|
|
||||||
hash = 79 * hash + Objects.hashCode(this.message);
|
|
||||||
hash = 79 * hash + Objects.hashCode(this.writer);
|
|
||||||
hash = 79 * hash + Objects.hashCode(getCreationDate());
|
|
||||||
hash = 79 * hash + Objects.hashCode(getChangedDate());
|
|
||||||
hash = 79 * hash + (this.edited ? 1 : 0);
|
|
||||||
hash = 79 * hash + Objects.hashCode(this.ticket);
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (getClass() != obj.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final Comment other = (Comment) obj;
|
|
||||||
if (this.edited != other.edited) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!Objects.equals(this.message, other.message)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!Objects.equals(this.writer, other.writer)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!Objects.equals(getCreationDate(), other.getCreationDate())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!Objects.equals(this.ticket, other.ticket)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Comment{" + "writer=" + writer.getEmail() + ", creationDate=" + getCreationDate() + ", id=" + getId() + ", message="+ message + '}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(Comment c) {
|
|
||||||
return c.getCreationDate().compareTo(this.getCreationDate());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.ticket;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
public enum FilenameGeneration {
|
|
||||||
INSPEKTIONNR,
|
|
||||||
MASCHINEDESCRIPTION,
|
|
||||||
LOCATION;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
switch(this){
|
|
||||||
case INSPEKTIONNR:
|
|
||||||
return "inspektionnr";
|
|
||||||
case MASCHINEDESCRIPTION:
|
|
||||||
return "maschinedescription";
|
|
||||||
case LOCATION:
|
|
||||||
return "location";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "nothing";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.ticket;
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import model.AbstractEntity;
|
|
||||||
import javax.persistence.OneToOne;
|
|
||||||
import model.machine.Machine;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
public class LocationMachine extends AbstractEntity{
|
|
||||||
@OneToOne
|
|
||||||
private Machine machine;
|
|
||||||
|
|
||||||
@ManyToOne
|
|
||||||
private TicketLocation ticketLocation;
|
|
||||||
|
|
||||||
public LocationMachine() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Machine getMachine() {
|
|
||||||
return machine;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMachine(Machine machine) {
|
|
||||||
this.machine = machine;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TicketLocation getTicketLocation() {
|
|
||||||
return ticketLocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTicketLocation(TicketLocation ticketLocation) {
|
|
||||||
this.ticketLocation = ticketLocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,189 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.ticket;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.persistence.CascadeType;
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.EnumType;
|
|
||||||
import javax.persistence.Enumerated;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
import javax.persistence.OneToOne;
|
|
||||||
import model.AbstractEntity;
|
|
||||||
import model.adresses.CompanyBillingAddress;
|
|
||||||
import model.company.Company;
|
|
||||||
import model.files.Invoice;
|
|
||||||
import model.files.Report;
|
|
||||||
import model.person.Person;
|
|
||||||
import model.person.Token;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
public class Ticket extends AbstractEntity{
|
|
||||||
|
|
||||||
@ManyToOne(optional = false)
|
|
||||||
private Company company;
|
|
||||||
|
|
||||||
@OneToOne
|
|
||||||
private CompanyBillingAddress billingAddress;
|
|
||||||
|
|
||||||
@Column(nullable = false)
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
private Status status;
|
|
||||||
|
|
||||||
@OneToOne(optional = false)
|
|
||||||
private Person creator;
|
|
||||||
|
|
||||||
@OneToOne(optional = true)
|
|
||||||
private Person owner;
|
|
||||||
|
|
||||||
private LocalDateTime startDate;
|
|
||||||
|
|
||||||
private LocalDateTime endDate;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "ticket", cascade = CascadeType.ALL)
|
|
||||||
private List<Comment> comments;
|
|
||||||
|
|
||||||
private boolean payed;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "ticket", orphanRemoval = true, cascade = CascadeType.ALL)
|
|
||||||
private List<Token> tokens;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "ticket", cascade = {CascadeType.PERSIST, CascadeType.PERSIST})
|
|
||||||
private List<Report> reports;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "ticket", cascade = {CascadeType.PERSIST, CascadeType.PERSIST})
|
|
||||||
private List<Invoice> invoices;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "ticket", cascade = {CascadeType.PERSIST, CascadeType.PERSIST})
|
|
||||||
private List<TicketLocation> locations;
|
|
||||||
|
|
||||||
@Column(nullable = false, length = 200)
|
|
||||||
private String filenameGeneration;
|
|
||||||
|
|
||||||
public Ticket() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public CompanyBillingAddress getBillingAddress() {
|
|
||||||
return billingAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBillingAddress(CompanyBillingAddress billingAddress) {
|
|
||||||
this.billingAddress = billingAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getStartDate() {
|
|
||||||
return startDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStartDate(LocalDateTime startDate) {
|
|
||||||
this.startDate = startDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getEndDate() {
|
|
||||||
return endDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEndDate(LocalDateTime endDate) {
|
|
||||||
this.endDate = endDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Company getCompany() {
|
|
||||||
return company;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCompany(Company company) {
|
|
||||||
this.company = company;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<TicketLocation> getLocations() {
|
|
||||||
return locations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLocations(List<TicketLocation> locations) {
|
|
||||||
this.locations = locations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Status getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(Status status) {
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Person getCreator() {
|
|
||||||
return creator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCreator(Person creator) {
|
|
||||||
this.creator = creator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Person getOwner() {
|
|
||||||
return owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOwner(Person owner) {
|
|
||||||
this.owner = owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Comment> getComments() {
|
|
||||||
return comments;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setComments(List<Comment> comments) {
|
|
||||||
this.comments = comments;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isPayed() {
|
|
||||||
return payed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPayed(boolean payed) {
|
|
||||||
this.payed = payed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Token> getTokens() {
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTokens(List<Token> tokens) {
|
|
||||||
this.tokens = tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Report> getReports() {
|
|
||||||
return reports;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReports(List<Report> reports) {
|
|
||||||
this.reports = reports;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Invoice> getInvoices() {
|
|
||||||
return invoices;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInvoices(List<Invoice> invoices) {
|
|
||||||
this.invoices = invoices;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFilenameGeneration() {
|
|
||||||
return filenameGeneration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFilenameGeneration(String filenameGeneration) {
|
|
||||||
this.filenameGeneration = filenameGeneration;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.ticket;
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.OneToOne;
|
|
||||||
import model.AbstractEntity;
|
|
||||||
import model.company.Location;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
public class TicketLocation extends AbstractEntity{
|
|
||||||
@ManyToOne
|
|
||||||
private Ticket ticket;
|
|
||||||
|
|
||||||
@OneToOne
|
|
||||||
private Location location;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "ticketLocation")
|
|
||||||
private List<LocationMachine> machines;
|
|
||||||
|
|
||||||
|
|
||||||
public TicketLocation() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Ticket getTicket() {
|
|
||||||
return ticket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTicket(Ticket ticket) {
|
|
||||||
this.ticket = ticket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Location getLocation() {
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLocation(Location location) {
|
|
||||||
this.location = location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<LocationMachine> getMachines() {
|
|
||||||
return machines;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMachines(List<LocationMachine> machines) {
|
|
||||||
this.machines = machines;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
|
|
||||||
bean-discovery-mode="all">
|
|
||||||
</beans>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<jboss-web xmlns="http://www.jboss.com/xml/ns/javaee"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-web_10_0.xsd"
|
|
||||||
version="10.0">
|
|
||||||
<security-domain>mss-failsafe</security-domain>
|
|
||||||
</jboss-web>
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
|
||||||
xmlns:h="http://java.sun.com/jsf/html"
|
|
||||||
xmlns:f="http://java.sun.com/jsf/core"
|
|
||||||
xmlns:p="http://primefaces.org/ui">
|
|
||||||
|
|
||||||
<h:head>
|
|
||||||
<title>Willkommen #{personController.activeUser.call.toString()} #{personController.activeUser.lastname}</title>
|
|
||||||
</h:head>
|
|
||||||
|
|
||||||
<h:body>
|
|
||||||
<p>Willkommen #{personController.activeUser.call.toString()} #{personController.activeUser.lastname}</p>
|
|
||||||
<p:spinner />
|
|
||||||
</h:body>
|
|
||||||
</html>
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
|
||||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
|
||||||
xmlns:p="http://primefaces.org/ui"
|
|
||||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
|
||||||
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
|
|
||||||
<h:head>
|
|
||||||
<title>Login Testpage</title>
|
|
||||||
</h:head>
|
|
||||||
<h:body>
|
|
||||||
<h:form id="login">
|
|
||||||
<p:panel header="Login" style="width: 450px; margin: auto; margin-top: 100px;">
|
|
||||||
<p:messages id="messages" showDetail="true" closable="true">
|
|
||||||
<p:autoUpdate />
|
|
||||||
</p:messages>
|
|
||||||
<p:graphicImage url="/resources/images/logo.jpg" alt="MSS Machine Safety Services" style="width: 100%;"/>
|
|
||||||
<h:panelGrid columns="2" cellpadding="5">
|
|
||||||
|
|
||||||
<p:outputLabel for="username" value="Email" />
|
|
||||||
<p:inputText id="username" value="#{personController.username}" required="true" label="username" />
|
|
||||||
|
|
||||||
<p:outputLabel for="password" value="Password:" />
|
|
||||||
<p:password id="password" value="#{personController.password}" required="true" label="password" />
|
|
||||||
|
|
||||||
<p:outputLabel for="rememberMe" value="Remember Me:" />
|
|
||||||
<p:selectBooleanCheckbox id="rememberMe" value="#{personController.rememberMe}" />
|
|
||||||
|
|
||||||
<f:facet name="footer">
|
|
||||||
<p:commandButton value="Login" action="#{personController.submit()}" ajax="false"/>
|
|
||||||
</f:facet>
|
|
||||||
</h:panelGrid>
|
|
||||||
</p:panel>
|
|
||||||
</h:form>
|
|
||||||
|
|
||||||
</h:body>
|
|
||||||
</html>
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' ?>
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
|
||||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
|
||||||
xmlns:f = "http://java.sun.com/jsf/core"
|
|
||||||
xmlns:p="http://primefaces.org/ui"
|
|
||||||
xmlns:h="http://xmlns.jcp.org/jsf/html">
|
|
||||||
|
|
||||||
|
|
||||||
<h:head>
|
|
||||||
<f:facet name="last">
|
|
||||||
<h:outputStylesheet library="css" name="default.css"/>
|
|
||||||
<h:outputStylesheet library="css" name="icons.css"/>
|
|
||||||
<h:outputStylesheet library="webjars" name="primeflex/2.0.0/primeflex.min.css" />
|
|
||||||
</f:facet>
|
|
||||||
<title>
|
|
||||||
<ui:insert name="title">
|
|
||||||
Please add a Title!
|
|
||||||
</ui:insert>
|
|
||||||
</title>
|
|
||||||
<ui:insert name="head"/>
|
|
||||||
</h:head>
|
|
||||||
|
|
||||||
<h:body>
|
|
||||||
<h:form id="main">
|
|
||||||
<div class="p-grid">
|
|
||||||
<div class="p-col-12 p-md-3 p-lg-2 p-xl-2">
|
|
||||||
<div class="p-col-12" style="min-height: 90px;">
|
|
||||||
<p:commandLink action="welcome">
|
|
||||||
<p:graphicImage url="../resources/images/logo.jpg" alt="MSS Machine Safety Services" style="width: 100%;"/>
|
|
||||||
</p:commandLink>
|
|
||||||
</div>
|
|
||||||
<div class="p-col-12">
|
|
||||||
<p:menu style="width: 100%;">
|
|
||||||
<p:submenu label="Home">
|
|
||||||
<p:menuitem value="Home" outcome="welcome" icon="pi pi-home"/>
|
|
||||||
<p:menuitem value="Suche" outcome="welcome" icon="pi pi-search"/>
|
|
||||||
</p:submenu>
|
|
||||||
<p:submenu label="Ticket">
|
|
||||||
<p:menuitem value="Erstellen" outcome="welcome" icon="pi pi-plus"/>
|
|
||||||
<p:menuitem value="Suchen" outcome="welcome" icon="pi pi-search"/>
|
|
||||||
</p:submenu>
|
|
||||||
<p:submenu label="Stammdaten">
|
|
||||||
<p:menuitem value="Firmen" outcome="companies" icon="icon company"/>
|
|
||||||
<p:menuitem value="Standorte" outcome="locations" icon="icon location"/>
|
|
||||||
<p:menuitem value="Maschienen" outcome="machines" icon="icon machine"/>
|
|
||||||
<p:menuitem value="Schutzeinr." outcome="protection" icon="icon security"/>
|
|
||||||
</p:submenu>
|
|
||||||
</p:menu>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="p-col-12 p-md-9 p-lg-10 p-xl-10">
|
|
||||||
<div class="card p-col-12" style="min-height: 90px; text-align: right;">
|
|
||||||
|
|
||||||
<p:menu overlay="true" trigger="avatar" my="left top" at="bottom left">
|
|
||||||
<p:menuitem value="Profil" outcome="profile"/>
|
|
||||||
<p:menuitem value="Einstellungen" />
|
|
||||||
<p:menuitem value="Ausloggen" action="#{personController.logout()}" />
|
|
||||||
</p:menu>
|
|
||||||
|
|
||||||
<p:avatar dynamicColor="true" id="avatar" icon="pi pi-user" styleClass="p-mr-2 avatar" size="large" shape="circle" gravatar="#{personController.activeUser.email}">
|
|
||||||
<p:graphicImage value="#{personController.activeUser.userPicture.fileData}" rendered="#{personController.hasPicture()}"/>
|
|
||||||
</p:avatar>
|
|
||||||
</div>
|
|
||||||
<div class="p-col-12" style="width: 100%">
|
|
||||||
<div class="card p-col-12">
|
|
||||||
<p:growl showDetail="true">
|
|
||||||
<p:autoUpdate/>
|
|
||||||
</p:growl>
|
|
||||||
</div>
|
|
||||||
<div class="card p-col-12">
|
|
||||||
<ui:insert name="content">Content</ui:insert>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="p-col-12 p-lg-12 p-xl-12">
|
|
||||||
<ui:insert name="bottom">Bottom</ui:insert>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</h:form>
|
|
||||||
</h:body>
|
|
||||||
</html>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<ui:composition template="/resources/layout/user/template.xhtml"
|
|
||||||
xmlns="http://www.w3.org/1999/xhtml"
|
|
||||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
|
||||||
xmlns:p="http://primefaces.org/ui"
|
|
||||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
|
||||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
|
|
||||||
<ui:define name="title">
|
|
||||||
Firmen
|
|
||||||
</ui:define>
|
|
||||||
|
|
||||||
<ui:define name="content">
|
|
||||||
Willkommen zuhause
|
|
||||||
</ui:define>
|
|
||||||
|
|
||||||
<ui:define name="bottom">
|
|
||||||
|
|
||||||
</ui:define>
|
|
||||||
|
|
||||||
</ui:composition>
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
<ui:composition template="/resources/layout/user/template.xhtml"
|
|
||||||
xmlns="http://www.w3.org/1999/xhtml"
|
|
||||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
|
||||||
xmlns:p="http://primefaces.org/ui"
|
|
||||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
|
||||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
|
|
||||||
<ui:define name="title">
|
|
||||||
Willkommen #{personController.activeUser.call.toString()} #{personController.activeUser.lastname}
|
|
||||||
</ui:define>
|
|
||||||
|
|
||||||
<ui:define name="content">
|
|
||||||
<div class="p-grid">
|
|
||||||
<div class="card p-col-5 p-md-6 p-xl-6">
|
|
||||||
<p:fileUpload mode="advanced"
|
|
||||||
multiple="false"
|
|
||||||
sizeLimit="#{userPictureController.maxFileSize}" allowTypes="#{userPictureController.fileTypesRE}"
|
|
||||||
invalidSizeMessage="Maximum file size allowed is 2 MB"
|
|
||||||
invalidFileMessage="only gif | jpg | jpeg | png is allowed"
|
|
||||||
update="main"
|
|
||||||
listener="#{userPictureController.handleUserPictureUpload}"/>
|
|
||||||
</div>
|
|
||||||
<div class="card p-col-7 p-md-6 p-xl-6" style="text-align: right;">
|
|
||||||
<p:graphicImage style="max-width: 500px; max-height: 300px; margin-right: 20%;" id="image" value="#{personController.activeUser.userPicture.fileData}" rendered="#{personController.hasPicture()}"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card p-col-12 p-md-6 p-xl-6">
|
|
||||||
<div class="ui-fluid p-formgrid p-grid">
|
|
||||||
<div class="p-field p-col-8 p-md-8">
|
|
||||||
<p:outputLabel for="email" value="Email" />
|
|
||||||
<p:inputText readonly="true" id="email" value="#{personEditController.email}" />
|
|
||||||
</div>
|
|
||||||
<div class="p-field p-col-4 p-md-4" style="float: right;">
|
|
||||||
<br />
|
|
||||||
<p:commandButton value="Ändern"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-8 p-md-8">
|
|
||||||
<p:outputLabel for="password" value="Password" />
|
|
||||||
<p:inputText readonly="true" id="password" value="#{personEditController.password}" />
|
|
||||||
</div>
|
|
||||||
<div class="p-field p-col-4 p-md-4" style="float: right;">
|
|
||||||
<br />
|
|
||||||
<p:commandButton value="Ändern"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-8 p-md-8">
|
|
||||||
<p:outputLabel for="telefon" value="Telefon" />
|
|
||||||
<p:inputText readonly="true" id="telefon" value="#{personEditController.telefon}" />
|
|
||||||
</div>
|
|
||||||
<div class="p-field p-col-4 p-md-4" style="float: right;">
|
|
||||||
<br />
|
|
||||||
<p:commandButton value="Ändern"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-8 p-md-8">
|
|
||||||
<p:outputLabel for="mobile" value="Handy" />
|
|
||||||
<p:inputText readonly="true" id="mobile" value="#{personEditController.mobile}" />
|
|
||||||
</div>
|
|
||||||
<div class="p-field p-col-4 p-md-4" style="float: right;">
|
|
||||||
<br />
|
|
||||||
<p:commandButton value="Ändern"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card p-col-12 p-md-6 p-xl-6">
|
|
||||||
<div class="ui-fluid p-formgrid p-grid">
|
|
||||||
<div class="p-field p-col-8 p-md-8">
|
|
||||||
<p:outputLabel for="title" value="Titel" />
|
|
||||||
<p:inputText readonly="true" id="title" value="#{personEditController.title}" />
|
|
||||||
</div>
|
|
||||||
<div class="p-field p-col-4 p-md-4" style="float: right;">
|
|
||||||
<br />
|
|
||||||
<p:commandButton value="Ändern"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-8 p-md-8">
|
|
||||||
<p:outputLabel for="call" value="Anrede" />
|
|
||||||
<p:inputText readonly="true" id="call" value="#{personEditController.call.toString()}" />
|
|
||||||
</div>
|
|
||||||
<div class="p-field p-col-4 p-md-4" style="float: right;">
|
|
||||||
<br />
|
|
||||||
<p:commandButton value="Ändern"/>
|
|
||||||
</div>
|
|
||||||
<div class="p-field p-col-8 p-md-8">
|
|
||||||
<p:outputLabel for="firstname" value="Vorname" />
|
|
||||||
<p:inputText readonly="true" id="firstname" value="#{personEditController.firstname}" />
|
|
||||||
</div>
|
|
||||||
<div class="p-field p-col-4 p-md-4" style="float: right;">
|
|
||||||
<br />
|
|
||||||
<p:commandButton value="Ändern"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-field p-col-8 p-md-8">
|
|
||||||
<p:outputLabel for="lastname" value="Nachname" />
|
|
||||||
<p:inputText readonly="true" id="lastname" value="#{personEditController.lastname}" />
|
|
||||||
</div>
|
|
||||||
<div class="p-field p-col-4 p-md-4" style="float: right;">
|
|
||||||
<br />
|
|
||||||
<p:commandButton value="Ändern"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ui:define>
|
|
||||||
|
|
||||||
<ui:define name="bottom">
|
|
||||||
|
|
||||||
</ui:define>
|
|
||||||
|
|
||||||
</ui:composition>
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>plate.software</groupId>
|
|
||||||
<artifactId>mss-failsafe</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
<artifactId>mssfailsafe.datalayer</artifactId>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
<properties>
|
|
||||||
<maven.compiler.source>11</maven.compiler.source>
|
|
||||||
<maven.compiler.target>11</maven.compiler.target>
|
|
||||||
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
|
||||||
<jakartaee>8.0</jakartaee>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>plate.software</groupId>
|
|
||||||
<artifactId>userdata</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax</groupId>
|
|
||||||
<artifactId>javaee-api</artifactId>
|
|
||||||
<version>${jakartaee}</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.pdfbox</groupId>
|
|
||||||
<artifactId>pdfbox</artifactId>
|
|
||||||
<version>2.0.13</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
|
||||||
<artifactId>log4j-api</artifactId>
|
|
||||||
<version>2.14.1</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
|
||||||
<artifactId>log4j-core</artifactId>
|
|
||||||
<version>2.14.1</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>plate.software</groupId>
|
|
||||||
<artifactId>userManagement</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
<classifier>classes</classifier>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
||||||
-32
@@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.adresses;
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.OneToOne;
|
|
||||||
import model.company.Location;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
public class LocationAddress extends Address {
|
|
||||||
|
|
||||||
@OneToOne
|
|
||||||
private Location location;
|
|
||||||
|
|
||||||
public LocationAddress() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Location getLocation() {
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLocation(Location location) {
|
|
||||||
this.location = location;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.company;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import javax.persistence.CascadeType;
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.EnumType;
|
|
||||||
import javax.persistence.Enumerated;
|
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
import model.AbstractEntity;
|
|
||||||
import model.adresses.CompanyBillingAddress;
|
|
||||||
import model.customer.Customer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
public class Company extends AbstractEntity {
|
|
||||||
|
|
||||||
public static final String FIND_BY_NAME = "Company.findByName";
|
|
||||||
public static final String FIND_BY_STEUERID = "Company.findBySteuerID";
|
|
||||||
public static final String FIND_BY_UMSATZSTEUERID = "Company.findByUmsatzsteuerID";
|
|
||||||
public static final String FIND_BY_CUSTOMER = "Company.findByCustomer";
|
|
||||||
public static final String FIND_BY_ADDRESS = "Company.findByAddress";
|
|
||||||
public static final String FIND_BY_DELIVERYADDRESS = "Company.findByLocation";
|
|
||||||
|
|
||||||
@Column(unique = true, nullable = false)
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
@Column(unique = true, nullable = true)
|
|
||||||
private String steuerNr;
|
|
||||||
|
|
||||||
@Column(unique = true, nullable = true)
|
|
||||||
private String umsatzSteuerID;
|
|
||||||
|
|
||||||
@Column(unique = true, nullable = true)
|
|
||||||
private String kundenNr;
|
|
||||||
|
|
||||||
@Column(unique = false, nullable = true)
|
|
||||||
private String headerInspection;
|
|
||||||
|
|
||||||
@Column(unique = false, nullable = true)
|
|
||||||
private String headerService;
|
|
||||||
|
|
||||||
@Column(unique = false, nullable = false)
|
|
||||||
@Enumerated(EnumType.ORDINAL)
|
|
||||||
private Status status;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL)
|
|
||||||
private Set<CompanyBillingAddress> addresses;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL)
|
|
||||||
private Set<Location> locations;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "company", cascade = {
|
|
||||||
CascadeType.MERGE,
|
|
||||||
CascadeType.REFRESH
|
|
||||||
})
|
|
||||||
private Set<Customer> customers;
|
|
||||||
|
|
||||||
public Company() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSteuerNr() {
|
|
||||||
return steuerNr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSteuerNr(String steuerNr) {
|
|
||||||
this.steuerNr = steuerNr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUmsatzSteuerID() {
|
|
||||||
return umsatzSteuerID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUmsatzSteuerID(String umsatzSteuerID) {
|
|
||||||
this.umsatzSteuerID = umsatzSteuerID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getKundenNr() {
|
|
||||||
return kundenNr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setKundenNr(String kundenNr) {
|
|
||||||
this.kundenNr = kundenNr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHeaderInspection() {
|
|
||||||
return headerInspection;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHeaderInspection(String headerInspection) {
|
|
||||||
this.headerInspection = headerInspection;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHeaderService() {
|
|
||||||
return headerService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHeaderService(String headerService) {
|
|
||||||
this.headerService = headerService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Status getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(Status status) {
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<CompanyBillingAddress> getAddresses() {
|
|
||||||
return addresses;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAddresses(Set<CompanyBillingAddress> addresses) {
|
|
||||||
this.addresses = addresses;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Location> getLocations() {
|
|
||||||
return locations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLocations(Set<Location> locations) {
|
|
||||||
this.locations = locations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Customer> getCustomers() {
|
|
||||||
return customers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCustomers(Set<Customer> customers) {
|
|
||||||
this.customers = customers;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.company;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.ManyToMany;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
import javax.persistence.OneToOne;
|
|
||||||
import model.AbstractEntity;
|
|
||||||
import model.adresses.LocationAddress;
|
|
||||||
import model.customer.Customer;
|
|
||||||
import model.machine.Machine;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
public class Location extends AbstractEntity{
|
|
||||||
|
|
||||||
@ManyToOne
|
|
||||||
private Company company;
|
|
||||||
|
|
||||||
@OneToOne
|
|
||||||
private LocationAddress address;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "location")
|
|
||||||
private Set<Machine> machines;
|
|
||||||
|
|
||||||
@ManyToMany
|
|
||||||
private Set<Customer> contacts;
|
|
||||||
|
|
||||||
public Location() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Company getCompany() {
|
|
||||||
return company;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCompany(Company company) {
|
|
||||||
this.company = company;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocationAddress getAddress() {
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAddress(LocationAddress address) {
|
|
||||||
this.address = address;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Machine> getMachines() {
|
|
||||||
return machines;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMachines(Set<Machine> machines) {
|
|
||||||
this.machines = machines;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Customer> getContacts() {
|
|
||||||
return contacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContacts(Set<Customer> contacts) {
|
|
||||||
this.contacts = contacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.company;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
public enum Status {
|
|
||||||
ACTIVE,
|
|
||||||
INACTIVE;
|
|
||||||
|
|
||||||
private Status() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
switch(this){
|
|
||||||
case ACTIVE:
|
|
||||||
return "aktiv";
|
|
||||||
case INACTIVE:
|
|
||||||
return "inaktiv";
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toLanguageString(Locale locale){
|
|
||||||
if (locale == null ||locale.equals(Locale.GERMAN) || locale.equals(Locale.GERMANY)) {
|
|
||||||
return getGerman();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (locale.equals(Locale.ENGLISH)) {
|
|
||||||
getEnglish();
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getGerman() {
|
|
||||||
return toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getEnglish(){
|
|
||||||
switch(this){
|
|
||||||
case ACTIVE:
|
|
||||||
return "active";
|
|
||||||
case INACTIVE:
|
|
||||||
return "inactive";
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.customer;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.ManyToMany;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import model.person.Person;
|
|
||||||
import model.company.Company;
|
|
||||||
import model.company.Location;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
public class Customer extends Person{
|
|
||||||
|
|
||||||
@ManyToOne
|
|
||||||
private Company company;
|
|
||||||
|
|
||||||
@ManyToMany
|
|
||||||
private Set<Location> locations;
|
|
||||||
|
|
||||||
@Column(nullable = true, length = 210)
|
|
||||||
private String note;
|
|
||||||
|
|
||||||
public Customer() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer(Company company) {
|
|
||||||
this.company = company;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Company getCompany() {
|
|
||||||
return company;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCompany(Company company) {
|
|
||||||
this.company = company;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Location> getLocations() {
|
|
||||||
return locations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLocations(Set<Location> locations) {
|
|
||||||
this.locations = locations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNote() {
|
|
||||||
return note;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNote(String note) {
|
|
||||||
this.note = note;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.files;
|
|
||||||
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.EnumType;
|
|
||||||
import javax.persistence.Enumerated;
|
|
||||||
import javax.persistence.Inheritance;
|
|
||||||
import javax.persistence.InheritanceType;
|
|
||||||
import javax.persistence.Lob;
|
|
||||||
import model.AbstractEntity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
|
|
||||||
public class FileDB extends AbstractEntity{
|
|
||||||
@Column(nullable = false, length = 100)
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
private Mime mime;
|
|
||||||
|
|
||||||
@Lob
|
|
||||||
private byte[] fileData;
|
|
||||||
|
|
||||||
public FileDB() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getFileData() {
|
|
||||||
return fileData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFileData(byte[] fileData) {
|
|
||||||
this.fileData = fileData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Mime getMime() {
|
|
||||||
return mime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMime(Mime mime) {
|
|
||||||
this.mime = mime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.files;
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
import model.ticket.Ticket;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
public class Invoice extends FileDB {
|
|
||||||
@OneToMany
|
|
||||||
private Ticket ticket;
|
|
||||||
|
|
||||||
public Invoice() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Invoice(Ticket ticket) {
|
|
||||||
this.ticket = ticket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Ticket getTicket() {
|
|
||||||
return ticket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTicket(Ticket ticket) {
|
|
||||||
this.ticket = ticket;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.files;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
public enum Mime {
|
|
||||||
AAC(".aac", "AAC audio", "audio/aac"),
|
|
||||||
ABW(".abw", "AbiWord document", "application/x-abiword"),
|
|
||||||
ARC(".arc", "Archive document (multiple files embedded)", "application/x-freearc"),
|
|
||||||
AVI(".avi", "AVI: Audio Video Interleave", "video/x-msvideo"),
|
|
||||||
AZW(".azw", "Amazon Kindle eBook format", "application/vnd.amazon.ebook"),
|
|
||||||
BIN(".bin", "Any kind of binary data", "application/octet-stream"),
|
|
||||||
BMP(".bmp", "Windows OS/2 Bitmap Graphics", "image/bmp"),
|
|
||||||
BZ(".bz", "BZip archive", "application/x-bzip"),
|
|
||||||
BZ2(".bz2", "BZip2 archive", "application/x-bzip2"),
|
|
||||||
CDA(".cda", "CD audio", "application/x-cdf"),
|
|
||||||
CSH(".csh", "C-Shell script", "application/x-csh"),
|
|
||||||
CSS(".css", "Cascading Style Sheets (CSS)", "text/css"),
|
|
||||||
CSV(".csv", "Comma-separated values (CSV", "text/csv"),
|
|
||||||
DOC(".doc", "Microsoft Word", "application/msword"),
|
|
||||||
DOCX(".docx", "Microsoft Word (OpenXML)", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"),
|
|
||||||
EOT(".eot", "MS Embedded OpenType fonts", "application/vnd.ms-fontobject"),
|
|
||||||
EPUB(".epub", "Electronic publication (EPUB)", "application/epub+zip"),
|
|
||||||
GZ(".gz", "GZip Compressed Archive", "application/gzip"),
|
|
||||||
GIF(".gif", "Graphics Interchange Format (GIF)", "image/gif"),
|
|
||||||
HTM(".htm", "HyperText Markup Language (HTML)", "text/html"),
|
|
||||||
HTML(".html", "HyperText Markup Language (HTML)", "text/html"),
|
|
||||||
ICO(".ico", "Icon format", "image/vnd.microsoft.icon"),
|
|
||||||
ICS(".ics", "iCalendar format", "text/calendar"),
|
|
||||||
JAR(".jar", "Java Archive (JAR)", "application/java-archive"),
|
|
||||||
JPG(".jpg", "JPEG images", "image/jpeg"),
|
|
||||||
JPEG(".jpeg", "JPEG images", "image/jpeg"),
|
|
||||||
JS(".js", "JavaScript", "text/javascript"),
|
|
||||||
JSON(".json", "JSON format", "application/json"),
|
|
||||||
JSONLD(".jsonld", "JSON-LD format", "application/ld+json"),
|
|
||||||
MID(".mid", "Musical Instrument Digital Interface (MIDI)", "audio/midi"),
|
|
||||||
MIDI(".midi", "Musical Instrument Digital Interface (MIDI)", "audio/midi"),
|
|
||||||
MJS(".mjs", "JavaScript module", "text/javascript"),
|
|
||||||
MP3(".mp3", "MP3 audio", "audio/mpeg"),
|
|
||||||
MP4(".mp4", "MP4 video", "video/mp4"),
|
|
||||||
MPEG(".mpeg", "MPEG Video", "video/mpeg"),
|
|
||||||
MPKG(".mpkg", "Apple Installer Package", "application/vnd.apple.installer+xml"),
|
|
||||||
ODP(".odp", "OpenDocument presentation document", "application/vnd.oasis.opendocument.presentation"),
|
|
||||||
ODS(".ods", "OpenDocument spreadsheet document", "application/vnd.oasis.opendocument.spreadsheet"),
|
|
||||||
ODT(".odt", "OpenDocument text document", "application/vnd.oasis.opendocument.text"),
|
|
||||||
OGA(".oga", "OGG audio", "audio/ogg"),
|
|
||||||
OGV(".ogv", "OGG video", "video/ogg"),
|
|
||||||
OGX(".ogx", "OGG", "application/ogg"),
|
|
||||||
OPUUS(".opus", "Opus audio", "audio/opus"),
|
|
||||||
OTF(".otf", "OpenType font", "font/otf"),
|
|
||||||
PNG(".png", "Portable Network Graphics", "image/png"),
|
|
||||||
PDF(".pdf", "Adobe Portable Document Format (PDF)", "application/pdf"),
|
|
||||||
PHP(".php", "Hypertext Preprocessor (Personal Home Page)", "application/x-httpd-php"),
|
|
||||||
PPT(".ppt", "Microsoft PowerPoint", "application/vnd.ms-powerpoint"),
|
|
||||||
PPTX(".pptx", "Microsoft PowerPoint (OpenXML)", "application/vnd.openxmlformats-officedocument.presentationml.presentation"),
|
|
||||||
RAR(".rar", "RAR archive", "application/vnd.rar"),
|
|
||||||
RTF(".rtf", "Rich Text Format (RTF)", "application/rtf"),
|
|
||||||
SH(".sh", "Bourne shell script", "application/x-sh"),
|
|
||||||
SVG(".svg", "Scalable Vector Graphics (SVG)", "image/svg+xml"),
|
|
||||||
SWF(".swf", "Small web format (SWF) or Adobe Flash document", "application/x-shockwave-flash"),
|
|
||||||
TAR(".tar", "Tape Archive (TAR)", "application/x-tar"),
|
|
||||||
TIF(".tif", "Tagged Image File Format (TIFF)", "image/tiff"),
|
|
||||||
TIFF(".tiff", "Tagged Image File Format (TIFF)", "image/tiff"),
|
|
||||||
TS(".ts", "MPEG transport stream", "video/mp2t"),
|
|
||||||
TTF(".ttf", "TrueType Font", "font/ttf"),
|
|
||||||
TXT(".txt", "Text, (generally ASCII or ISO 8859-n)", "text/plain"),
|
|
||||||
VSD(".vsd", "Microsoft Visio", "application/vnd.visio"),
|
|
||||||
WAV(".wav", "Waveform Audio Format", "audio/wav"),
|
|
||||||
WEBA(".weba", "WEBM audio", "audio/webm"),
|
|
||||||
WEBM(".webm", "WEBM video", "video/webm"),
|
|
||||||
WEBP(".webp", "WEBP image", "image/webp"),
|
|
||||||
WOFF(".woff", "Web Open Font Format (WOFF)", "font/woff"),
|
|
||||||
WOFF2(".woff2", "Web Open Font Format (WOFF)", "font/woff2"),
|
|
||||||
XHTML(".xhtml", "XHTML", "application/xhtml+xml"),
|
|
||||||
XLS(".xls", "Microsoft Excel", "application/vnd.ms-excel"),
|
|
||||||
XLSX(".xlsx", "Microsoft Excel (OpenXML)", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"),
|
|
||||||
XML(".xml", "XML", "application/xml"),
|
|
||||||
XUL(".xul", "XUL", "application/vnd.mozilla.xul+xml"),
|
|
||||||
ZIP(".zip", "ZIP archive", "application/zip"),
|
|
||||||
GP3V(".3gp", "3GPP audio/video container", "video/3gpp"),
|
|
||||||
GP3A(".3gp", "3GPP audio/video container", "audio/3gpp"),
|
|
||||||
G23V(".3g2", "3GPP2 audio/video container", "video/3gpp2"),
|
|
||||||
G23A(".3g2", "3GPP2 audio/video container", "audio/3gpp2"),
|
|
||||||
Z7(".7z", "7-zip archive", "application/x-7z-compressed");
|
|
||||||
|
|
||||||
private final String extension;
|
|
||||||
private final String kindOfDocument;
|
|
||||||
private final String mimeType;
|
|
||||||
|
|
||||||
private Mime(String extension, String kindOfDocument, String mimeType) {
|
|
||||||
this.extension = extension;
|
|
||||||
this.kindOfDocument = kindOfDocument;
|
|
||||||
this.mimeType = mimeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getExtension() {
|
|
||||||
return extension;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getKindOfDocument() {
|
|
||||||
return kindOfDocument;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMimeType() {
|
|
||||||
return mimeType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.files;
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
import model.ticket.Ticket;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
public class Report extends FileDB{
|
|
||||||
|
|
||||||
@OneToMany
|
|
||||||
private Ticket ticket;
|
|
||||||
|
|
||||||
public Report() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Ticket getTicket() {
|
|
||||||
return ticket;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTicket(Ticket ticket) {
|
|
||||||
this.ticket = ticket;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.machine;
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import model.AbstractEntity;
|
|
||||||
import model.company.Location;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
public class Machine extends AbstractEntity {
|
|
||||||
|
|
||||||
@ManyToOne
|
|
||||||
private Location location;
|
|
||||||
|
|
||||||
public Machine() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Location getLocation() {
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLocation(Location location) {
|
|
||||||
this.location = location;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-32
@@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.ticket;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
public enum FilenameGeneration {
|
|
||||||
INSPEKTIONNR,
|
|
||||||
MASCHINEDESCRIPTION,
|
|
||||||
LOCATION;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
switch(this){
|
|
||||||
case INSPEKTIONNR:
|
|
||||||
return "inspektionnr";
|
|
||||||
case MASCHINEDESCRIPTION:
|
|
||||||
return "maschinedescription";
|
|
||||||
case LOCATION:
|
|
||||||
return "location";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "nothing";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,192 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.ticket;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.persistence.CascadeType;
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.EnumType;
|
|
||||||
import javax.persistence.Enumerated;
|
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
import javax.persistence.OneToOne;
|
|
||||||
import model.AbstractEntity;
|
|
||||||
import model.adresses.CompanyBillingAddress;
|
|
||||||
import model.company.Company;
|
|
||||||
import model.company.Location;
|
|
||||||
import model.files.Invoice;
|
|
||||||
import model.files.Report;
|
|
||||||
import model.person.Person;
|
|
||||||
import model.person.Token;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
public class Ticket extends AbstractEntity{
|
|
||||||
|
|
||||||
@Column(nullable = false)
|
|
||||||
@OneToOne
|
|
||||||
private Company company;
|
|
||||||
|
|
||||||
@OneToOne
|
|
||||||
private CompanyBillingAddress billingAddress;
|
|
||||||
|
|
||||||
@OneToMany
|
|
||||||
private List<Location> locations;
|
|
||||||
|
|
||||||
@Column(nullable = false)
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
private Status status;
|
|
||||||
|
|
||||||
@Column(nullable = false)
|
|
||||||
@OneToOne
|
|
||||||
private Person creator;
|
|
||||||
|
|
||||||
@Column(nullable = true)
|
|
||||||
@OneToOne
|
|
||||||
private Person owner;
|
|
||||||
|
|
||||||
private LocalDateTime startDate;
|
|
||||||
|
|
||||||
private LocalDateTime endDate;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "ticket", cascade = CascadeType.ALL)
|
|
||||||
private List<Comment> comments;
|
|
||||||
|
|
||||||
private boolean payed;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "ticket", orphanRemoval = true, cascade = CascadeType.ALL)
|
|
||||||
private List<Token> tokens;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "ticket", cascade = {CascadeType.PERSIST, CascadeType.PERSIST})
|
|
||||||
private List<Report> reports;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "ticket", cascade = {CascadeType.PERSIST, CascadeType.PERSIST})
|
|
||||||
private List<Invoice> invoices;
|
|
||||||
|
|
||||||
@Column(nullable = false, length = 200)
|
|
||||||
private String filenameGeneration;
|
|
||||||
|
|
||||||
public Ticket() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public CompanyBillingAddress getBillingAddress() {
|
|
||||||
return billingAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBillingAddress(CompanyBillingAddress billingAddress) {
|
|
||||||
this.billingAddress = billingAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getStartDate() {
|
|
||||||
return startDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStartDate(LocalDateTime startDate) {
|
|
||||||
this.startDate = startDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getEndDate() {
|
|
||||||
return endDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEndDate(LocalDateTime endDate) {
|
|
||||||
this.endDate = endDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Company getCompany() {
|
|
||||||
return company;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCompany(Company company) {
|
|
||||||
this.company = company;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Location> getLocations() {
|
|
||||||
return locations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLocations(List<Location> locations) {
|
|
||||||
this.locations = locations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Status getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(Status status) {
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Person getCreator() {
|
|
||||||
return creator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCreator(Person creator) {
|
|
||||||
this.creator = creator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Person getOwner() {
|
|
||||||
return owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOwner(Person owner) {
|
|
||||||
this.owner = owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Comment> getComments() {
|
|
||||||
return comments;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setComments(List<Comment> comments) {
|
|
||||||
this.comments = comments;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isPayed() {
|
|
||||||
return payed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPayed(boolean payed) {
|
|
||||||
this.payed = payed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Token> getTokens() {
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTokens(List<Token> tokens) {
|
|
||||||
this.tokens = tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Report> getReports() {
|
|
||||||
return reports;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReports(List<Report> reports) {
|
|
||||||
this.reports = reports;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Invoice> getInvoices() {
|
|
||||||
return invoices;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInvoices(List<Invoice> invoices) {
|
|
||||||
this.invoices = invoices;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFilenameGeneration() {
|
|
||||||
return filenameGeneration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFilenameGeneration(String filenameGeneration) {
|
|
||||||
this.filenameGeneration = filenameGeneration;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.ticket;
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.OneToOne;
|
|
||||||
import model.AbstractEntity;
|
|
||||||
import model.company.Location;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
public class TicketLocation extends AbstractEntity{
|
|
||||||
@ManyToOne
|
|
||||||
private Ticket ticket;
|
|
||||||
|
|
||||||
@OneToOne
|
|
||||||
private Location location;
|
|
||||||
|
|
||||||
|
|
||||||
private List<TicketMachine> machines;
|
|
||||||
|
|
||||||
|
|
||||||
public TicketLocation() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package model.ticket;
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import model.AbstractEntity;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.OneToOne;
|
|
||||||
import model.machine.Machine;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author patri
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
public class TicketMachine extends AbstractEntity{
|
|
||||||
@ManyToOne
|
|
||||||
private Ticket ticket;
|
|
||||||
|
|
||||||
@OneToOne
|
|
||||||
private Machine machine;
|
|
||||||
|
|
||||||
public TicketMachine() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
|
|
||||||
<persistence-unit name="pu_datalayer" transaction-type="JTA">
|
|
||||||
<jta-data-source>java:/mss-failsave</jta-data-source>
|
|
||||||
<class>model.company.Location</class>
|
|
||||||
<class>model.adresses.LocationAdress</class>
|
|
||||||
<class>model.machine.Machine</class>
|
|
||||||
<properties>
|
|
||||||
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
|
|
||||||
</properties>
|
|
||||||
</persistence-unit>
|
|
||||||
</persistence>
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
|
|
||||||
<persistence-unit name="pu_datalayer" transaction-type="JTA">
|
|
||||||
<jta-data-source>java:/mss-failsave</jta-data-source>
|
|
||||||
<class>model.company.Location</class>
|
|
||||||
<class>model.adresses.LocationAdress</class>
|
|
||||||
<class>model.machine.Machine</class>
|
|
||||||
<properties>
|
|
||||||
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
|
|
||||||
</properties>
|
|
||||||
</persistence-unit>
|
|
||||||
</persistence>
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project-shared-configuration>
|
|
||||||
<!--
|
|
||||||
This file contains additional configuration written by modules in the NetBeans IDE.
|
|
||||||
The configuration is intended to be shared among all the users of project and
|
|
||||||
therefore it is assumed to be part of version control checkout.
|
|
||||||
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
|
||||||
-->
|
|
||||||
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
|
||||||
<!--
|
|
||||||
Properties that influence various parts of the IDE, especially code formatting and the like.
|
|
||||||
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
|
|
||||||
That way multiple projects can share the same settings (useful for formatting rules for example).
|
|
||||||
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
|
||||||
-->
|
|
||||||
<org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_j2eeVersion>1.8-web</org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_j2eeVersion>
|
|
||||||
<org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_deploy_2e_server>WildFly</org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_deploy_2e_server>
|
|
||||||
<org-netbeans-modules-maven-jaxws.rest_2e_config_2e_type>ide</org-netbeans-modules-maven-jaxws.rest_2e_config_2e_type>
|
|
||||||
</properties>
|
|
||||||
</project-shared-configuration>
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<artifactId>mss-failsafe</artifactId>
|
|
||||||
<groupId>plate.software</groupId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
<groupId>plate.software</groupId>
|
|
||||||
<artifactId>mssfailsafeWeblayer</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
<packaging>war</packaging>
|
|
||||||
<name>mssfailsafeWeblayer-1.0-SNAPSHOT</name>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
|
||||||
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
|
||||||
<jakartaee>8.0</jakartaee>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>plate.software</groupId>
|
|
||||||
<artifactId>userdata</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax</groupId>
|
|
||||||
<artifactId>javaee-api</artifactId>
|
|
||||||
<version>${jakartaee}</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.pdfbox</groupId>
|
|
||||||
<artifactId>pdfbox</artifactId>
|
|
||||||
<version>2.0.13</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.glassfish.soteria</groupId>
|
|
||||||
<artifactId>javax.security.enterprise</artifactId>
|
|
||||||
<version>1.0</version> <!-- Stable version -->
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.omnifaces</groupId>
|
|
||||||
<artifactId>omnifaces</artifactId>
|
|
||||||
<version>3.11.1</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax</groupId>
|
|
||||||
<artifactId>javaee-web-api</artifactId>
|
|
||||||
<version>8.0</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.glassfish</groupId>
|
|
||||||
<artifactId>javax.faces</artifactId>
|
|
||||||
<version>2.3.0</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
|
||||||
<artifactId>log4j-api</artifactId>
|
|
||||||
<version>2.14.1</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
|
||||||
<artifactId>log4j-core</artifactId>
|
|
||||||
<version>2.14.1</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.primefaces</groupId>
|
|
||||||
<artifactId>primefaces</artifactId>
|
|
||||||
<version>10.0.0</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>3.1</version>
|
|
||||||
<configuration>
|
|
||||||
<source>1.8</source>
|
|
||||||
<target>1.8</target>
|
|
||||||
<compilerArguments>
|
|
||||||
<endorseddirs>${endorsed.dir}</endorseddirs>
|
|
||||||
</compilerArguments>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
|
||||||
<version>2.3</version>
|
|
||||||
<configuration>
|
|
||||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
|
||||||
<version>2.6</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>validate</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>copy</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<outputDirectory>${endorsed.dir}</outputDirectory>
|
|
||||||
<silent>true</silent>
|
|
||||||
<artifactItems>
|
|
||||||
<artifactItem>
|
|
||||||
<groupId>javax</groupId>
|
|
||||||
<artifactId>javaee-api</artifactId>
|
|
||||||
<version>${jakartaee}</version>
|
|
||||||
<type>jar</type>
|
|
||||||
</artifactItem>
|
|
||||||
</artifactItems>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</project>
|
|
||||||
-13
@@ -1,13 +0,0 @@
|
|||||||
package plate.software.mssfailsafeweblayer;
|
|
||||||
|
|
||||||
import javax.ws.rs.ApplicationPath;
|
|
||||||
import javax.ws.rs.core.Application;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures JAX-RS for the application.
|
|
||||||
* @author Juneau
|
|
||||||
*/
|
|
||||||
@ApplicationPath("resources")
|
|
||||||
public class JAXRSConfiguration extends Application {
|
|
||||||
|
|
||||||
}
|
|
||||||
-20
@@ -1,20 +0,0 @@
|
|||||||
package plate.software.mssfailsafeweblayer.resources;
|
|
||||||
|
|
||||||
import javax.ws.rs.GET;
|
|
||||||
import javax.ws.rs.Path;
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author
|
|
||||||
*/
|
|
||||||
@Path("javaee8")
|
|
||||||
public class JavaEE8Resource {
|
|
||||||
|
|
||||||
@GET
|
|
||||||
public Response ping(){
|
|
||||||
return Response
|
|
||||||
.ok("ping")
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<persistence version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
|
|
||||||
<!-- Define Persistence Unit -->
|
|
||||||
<persistence-unit name="my_persistence_unit">
|
|
||||||
|
|
||||||
</persistence-unit>
|
|
||||||
</persistence>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<jboss-web xmlns="http://www.jboss.com/xml/ns/javaee"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-web_10_0.xsd"
|
|
||||||
version="10.0">
|
|
||||||
<security-domain>mss-failsafe</security-domain>
|
|
||||||
</jboss-web>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<jboss-web version="10.0" xmlns="http://www.jboss.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-web_10_0.xsd">
|
|
||||||
<context-root>/mssfailsafeWeblayer-1.0-SNAPSHOT</context-root>
|
|
||||||
<security-domain>jaspitest</security-domain>
|
|
||||||
</jboss-web>
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<web-app version="4.0" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">
|
|
||||||
<welcome-file-list>
|
|
||||||
<welcome-file>/index.xhtml</welcome-file>
|
|
||||||
</welcome-file-list>
|
|
||||||
<error-page>
|
|
||||||
<!-- Missing login -->
|
|
||||||
<error-code>401</error-code>
|
|
||||||
<location>/error.xhtml</location>
|
|
||||||
</error-page>
|
|
||||||
<error-page>
|
|
||||||
<!-- Forbidden directory listing -->
|
|
||||||
<error-code>403</error-code>
|
|
||||||
<location>/error.xhtml</location>
|
|
||||||
</error-page>
|
|
||||||
<security-constraint>
|
|
||||||
<web-resource-collection>
|
|
||||||
<web-resource-name>authorise</web-resource-name>
|
|
||||||
<url-pattern>/user/*</url-pattern>
|
|
||||||
<http-method>GET</http-method>
|
|
||||||
<http-method>POST</http-method>
|
|
||||||
<http-method>TRACE</http-method>
|
|
||||||
<http-method>HEAD</http-method>
|
|
||||||
<http-method>DELETE</http-method>
|
|
||||||
<http-method>CONNECT</http-method>
|
|
||||||
<http-method>OPTIONS</http-method>
|
|
||||||
<http-method>PUT</http-method>
|
|
||||||
</web-resource-collection>
|
|
||||||
<auth-constraint>
|
|
||||||
<role-name>ADMIN</role-name>
|
|
||||||
<role-name>USER</role-name>
|
|
||||||
</auth-constraint>
|
|
||||||
<!--
|
|
||||||
<user-data-constraint>
|
|
||||||
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
|
||||||
</user-data-constraint>-->
|
|
||||||
</security-constraint>
|
|
||||||
<security-constraint>
|
|
||||||
<web-resource-collection>
|
|
||||||
<web-resource-name>authorise</web-resource-name>
|
|
||||||
<url-pattern>/admin/*</url-pattern>
|
|
||||||
<http-method>GET</http-method>
|
|
||||||
<http-method>POST</http-method>
|
|
||||||
<http-method>TRACE</http-method>
|
|
||||||
<http-method>HEAD</http-method>
|
|
||||||
<http-method>DELETE</http-method>
|
|
||||||
<http-method>CONNECT</http-method>
|
|
||||||
<http-method>OPTIONS</http-method>
|
|
||||||
<http-method>PUT</http-method>
|
|
||||||
</web-resource-collection>
|
|
||||||
<auth-constraint>
|
|
||||||
<role-name>ADMIN</role-name>
|
|
||||||
</auth-constraint>
|
|
||||||
<!--<user-data-constraint>
|
|
||||||
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
|
||||||
</user-data-constraint>-->
|
|
||||||
</security-constraint>
|
|
||||||
<security-role>
|
|
||||||
<description>Normal User which got invited</description>
|
|
||||||
<role-name>USER</role-name>
|
|
||||||
</security-role>
|
|
||||||
<security-role>
|
|
||||||
<description>Admin user who can change entries, invite new domains and more..</description>
|
|
||||||
<role-name>ADMIN</role-name>
|
|
||||||
</security-role>
|
|
||||||
<context-param>
|
|
||||||
<param-name>javax.faces.PROJECT_STAGE</param-name>
|
|
||||||
<param-value>Development</param-value>
|
|
||||||
</context-param>
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>Faces Servlet</servlet-name>
|
|
||||||
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
|
|
||||||
<load-on-startup>1</load-on-startup>
|
|
||||||
</servlet>
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>Faces Servlet</servlet-name>
|
|
||||||
<url-pattern>*.xhtml</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
<session-config>
|
|
||||||
<session-timeout>
|
|
||||||
30
|
|
||||||
</session-timeout>
|
|
||||||
<cookie-config>
|
|
||||||
<http-only>true</http-only>
|
|
||||||
<!-- Prevent client side scripting from accessing/manipulating session cookie. -->
|
|
||||||
</cookie-config>
|
|
||||||
<tracking-mode>COOKIE</tracking-mode>
|
|
||||||
<!-- This disables URL rewriting. -->
|
|
||||||
</session-config>
|
|
||||||
</web-app>
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
|
||||||
xmlns:h="http://java.sun.com/jsf/html"
|
|
||||||
xmlns:f="http://java.sun.com/jsf/core"
|
|
||||||
xmlns:p="http://primefaces.org/ui">
|
|
||||||
|
|
||||||
<h:head>
|
|
||||||
<title>Willkommen #{personController.activeUser.call.toString()} #{personController.activeUser.lastname}</title>
|
|
||||||
</h:head>
|
|
||||||
|
|
||||||
<h:body>
|
|
||||||
<p>Willkommen #{personController.activeUser.call.toString()} #{personController.activeUser.lastname}</p>
|
|
||||||
<p:spinner />
|
|
||||||
</h:body>
|
|
||||||
</html>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
|
||||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
|
||||||
xmlns:p="http://primefaces.org/ui"
|
|
||||||
xmlns:f="http://xmlns.jcp.org/jsf/core">
|
|
||||||
<h:head>
|
|
||||||
<title>Error Testpage</title>
|
|
||||||
</h:head>
|
|
||||||
<h:body>
|
|
||||||
|
|
||||||
<p>Error!</p>
|
|
||||||
|
|
||||||
</h:body>
|
|
||||||
</html>
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
|
||||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
|
||||||
xmlns:p="http://primefaces.org/ui"
|
|
||||||
xmlns:f="http://xmlns.jcp.org/jsf/core">
|
|
||||||
<h:head>
|
|
||||||
<title>Login Testpage</title>
|
|
||||||
</h:head>
|
|
||||||
<h:body>
|
|
||||||
|
|
||||||
<h:form id="login">
|
|
||||||
<p:panel header="Login MSS-Failsafe " style="width: 450px; margin: auto; margin-top: 100px;">
|
|
||||||
<p:messages id="messages" showDetail="true" closable="true">
|
|
||||||
<p:autoUpdate />
|
|
||||||
</p:messages>
|
|
||||||
<h:panelGrid columns="2" cellpadding="5">
|
|
||||||
<p:outputLabel for="username" value="Email" />
|
|
||||||
<p:inputText id="username" value="#{personController.username}" required="true" label="username" />
|
|
||||||
|
|
||||||
<p:outputLabel for="password" value="Password:" />
|
|
||||||
<p:password id="password" value="#{personController.password}" required="true" label="password" />
|
|
||||||
|
|
||||||
<p:outputLabel for="rememberMe" value="Remember Me:" />
|
|
||||||
<p:selectBooleanCheckbox id="rememberMe" value="#{personController.rememberMe}" />
|
|
||||||
|
|
||||||
<f:facet name="footer">
|
|
||||||
<p:commandButton value="Login" action="#{personController.submit()}" ajax="false"/>
|
|
||||||
</f:facet>
|
|
||||||
</h:panelGrid>
|
|
||||||
</p:panel>
|
|
||||||
</h:form>
|
|
||||||
|
|
||||||
</h:body>
|
|
||||||
</html>
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
|
||||||
xmlns:h="http://java.sun.com/jsf/html"
|
|
||||||
xmlns:f="http://java.sun.com/jsf/core"
|
|
||||||
xmlns:p="http://primefaces.org/ui">
|
|
||||||
|
|
||||||
<h:head>
|
|
||||||
<title>Willkommen #{personController.activeUser.call.toString()} #{personController.activeUser.lastname}</title>
|
|
||||||
</h:head>
|
|
||||||
|
|
||||||
<h:body>
|
|
||||||
<p>Willkommen #{personController.activeUser.call.toString()} #{personController.activeUser.lastname}</p>
|
|
||||||
<p:spinner />
|
|
||||||
</h:body>
|
|
||||||
</html>
|
|
||||||
Regular → Executable
+9
-1
@@ -6,6 +6,7 @@ The configuration is intended to be shared among all the users of project and
|
|||||||
therefore it is assumed to be part of version control checkout.
|
therefore it is assumed to be part of version control checkout.
|
||||||
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
||||||
-->
|
-->
|
||||||
|
<libraries xmlns="http://www.netbeans.org/ns/cdnjs-libraries/1"/>
|
||||||
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
||||||
<!--
|
<!--
|
||||||
Properties that influence various parts of the IDE, especially code formatting and the like.
|
Properties that influence various parts of the IDE, especially code formatting and the like.
|
||||||
@@ -13,9 +14,16 @@ You can copy and paste the single properties, into the pom.xml file and the IDE
|
|||||||
That way multiple projects can share the same settings (useful for formatting rules for example).
|
That way multiple projects can share the same settings (useful for formatting rules for example).
|
||||||
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
||||||
-->
|
-->
|
||||||
<org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_j2eeVersion>1.8-web</org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_j2eeVersion>
|
<org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_j2eeVersion>8.0-web</org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_j2eeVersion>
|
||||||
<org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_deploy_2e_server>WildFly</org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_deploy_2e_server>
|
<org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_deploy_2e_server>WildFly</org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_deploy_2e_server>
|
||||||
<org-netbeans-modules-maven-jaxws.rest_2e_config_2e_type>ide</org-netbeans-modules-maven-jaxws.rest_2e_config_2e_type>
|
<org-netbeans-modules-maven-jaxws.rest_2e_config_2e_type>ide</org-netbeans-modules-maven-jaxws.rest_2e_config_2e_type>
|
||||||
<org-netbeans-modules-projectapi.jsf_2e_language>Facelets</org-netbeans-modules-projectapi.jsf_2e_language>
|
<org-netbeans-modules-projectapi.jsf_2e_language>Facelets</org-netbeans-modules-projectapi.jsf_2e_language>
|
||||||
|
<org-netbeans-modules-css-prep.less_2e_mappings>/less:/css</org-netbeans-modules-css-prep.less_2e_mappings>
|
||||||
|
<org-netbeans-modules-css-prep.less_2e_enabled>false</org-netbeans-modules-css-prep.less_2e_enabled>
|
||||||
|
<org-netbeans-modules-css-prep.sass_2e_enabled>false</org-netbeans-modules-css-prep.sass_2e_enabled>
|
||||||
|
<org-netbeans-modules-css-prep.sass_2e_compiler_2e_options/>
|
||||||
|
<org-netbeans-modules-css-prep.less_2e_compiler_2e_options/>
|
||||||
|
<org-netbeans-modules-css-prep.sass_2e_mappings>/scss:/css</org-netbeans-modules-css-prep.sass_2e_mappings>
|
||||||
|
<org-netbeans-modules-web-clientproject-api.js_2e_libs_2e_folder>js/libs</org-netbeans-modules-web-clientproject-api.js_2e_libs_2e_folder>
|
||||||
</properties>
|
</properties>
|
||||||
</project-shared-configuration>
|
</project-shared-configuration>
|
||||||
Regular → Executable
+176
-61
@@ -1,78 +1,193 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<groupId>plate.software</groupId>
|
<groupId>plate.software</groupId>
|
||||||
|
<artifactId>mss</artifactId>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<artifactId>mss-failsafe</artifactId>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
<name>mss-1.0-SNAPSHOT</name>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<packaging>pom</packaging>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
|
||||||
|
|
||||||
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||||
|
<jakartaee>8.0</jakartaee>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax</groupId>
|
||||||
|
<artifactId>javaee-api</artifactId>
|
||||||
|
<version>${jakartaee}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate</groupId>
|
||||||
|
<artifactId>hibernate-core</artifactId>
|
||||||
|
<version>5.6.5.Final</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.poi</groupId>
|
||||||
|
<artifactId>poi</artifactId>
|
||||||
|
<version>5.2.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>itextpdf</artifactId>
|
||||||
|
<version>5.5.13</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>kernel</artifactId>
|
||||||
|
<version>7.2.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>io</artifactId>
|
||||||
|
<version>7.2.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>layout</artifactId>
|
||||||
|
<version>7.2.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>forms</artifactId>
|
||||||
|
<version>7.2.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>pdfa</artifactId>
|
||||||
|
<version>7.2.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>sign</artifactId>
|
||||||
|
<version>7.2.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>barcodes</artifactId>
|
||||||
|
<version>7.2.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>font-asian</artifactId>
|
||||||
|
<version>7.2.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>hyph</artifactId>
|
||||||
|
<version>7.2.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.soteria</groupId>
|
||||||
|
<artifactId>javax.security.enterprise</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</dependency>-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.omnifaces</groupId>
|
||||||
|
<artifactId>omnifaces</artifactId>
|
||||||
|
<version>3.11.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<modules>
|
<dependency>
|
||||||
|
<groupId>javax</groupId>
|
||||||
|
<artifactId>javaee-web-api</artifactId>
|
||||||
|
<version>8.0</version>
|
||||||
<module>mssfailsafe.datalayer</module>
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
<module>userdata</module>
|
<groupId>org.glassfish</groupId>
|
||||||
|
<artifactId>javax.faces</artifactId>
|
||||||
|
<version>2.3.0</version>
|
||||||
<module>mssfailsafeWeblayer</module>
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
<module>mss</module>
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
<artifactId>log4j-api</artifactId>
|
||||||
</modules>
|
<version>2.17.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
<artifactId>log4j-core</artifactId>
|
||||||
<name>mss-failsafe</name>
|
<version>2.17.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.primefaces</groupId>
|
||||||
|
<artifactId>primefaces</artifactId>
|
||||||
|
<version>11.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.webjars.npm</groupId>
|
||||||
|
<artifactId>primeflex</artifactId>
|
||||||
|
<version>2.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>11</source>
|
||||||
|
<target>11</target>
|
||||||
|
<compilerArguments>
|
||||||
|
<endorseddirs>${endorsed.dir}</endorseddirs>
|
||||||
|
</compilerArguments>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
|
<version>3.3.2</version>
|
||||||
|
<configuration>
|
||||||
|
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<version>2.6</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>validate</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${endorsed.dir}</outputDirectory>
|
||||||
|
<silent>true</silent>
|
||||||
|
<artifactItems>
|
||||||
|
<artifactItem>
|
||||||
|
<groupId>javax</groupId>
|
||||||
|
<artifactId>javaee-api</artifactId>
|
||||||
|
<version>${jakartaee}</version>
|
||||||
|
<type>jar</type>
|
||||||
|
</artifactItem>
|
||||||
|
</artifactItems>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -0,0 +1,197 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package business;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
import model.AbstractEntity;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.hibernate.Hibernate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Patrick
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
|
public abstract class AbstractManager<T extends AbstractEntity> {
|
||||||
|
|
||||||
|
protected final Logger LOGGER = LogManager.getLogger(this.getClass());
|
||||||
|
|
||||||
|
private final Class<T> entityClass;
|
||||||
|
|
||||||
|
public AbstractManager(Class<T> entityClass) {
|
||||||
|
this.entityClass = entityClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract EntityManager getEntityManager();
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public boolean save(T entity) {
|
||||||
|
if (entity == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity.getId() != null) {
|
||||||
|
try {
|
||||||
|
edit(entity);
|
||||||
|
getEntityManager().flush();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
create(entity);
|
||||||
|
getEntityManager().flush();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public boolean saveAll(Collection<T> entities) {
|
||||||
|
if (entities == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entities.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (T entity : entities) {
|
||||||
|
if (entity.getId() != null) {
|
||||||
|
try {
|
||||||
|
edit(entity);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
create(entity);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getEntityManager().flush();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void create(T entity) {
|
||||||
|
try {
|
||||||
|
getEntityManager().persist(entity);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void edit(T entity) {
|
||||||
|
getEntityManager().merge(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T refresh(T entity) {
|
||||||
|
if (entity == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (entity.getId() == null) {
|
||||||
|
save(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
entity = getEntityManager().merge(entity);
|
||||||
|
Hibernate.initialize(entity);
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean removeAllIn(Collection<T> col) {
|
||||||
|
if (col == null || col.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
boolean success = true;
|
||||||
|
|
||||||
|
for (T entity : col) {
|
||||||
|
if (!remove(entity)) {
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error(e);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean remove(T entity) {
|
||||||
|
if (entity == null || entity.getId() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Hibernate.initialize(entity);
|
||||||
|
entity = find(entity.getId());
|
||||||
|
|
||||||
|
getEntityManager().remove(entity);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
String queryString = "DELETE FROM " + entityClass.getSimpleName() + " e WHERE e.id = :id";
|
||||||
|
Query query = getEntityManager().createQuery(queryString);
|
||||||
|
query.setParameter("id", entity.getId());
|
||||||
|
|
||||||
|
try {
|
||||||
|
query.executeUpdate();
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error(e);
|
||||||
|
return false;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public T find(Object id) {
|
||||||
|
return getEntityManager().find(entityClass, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> findAll() {
|
||||||
|
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
|
||||||
|
cq.select(cq.from(entityClass));
|
||||||
|
return getEntityManager().createQuery(cq).getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> findRange(int[] range) {
|
||||||
|
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
|
||||||
|
cq.select(cq.from(entityClass));
|
||||||
|
javax.persistence.Query q = getEntityManager().createQuery(cq);
|
||||||
|
q.setMaxResults(range[1] - range[0] + 1);
|
||||||
|
q.setFirstResult(range[0]);
|
||||||
|
return q.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int count() {
|
||||||
|
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
|
||||||
|
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
|
||||||
|
cq.select(getEntityManager().getCriteriaBuilder().count(rt));
|
||||||
|
javax.persistence.Query q = getEntityManager().createQuery(cq);
|
||||||
|
return ((Long) q.getSingleResult()).intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package business;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.enterprise.context.SessionScoped;
|
||||||
|
import javax.faces.context.FacesContext;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.primefaces.model.DefaultStreamedContent;
|
||||||
|
import org.primefaces.model.StreamedContent;
|
||||||
|
|
||||||
|
@Named
|
||||||
|
@SessionScoped
|
||||||
|
public class BackupFileManager implements Serializable {
|
||||||
|
|
||||||
|
private static final Logger logger = LogManager.getLogger(BackupFileManager.class);
|
||||||
|
private static final String BACKUP_DIRECTORY = "/h2DB/";
|
||||||
|
private List<File> backupFiles;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
loadBackupFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadBackupFiles() {
|
||||||
|
File directory = new File(BACKUP_DIRECTORY);
|
||||||
|
if (directory.exists() && directory.isDirectory()) {
|
||||||
|
File[] files = directory.listFiles((dir, name) -> name.startsWith("h2-mss-database-backup_") && name.endsWith(".zip"));
|
||||||
|
if (files != null) {
|
||||||
|
backupFiles = Arrays.asList(files);
|
||||||
|
// Sortiere Dateien nach Änderungsdatum (neueste zuerst)
|
||||||
|
Collections.sort(backupFiles, (f1, f2) -> Long.compare(f2.lastModified(), f1.lastModified()));
|
||||||
|
} else {
|
||||||
|
backupFiles = Collections.emptyList();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
backupFiles = Collections.emptyList();
|
||||||
|
logger.warn("Backup-Verzeichnis existiert nicht: " + BACKUP_DIRECTORY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<File> getBackupFiles() {
|
||||||
|
return backupFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StreamedContent downloadFile(String fileName) {
|
||||||
|
try {
|
||||||
|
File file = new File(BACKUP_DIRECTORY + fileName);
|
||||||
|
return DefaultStreamedContent.builder()
|
||||||
|
.name(fileName)
|
||||||
|
.contentType("application/zip")
|
||||||
|
.stream(() -> {
|
||||||
|
try {
|
||||||
|
return new FileInputStream(file);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("Fehler beim Lesen der Backup-Datei: " + fileName, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Fehler beim Vorbereiten des Downloads für: " + fileName, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package business;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Lob;
|
||||||
|
import javax.persistence.NoResultException;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
import javax.persistence.Query;
|
||||||
|
import javax.persistence.metamodel.Metamodel;
|
||||||
|
import javax.persistence.metamodel.ManagedType;
|
||||||
|
import javax.persistence.metamodel.EntityType;
|
||||||
|
import javax.persistence.metamodel.Attribute;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author patri
|
||||||
|
*/
|
||||||
|
@Stateless
|
||||||
|
@Named
|
||||||
|
public class ChangeToCLOBManager {
|
||||||
|
|
||||||
|
// Inject the Logger
|
||||||
|
private static final Logger logger = LogManager.getLogger(ChangeToCLOBManager.class);
|
||||||
|
|
||||||
|
@PersistenceContext
|
||||||
|
private EntityManager em;
|
||||||
|
|
||||||
|
@javax.ejb.Asynchronous
|
||||||
|
public void checkColumnType() {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Map<String, List<String>> tables_values = checkLobAnnotations(em);
|
||||||
|
logger.info("running check for table values!");
|
||||||
|
tables_values.forEach((table, columns) -> {
|
||||||
|
if (columns == null || columns.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger.info("looking for fields in {}", table);
|
||||||
|
|
||||||
|
// Check if the column's data type is VARCHAR
|
||||||
|
columns.stream().filter(col -> (isVarcharColumn(em, table, col))).map(col -> {
|
||||||
|
// Change the column's data type to CLOB
|
||||||
|
changeColumnType(em, table, col);
|
||||||
|
return col;
|
||||||
|
}).forEachOrdered(col -> {
|
||||||
|
logger.info("Changed column type to CLOB of table: {}; column: {}", table, col);
|
||||||
|
});
|
||||||
|
});*/
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isVarcharColumn(EntityManager em, String tableName, String columnName) {
|
||||||
|
// Construct the native SQL query
|
||||||
|
String nativeSql = "SELECT TYPE_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ?1 AND COLUMN_NAME = ?2";
|
||||||
|
|
||||||
|
// Create a native Query
|
||||||
|
Query nativeQuery = em.createNativeQuery(nativeSql);
|
||||||
|
|
||||||
|
// Set the parameters for the query
|
||||||
|
nativeQuery.setParameter(1, tableName.toUpperCase());
|
||||||
|
nativeQuery.setParameter(2, columnName.toUpperCase());
|
||||||
|
|
||||||
|
logger.info("Added parameters 1: {}; 2:{}", tableName.toUpperCase(), columnName.toUpperCase());
|
||||||
|
String dataType = null;
|
||||||
|
// Execute the query and get the result
|
||||||
|
try {
|
||||||
|
dataType = (String) nativeQuery.getSingleResult();
|
||||||
|
} catch (NoResultException e) {
|
||||||
|
logger.info("NoResult", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true if the column's data type is VARCHAR, false otherwise
|
||||||
|
return dataType != null ? "VARCHAR".equalsIgnoreCase(dataType) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void changeColumnType(EntityManager em, String tableName, String columnName) {
|
||||||
|
// Construct the native SQL query
|
||||||
|
String nativeSql = "ALTER TABLE " + tableName.toUpperCase() + " MODIFY COLUMN " + columnName.toUpperCase() + " CLOB";
|
||||||
|
|
||||||
|
logger.info(nativeSql);
|
||||||
|
|
||||||
|
// Create a native Query
|
||||||
|
Query nativeQuery = em.createNativeQuery(nativeSql);
|
||||||
|
|
||||||
|
// Execute the query
|
||||||
|
nativeQuery.executeUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, List<String>> checkLobAnnotations(EntityManager em) {
|
||||||
|
// Create a Map to store the results
|
||||||
|
Map<String, List<String>> results = new HashMap<>();
|
||||||
|
// Get the Metamodel from the EntityManager
|
||||||
|
Metamodel metamodel = em.getMetamodel();
|
||||||
|
|
||||||
|
// Iterate over all the managed types
|
||||||
|
for (ManagedType<?> managedType : metamodel.getManagedTypes()) {
|
||||||
|
// Check if the managed type is an Entity
|
||||||
|
if (managedType.getJavaType().isAnnotationPresent(Entity.class)) {
|
||||||
|
// Get the EntityType for the managed type
|
||||||
|
EntityType<?> entityType = (EntityType<?>) managedType;
|
||||||
|
// Get the table name
|
||||||
|
|
||||||
|
// Iterate over all the attributes
|
||||||
|
for (Attribute<?, ?> attribute : entityType.getAttributes()) {
|
||||||
|
String tableName = entityType.getName();
|
||||||
|
String columnName = attribute.getName();
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
logger.info(entityType.getJavaType().getName());
|
||||||
|
Class<?> cl = getClass().getClassLoader().loadClass(entityType.getJavaType().getName());
|
||||||
|
Field[] fields = getClass().getClassLoader().loadClass(entityType.getJavaType().getName()).getFields();
|
||||||
|
for(Field field : fields){
|
||||||
|
field.setAccessible(true);
|
||||||
|
logger.info(field.getName());
|
||||||
|
if (field.isAnnotationPresent(Lob.class)) {
|
||||||
|
logger.info("Field with lob class!!!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("entity name : {}; attribute name: {}; isLob: {}", tableName, columnName, "todo");
|
||||||
|
} catch (SecurityException ex) {
|
||||||
|
logger.error("Security");
|
||||||
|
} catch (ClassNotFoundException ex) {
|
||||||
|
logger.error("Classnot");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the element has the @Lob annotation
|
||||||
|
if (attribute.getJavaType().isAnnotationPresent(Lob.class)) {
|
||||||
|
logger.info("Attribute " + attribute.getName() + " in " + entityType.getName() + " has @Lob annotation");
|
||||||
|
if (!results.containsKey(tableName)) {
|
||||||
|
results.put(tableName, new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
results.get(tableName).add(columnName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package business;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.ejb.EJB;
|
||||||
|
import javax.ejb.Schedule;
|
||||||
|
import javax.ejb.Singleton;
|
||||||
|
import javax.ejb.Startup;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
@Named
|
||||||
|
@Startup
|
||||||
|
@Singleton
|
||||||
|
public class DatabaseBackupManager {
|
||||||
|
|
||||||
|
private static final Logger logger = LogManager.getLogger(DatabaseBackupManager.class);
|
||||||
|
|
||||||
|
@EJB
|
||||||
|
private ChangeToCLOBManager changeToCLOBManager;
|
||||||
|
|
||||||
|
@PersistenceContext(unitName="pu_person")
|
||||||
|
private EntityManager entityManager;
|
||||||
|
|
||||||
|
@Schedule(hour="4", minute = "0", second = "0", persistent = true)
|
||||||
|
public void createDatabaseBackup() {
|
||||||
|
// Get the current date and time
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
|
||||||
|
// Format the date and time to be included in the filename
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss");
|
||||||
|
String formattedDateTime = now.format(formatter);
|
||||||
|
|
||||||
|
// Create the backup filename
|
||||||
|
String backupFilename = "/h2DB/h2-mss-database-backup_" + formattedDateTime + ".zip";
|
||||||
|
|
||||||
|
// Use the EntityManager to create a backup of the H2 database
|
||||||
|
entityManager.createNativeQuery("BACKUP TO '" + backupFilename + "'")
|
||||||
|
.executeUpdate();
|
||||||
|
|
||||||
|
// Log a message indicating that the backup was successful
|
||||||
|
logger.info("Successfully created H2 database backup: " + backupFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
private void init(){
|
||||||
|
changeToCLOBManager.checkColumnType();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package business;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.enterprise.context.SessionScoped;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.primefaces.model.DefaultStreamedContent;
|
||||||
|
import org.primefaces.model.StreamedContent;
|
||||||
|
|
||||||
|
@Named
|
||||||
|
@SessionScoped
|
||||||
|
public class LogFileManager implements Serializable {
|
||||||
|
|
||||||
|
private static final Logger logger = LogManager.getLogger(LogFileManager.class);
|
||||||
|
private static final String LOG_DIRECTORY = "/logs/";
|
||||||
|
|
||||||
|
private List<File> logFiles;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
loadLogFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadLogFiles() {
|
||||||
|
File directory = new File(LOG_DIRECTORY);
|
||||||
|
if (directory.exists() && directory.isDirectory()) {
|
||||||
|
File[] files = directory.listFiles((dir, name) -> name != null && name.startsWith("application.log"));
|
||||||
|
if (files != null) {
|
||||||
|
logFiles = Arrays.asList(files);
|
||||||
|
Collections.sort(logFiles, (f1, f2) -> Long.compare(f2.lastModified(), f1.lastModified()));
|
||||||
|
} else {
|
||||||
|
logFiles = Collections.emptyList();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logFiles = Collections.emptyList();
|
||||||
|
logger.warn("Log-Verzeichnis existiert nicht: " + LOG_DIRECTORY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<File> getLogFiles() {
|
||||||
|
return logFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StreamedContent downloadFile(String fileName) {
|
||||||
|
try {
|
||||||
|
final File file = new File(LOG_DIRECTORY + fileName);
|
||||||
|
final String contentType;
|
||||||
|
if (fileName.endsWith(".gz")) {
|
||||||
|
contentType = "application/gzip";
|
||||||
|
} else if (fileName.endsWith(".log")) {
|
||||||
|
contentType = "text/plain";
|
||||||
|
} else {
|
||||||
|
contentType = "application/octet-stream";
|
||||||
|
}
|
||||||
|
return DefaultStreamedContent.builder()
|
||||||
|
.name(fileName)
|
||||||
|
.contentType(contentType)
|
||||||
|
.stream(() -> {
|
||||||
|
try {
|
||||||
|
return new FileInputStream(file);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("Fehler beim Lesen der Log-Datei: " + fileName, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Fehler beim Vorbereiten des Downloads für Log-Datei: " + fileName, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package business;
|
||||||
|
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
import javax.mail.Message;
|
||||||
|
import javax.mail.Session;
|
||||||
|
import javax.mail.Transport;
|
||||||
|
import javax.mail.internet.InternetAddress;
|
||||||
|
import javax.mail.internet.MimeMessage;
|
||||||
|
import java.util.Properties;
|
||||||
|
import javax.activation.DataHandler;
|
||||||
|
import javax.activation.DataSource;
|
||||||
|
import javax.activation.FileDataSource;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.mail.MessagingException;
|
||||||
|
import javax.mail.internet.MimeBodyPart;
|
||||||
|
import javax.mail.internet.MimeMultipart;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
@Named
|
||||||
|
@Stateless
|
||||||
|
public class PasswordResetEJB {
|
||||||
|
|
||||||
|
protected final Logger LOGGER = LogManager.getLogger(PasswordResetEJB.class);
|
||||||
|
|
||||||
|
// Set up the email server properties
|
||||||
|
private static final String SMTP_SERVER = "smtp.gmail.com";
|
||||||
|
private static final String USERNAME = "dein@user.gmail.com";
|
||||||
|
private static final String PASSWORD = "HierStehtDeinPasswort";
|
||||||
|
|
||||||
|
// Set up the email message properties
|
||||||
|
private static final String EMAIL_SUBJECT = "Password Reset Request";
|
||||||
|
private static final String EMAIL_BODY
|
||||||
|
= "Sehr geehrte/r %s,\n\n"
|
||||||
|
+ "Sie haben angefordert, Ihr Passwort zurückzusetzen. Bitte klicken Sie auf den unten stehenden Link, um fortzufahren:\n\n"
|
||||||
|
+ "%s\n\n"
|
||||||
|
+ "Wenn Sie diese Anfrage nicht gestellt haben, ignorieren Sie bitte diese E-Mail.\n\n"
|
||||||
|
+ "Bitte beachten Sie, dass der Link nur einmal verwendet werden kann und innerhalb von 24 Stunden ab Erhalt dieser E-Mail abläuft.\n\n"
|
||||||
|
+ "Wenn Sie weitere Fragen haben, zögern Sie bitte nicht, uns zu kontaktieren.\n\n"
|
||||||
|
+ "Freundliche Grüße,\n\n"
|
||||||
|
+ "%s";
|
||||||
|
private static final String COMPANY
|
||||||
|
= "MSS Machine Safety Services\n"
|
||||||
|
+ "+49162 1322 382\n"
|
||||||
|
+ "kontakt@mss-failsafe.com\n"
|
||||||
|
+ "Lüneburger Str. 48\n"
|
||||||
|
+ "28870 Ottersberg";
|
||||||
|
|
||||||
|
private static final String imagePath = "/resources/images/logos/logo_small.png";
|
||||||
|
private static DataSource dataSource;
|
||||||
|
|
||||||
|
public boolean sendPasswordResetEmail(String to, String name, String resetLink) {
|
||||||
|
if (dataSource == null) {
|
||||||
|
dataSource = new FileDataSource(imagePath);
|
||||||
|
}
|
||||||
|
// Set up the email server properties
|
||||||
|
Properties prop = new Properties();
|
||||||
|
prop.put("mail.smtp.host", SMTP_SERVER);
|
||||||
|
prop.put("mail.smtp.port", "587");
|
||||||
|
prop.put("mail.smtp.auth", "true");
|
||||||
|
prop.put("mail.smtp.starttls.enable", "true");
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Set up the email session
|
||||||
|
Session session = Session.getInstance(prop, null);
|
||||||
|
|
||||||
|
// Create a MimeMultipart object to hold the text and image parts of the email
|
||||||
|
MimeMultipart multipart = new MimeMultipart("related");
|
||||||
|
|
||||||
|
// Create a MimeBodyPart object to hold the text of the email
|
||||||
|
MimeBodyPart messageBodyPart = new MimeBodyPart();
|
||||||
|
messageBodyPart.setText(getFormattedMessage(name, resetLink));
|
||||||
|
multipart.addBodyPart(messageBodyPart);
|
||||||
|
|
||||||
|
// Create a MimeBodyPart object to hold the image
|
||||||
|
//MimeBodyPart imagePart = new MimeBodyPart();
|
||||||
|
//imagePart.setDataHandler(new DataHandler(dataSource));
|
||||||
|
//imagePart.setHeader("Content-ID", "MSS Machine Safety Services");
|
||||||
|
//multipart.addBodyPart(imagePart);
|
||||||
|
|
||||||
|
// Set up the email message
|
||||||
|
MimeMessage message = new MimeMessage(session);
|
||||||
|
message.setFrom(new InternetAddress(USERNAME));
|
||||||
|
message.setRecipients(Message.RecipientType.TO, to);
|
||||||
|
message.setSubject(EMAIL_SUBJECT);
|
||||||
|
message.setContent(multipart);
|
||||||
|
|
||||||
|
// Send the email message
|
||||||
|
Transport transport = session.getTransport("smtp");
|
||||||
|
transport.connect(SMTP_SERVER, USERNAME, PASSWORD);
|
||||||
|
transport.sendMessage(message, message.getAllRecipients());
|
||||||
|
transport.close();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (MessagingException e) {
|
||||||
|
LOGGER.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFormattedMessage(String name, String resetLink) {
|
||||||
|
return String.format(EMAIL_BODY, name, resetLink, COMPANY);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package business.addresses;
|
||||||
|
|
||||||
|
import business.AbstractManager;
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
import model.company.Location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author patri
|
||||||
|
*/
|
||||||
|
@Named
|
||||||
|
@Stateless
|
||||||
|
public class CompanyAddressManager extends AbstractManager<Location>{
|
||||||
|
|
||||||
|
@PersistenceContext(name = "pu_person")
|
||||||
|
EntityManager em;
|
||||||
|
|
||||||
|
public CompanyAddressManager() {
|
||||||
|
super(Location.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected EntityManager getEntityManager() {
|
||||||
|
return em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package business.addresses;
|
||||||
|
|
||||||
|
import business.AbstractManager;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
import model.company.Location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author patri
|
||||||
|
*/
|
||||||
|
@Named
|
||||||
|
@Stateless
|
||||||
|
public class LocationAddressManager extends AbstractManager<Location>{
|
||||||
|
|
||||||
|
@PersistenceContext(name = "pu_person")
|
||||||
|
EntityManager em;
|
||||||
|
|
||||||
|
public LocationAddressManager() {
|
||||||
|
super(Location.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected EntityManager getEntityManager() {
|
||||||
|
return em;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
|
||||||
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
|
||||||
|
*/
|
||||||
|
package business.company;
|
||||||
|
|
||||||
|
import business.AbstractManager;
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
import model.company.CompanyLogo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pplate
|
||||||
|
*/
|
||||||
|
@Named
|
||||||
|
@Stateless
|
||||||
|
public class CompanyLogoManager extends AbstractManager<CompanyLogo>{
|
||||||
|
|
||||||
|
@PersistenceContext(name = "pu_person")
|
||||||
|
EntityManager em;
|
||||||
|
|
||||||
|
public CompanyLogoManager() {
|
||||||
|
super(CompanyLogo.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected EntityManager getEntityManager() {
|
||||||
|
return em;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package business.company;
|
||||||
|
|
||||||
|
import business.AbstractManager;
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
import model.company.Company;
|
||||||
|
import model.company.Location;
|
||||||
|
import model.machine.Machine;
|
||||||
|
import org.hibernate.Hibernate;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.persistence.NoResultException;
|
||||||
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author patri
|
||||||
|
*/
|
||||||
|
@Named
|
||||||
|
@Stateless
|
||||||
|
public class CompanyManager extends AbstractManager<Company> {
|
||||||
|
|
||||||
|
@PersistenceContext(name = "pu_person")
|
||||||
|
EntityManager em;
|
||||||
|
|
||||||
|
private static final String loadWithCollectionQuery =
|
||||||
|
"SELECT DISTINCT c FROM Company c " +
|
||||||
|
"LEFT JOIN FETCH c.addresses " +
|
||||||
|
"LEFT JOIN FETCH c.locations l " +
|
||||||
|
"LEFT JOIN FETCH l.machines m " +
|
||||||
|
"LEFT JOIN FETCH m.securityArea sa " +
|
||||||
|
"LEFT JOIN FETCH sa.securityDevices " +
|
||||||
|
"LEFT JOIN FETCH sa.dangerPoints " +
|
||||||
|
"LEFT JOIN FETCH sa.switchingDevices " +
|
||||||
|
"LEFT JOIN FETCH sa.questionnaires " +
|
||||||
|
"WHERE c.id = :companyId";
|
||||||
|
|
||||||
|
public CompanyManager() {
|
||||||
|
super(Company.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected EntityManager getEntityManager() {
|
||||||
|
return em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Company findWithAddresses(Company selected) {
|
||||||
|
Company loaded = null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
try {
|
||||||
|
return em.createQuery(loadWithCollectionQuery, Company.class)
|
||||||
|
.setParameter("companyId", selected.getId())
|
||||||
|
.getSingleResult();
|
||||||
|
} catch (NoResultException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
try {
|
||||||
|
loaded = find(selected.getId());
|
||||||
|
Hibernate.initialize(loaded);
|
||||||
|
loaded.getLocations().stream()
|
||||||
|
.map(Location::getMachines)
|
||||||
|
.flatMap(List::stream)
|
||||||
|
.map(Machine::getSecurityArea)
|
||||||
|
.flatMap(List::stream)
|
||||||
|
.forEach(area -> {
|
||||||
|
Hibernate.initialize(area.getSecurityDevices());
|
||||||
|
Hibernate.initialize(area.getDangerPoints());
|
||||||
|
Hibernate.initialize(area.getSwitchingDevices());
|
||||||
|
Hibernate.initialize(area.getQuestionnaires());
|
||||||
|
if (area.getQuestionnaires() != null) {
|
||||||
|
area.getQuestionnaires().forEach(q -> Hibernate.initialize(q.getQuestions()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//loaded.getLocations().size();
|
||||||
|
//loaded.getAddresses().size();
|
||||||
|
//loaded.getCustomers().size();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Company findCompanyByName(String name) {
|
||||||
|
TypedQuery<Company> query = em.createNamedQuery(Company.FIND_BY_NAME, Company.class);
|
||||||
|
query.setParameter("name", name);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Company loaded = query.getSingleResult();
|
||||||
|
if (loaded != null) {
|
||||||
|
Hibernate.initialize(loaded.getAddresses());
|
||||||
|
loaded.getLocations().stream()
|
||||||
|
.map(Location::getMachines)
|
||||||
|
.flatMap(List::stream)
|
||||||
|
.map(Machine::getSecurityArea)
|
||||||
|
.flatMap(List::stream)
|
||||||
|
.forEach(area -> {
|
||||||
|
Hibernate.initialize(area.getSecurityDevices());
|
||||||
|
Hibernate.initialize(area.getDangerPoints());
|
||||||
|
Hibernate.initialize(area.getSwitchingDevices());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return loaded;
|
||||||
|
|
||||||
|
} catch (NoResultException noRe) {
|
||||||
|
return null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Company findWithLocations(Company selected) {
|
||||||
|
Company loaded = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
loaded = find(selected.getId());
|
||||||
|
loaded.getCustomers().size();
|
||||||
|
loaded.getLocations().size();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return loaded;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package business.company;
|
||||||
|
|
||||||
|
import business.AbstractManager;
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
import javax.persistence.TypedQuery;
|
||||||
|
import model.customer.Customer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author patri
|
||||||
|
*/
|
||||||
|
@Stateless
|
||||||
|
@Named
|
||||||
|
public class CustomerManager extends AbstractManager<Customer>{
|
||||||
|
|
||||||
|
@PersistenceContext(name = "pu_person")
|
||||||
|
EntityManager em;
|
||||||
|
|
||||||
|
public CustomerManager() {
|
||||||
|
super(Customer.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected EntityManager getEntityManager() {
|
||||||
|
return em;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Customer findByEmail(String email){
|
||||||
|
Customer result = null;
|
||||||
|
if (email == null || email.isEmpty()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
TypedQuery<Customer> query = em.createNamedQuery(Customer.GET_BY_EMAIL, Customer.class);
|
||||||
|
query.setParameter("email", email);
|
||||||
|
|
||||||
|
try {
|
||||||
|
result = query.getSingleResult();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.info(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package business.company;
|
||||||
|
|
||||||
|
import business.AbstractManager;
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
import model.company.Location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author patri
|
||||||
|
*/
|
||||||
|
@Named
|
||||||
|
@Stateless
|
||||||
|
public class LocationManager extends AbstractManager<Location>{
|
||||||
|
|
||||||
|
@PersistenceContext(name = "pu_person")
|
||||||
|
EntityManager em;
|
||||||
|
|
||||||
|
public LocationManager() {
|
||||||
|
super(Location.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected EntityManager getEntityManager() {
|
||||||
|
return em;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location loadWithMachines(Long id){
|
||||||
|
if (id == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Location loc = find(id);
|
||||||
|
loc.getMachines().size();
|
||||||
|
return loc;
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
|
||||||
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
|
||||||
|
*/
|
||||||
|
package business.machine;
|
||||||
|
|
||||||
|
import business.AbstractManager;
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
import model.machine.Contact;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pplate
|
||||||
|
*/
|
||||||
|
@Named
|
||||||
|
@Stateless
|
||||||
|
public class ContactManager extends AbstractManager<Contact>{
|
||||||
|
|
||||||
|
@PersistenceContext(name = "pu_person")
|
||||||
|
EntityManager em;
|
||||||
|
|
||||||
|
public ContactManager() {
|
||||||
|
super(Contact.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected EntityManager getEntityManager() {
|
||||||
|
return em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
|
||||||
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
|
||||||
|
*/
|
||||||
|
package business.machine;
|
||||||
|
|
||||||
|
import business.AbstractManager;
|
||||||
|
import java.util.Collection;
|
||||||
|
import javax.ejb.EJB;
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
import model.AbstractEntity;
|
||||||
|
import model.security.DangerPoint;
|
||||||
|
import model.security.MeasuringPoint;
|
||||||
|
import org.hibernate.Hibernate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pplate
|
||||||
|
*/
|
||||||
|
@Named
|
||||||
|
@Stateless
|
||||||
|
public class DangerPointManager extends AbstractManager<DangerPoint> {
|
||||||
|
|
||||||
|
@PersistenceContext(name = "pu_person")
|
||||||
|
EntityManager em;
|
||||||
|
|
||||||
|
@EJB
|
||||||
|
MeasuringPointManager measuringPointManager;
|
||||||
|
|
||||||
|
public DangerPointManager() {
|
||||||
|
super(DangerPoint.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected EntityManager getEntityManager() {
|
||||||
|
return em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(DangerPoint entity) {
|
||||||
|
entity = em.find(DangerPoint.class, entity.getId());
|
||||||
|
Hibernate.initialize(entity.getMeasuringPoint());
|
||||||
|
if (entity.getMeasuringPoint() != null) {
|
||||||
|
entity.getMeasuringPoint().setDangerPoint(null);
|
||||||
|
em.remove(entity.getMeasuringPoint());
|
||||||
|
//measuringPointManager.remove(entity.getMeasuringPoint());
|
||||||
|
entity.setMeasuringPoint(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
entity = em.find(DangerPoint.class, entity.getId());
|
||||||
|
em.remove(entity);
|
||||||
|
//save(entity);
|
||||||
|
|
||||||
|
//return super.remove(entity);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeAllIn(Collection<DangerPoint> col) {
|
||||||
|
for (DangerPoint dp : col) {
|
||||||
|
if (dp.getMeasuringPoint() != null) {
|
||||||
|
dp.getMeasuringPoint().setDangerPoint(null);
|
||||||
|
MeasuringPoint pt = dp.getMeasuringPoint();
|
||||||
|
dp.setMeasuringPoint(null);
|
||||||
|
measuringPointManager.save(pt);
|
||||||
|
measuringPointManager.remove(pt);
|
||||||
|
}
|
||||||
|
dp.setSecurityArea(null);
|
||||||
|
save(dp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.removeAllIn(col);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package business.machine;
|
||||||
|
|
||||||
|
import business.AbstractManager;
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
import model.company.Location;
|
||||||
|
import model.machine.Machine;
|
||||||
|
import model.security.SecurityArea;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author patri
|
||||||
|
*/
|
||||||
|
@Named
|
||||||
|
@Stateless
|
||||||
|
public class MachineManager extends AbstractManager<Machine>{
|
||||||
|
|
||||||
|
@PersistenceContext(name = "pu_person")
|
||||||
|
EntityManager em;
|
||||||
|
|
||||||
|
public MachineManager() {
|
||||||
|
super(Machine.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected EntityManager getEntityManager() {
|
||||||
|
return em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Machine copyMachine(Machine mac){
|
||||||
|
save(mac);
|
||||||
|
|
||||||
|
mac = refresh(mac);
|
||||||
|
if (mac.getInspections() != null) {
|
||||||
|
mac.getInspections().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mac.getSecurityArea() != null) {
|
||||||
|
mac.getSecurityArea().size();
|
||||||
|
for(SecurityArea area : mac.getSecurityArea()){
|
||||||
|
area.getSecurityDevices().size();
|
||||||
|
area.getSwitchingDevices().size();
|
||||||
|
area.getDangerPoints().size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Machine copy = new Machine(mac);
|
||||||
|
if (save(copy)) {
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user