Skip to content

Commit bbd2846

Browse files
committed
Clean up code quality issues
- DatatypeBoolean/DatatypeXHTML: drop the private id/name fields that shadowed the base class along with their redundant getters - ExceptionSpecObject: readable message (line breaks between the fields, datatype name instead of an object dump, tolerates a null definition) - AttributeValueDate: parse the xsd:dateTime value into an OffsetDateTime (getDateTime/getDate); getValue() still returns the raw string and unparseable values yield null instead of throwing - ReqIFHeader: remove the tool-specific "_Template" stripping from getTitle() and reactivate getComment(), which was commented out even though the COMMENT was already read - Remove leftover commented-out code in Specification and ReqIFHeader - Tests: CodeQualityFixesTest BREAKING: getTitle() returns the title as written in the document; it no longer strips a "_Template" suffix. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011mat2d7AJkouKhXWUYzHxs
1 parent 302fe66 commit bbd2846

8 files changed

Lines changed: 250 additions & 59 deletions

File tree

FEHLERANALYSE.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ die bei jedem Push in der GitHub-Actions-Pipeline (`.github/workflows/ci.yml`, `
1818
| `SpecRelation`-Typsemantik + Relationsattribute (4.3) | "Fix SpecRelation type semantics and parse relation attributes" | `SpecRelationTest` |
1919
| Tabellen-/Listen-Deconstruction (4.7) | "Derive XHTML token list from the node tree" | `XHTMLDeconstructionTest` |
2020
| XHTML-Ausgabe: Escaping, Attribute, Inhaltsverlust (4.8) | "Fix XHTML rendering" | `XHTMLRenderingTest` |
21+
| Code-Qualität (Abschnitt 5) | "Clean up code quality issues" | `CodeQualityFixesTest` |
2122

2223
Zur Heuristik (4.2): Die Klassifizierung ist jetzt eine Strategie (`TypeClassifier`),
2324
die das fertig geparste `SpecObject` (inkl. Attributwerte) erhält.
@@ -65,8 +66,23 @@ beschrieben — tatsächlich lag **Inhaltsverlust** vor. Behoben:
6566
**Breaking Change:** `getValue()` liefert für XHTML-Attribute einen anderen (korrekten)
6667
String als zuvor. Baum (`getDivValue()`) und Token-Liste sind nicht betroffen.
6768

68-
Bewusst nicht angefasst: die kosmetischen Punkte aus Abschnitt 5
69-
(bis auf den entfernten `javax.xml.crypto.Data`-Import).
69+
Zu Abschnitt 5: alle Punkte erledigt.
70+
- 5.1 Feld-Verschattung in `DatatypeBoolean`/`DatatypeXHTML` entfernt (die Getter der
71+
Basisklasse liefern dieselben Werte).
72+
- 5.2 unbenutzter `javax.xml.crypto.Data`-Import entfernt.
73+
- 5.3 `ExceptionSpecObject`: lesbare Meldung mit Zeilenumbrüchen, Datentyp als Name
74+
statt Objekt-Dump, verträgt eine fehlende Definition.
75+
- 5.4 durch das Java-17-Target gegenstandslos.
76+
- 5.5 `AttributeValueDate` parst den Wert zusätzlich nach `OffsetDateTime`
77+
(`getDateTime()`, `getDate()`); `getValue()` liefert unverändert den Rohstring,
78+
unparsbare Werte ergeben `null` statt einer Exception.
79+
- 5.6 `_Template`-Hack entfernt: `getTitle()` liefert den Titel wie im Dokument.
80+
**Breaking Change** für Nutzer, die sich auf das Abschneiden verlassen haben.
81+
- 5.7 auskommentierter Code entfernt; `getComment()` ist reaktiviert (der `COMMENT`
82+
wurde ohnehin gelesen). Die Tippfehler in den Methodennamen sind mit der
83+
Neuimplementierung der Deconstruction entfallen.
84+
85+
Damit sind alle Punkte der Analyse abgearbeitet.
7086

7187
Die ursprüngliche Analyse folgt unverändert. Datei- und Zeilenangaben beziehen sich auf den
7288
Stand **vor** den Fixes (Quellen liegen inzwischen unter `src/main/java/`).
Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,73 @@
11
package de.uni_stuttgart.ils.reqif4j.attributes;
22

3-
public class AttributeValueDate extends AttributeValue{
3+
import java.time.LocalDate;
4+
import java.time.LocalDateTime;
5+
import java.time.OffsetDateTime;
6+
import java.time.ZoneOffset;
7+
import java.time.format.DateTimeParseException;
8+
9+
/**
10+
* Value of a DATE attribute. ReqIF declares DATE as {@code xsd:dateTime}, so
11+
* the raw string is additionally parsed into a {@link OffsetDateTime}.
12+
*
13+
* {@link #getValue()} keeps returning the raw string; use
14+
* {@link #getDateTime()} for the parsed value.
15+
*/
16+
public class AttributeValueDate extends AttributeValue {
17+
18+
private final OffsetDateTime dateTime;
19+
420
public AttributeValueDate(String value, AttributeDefinition type) {
521
super(value, type);
622

7-
23+
this.dateTime = parse(value);
824
}
925

26+
/**
27+
* @return the raw value as written in the document (may be null)
28+
*/
1029
@Override
1130
public Object getValue() {
12-
return (String)this.value;
31+
return (String) this.value;
32+
}
33+
34+
/**
35+
* @return the parsed timestamp, or null if the attribute has no value or
36+
* the value is not a valid date. Values without a zone offset are
37+
* read as UTC, date-only values as start of day UTC.
38+
*/
39+
public OffsetDateTime getDateTime() {
40+
return this.dateTime;
41+
}
42+
43+
/**
44+
* @return the parsed date without time, or null if unparseable
45+
*/
46+
public LocalDate getDate() {
47+
return this.dateTime == null ? null : this.dateTime.toLocalDate();
48+
}
49+
50+
private static OffsetDateTime parse(String value) {
51+
52+
if (value == null || value.isBlank()) {
53+
return null;
54+
}
55+
String date = value.trim();
56+
57+
try {
58+
return OffsetDateTime.parse(date);
59+
} catch (DateTimeParseException withoutOffset) {
60+
// fall through
61+
}
62+
try {
63+
return LocalDateTime.parse(date).atOffset(ZoneOffset.UTC);
64+
} catch (DateTimeParseException notADateTime) {
65+
// fall through
66+
}
67+
try {
68+
return LocalDate.parse(date).atStartOfDay().atOffset(ZoneOffset.UTC);
69+
} catch (DateTimeParseException notADate) {
70+
return null;
71+
}
1372
}
1473
}

src/main/java/de/uni_stuttgart/ils/reqif4j/datatypes/DatatypeBoolean.java

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,10 @@
33
import de.uni_stuttgart.ils.reqif4j.reqif.ReqIFConst;
44

55
public class DatatypeBoolean extends Datatype {
6-
7-
private String id;
8-
private String name;
9-
10-
11-
12-
13-
public String getID() {
14-
return this.id;
15-
}
16-
17-
public String getName() {
18-
return this.name;
19-
}
20-
21-
22-
23-
6+
7+
248
public DatatypeBoolean(String id, String name) {
259
super(id, name, ReqIFConst.BOOLEAN);
26-
27-
this.id = id;
28-
this.name = name;
2910
}
3011

3112
}

src/main/java/de/uni_stuttgart/ils/reqif4j/datatypes/DatatypeXHTML.java

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,10 @@
33
import de.uni_stuttgart.ils.reqif4j.reqif.ReqIFConst;
44

55
public class DatatypeXHTML extends Datatype {
6-
7-
8-
private String id;
9-
private String name;
10-
11-
12-
13-
14-
public String getID() {
15-
return this.id;
16-
}
17-
18-
public String getName() {
19-
return this.name;
20-
}
21-
22-
23-
24-
6+
7+
258
public DatatypeXHTML(String id, String name) {
269
super(id, name, ReqIFConst.XHTML);
27-
28-
this.id = id;
29-
this.name = name;
3010
}
3111

3212
}

src/main/java/de/uni_stuttgart/ils/reqif4j/reqif/ReqIFHeader.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public class ReqIFHeader {
1111
private String toolID;
1212
private String sourceToolID = "";
1313
private String reqifVersion = "";
14-
//private String comment = "";
14+
private String comment = "";
1515
private String creationDate = "";
1616

1717

@@ -41,9 +41,12 @@ public String getReqIFVersion() {
4141
return this.reqifVersion;
4242
}
4343

44-
/*public String getComment() {
44+
/**
45+
* @return the COMMENT of the header, or "" if the document declares none
46+
*/
47+
public String getComment() {
4548
return this.comment;
46-
}*/
49+
}
4750

4851
public String getCreationDate() {
4952
return this.creationDate;
@@ -66,10 +69,10 @@ public ReqIFHeader(Element theHeader) {
6669
if(theHeader.getElementsByTagName(ReqIFConst.COMMENT).getLength() > 0) {
6770
// The "Created by: " convention is tool-specific; a comment without
6871
// it must not crash the parser.
69-
String comment = theHeader.getElementsByTagName(ReqIFConst.COMMENT).item(0).getTextContent();
70-
int createdBy = comment.indexOf("Created by: ");
72+
this.comment = theHeader.getElementsByTagName(ReqIFConst.COMMENT).item(0).getTextContent();
73+
int createdBy = this.comment.indexOf("Created by: ");
7174
if(createdBy >= 0) {
72-
this.author = comment.substring(createdBy + "Created by: ".length()).trim();
75+
this.author = this.comment.substring(createdBy + "Created by: ".length()).trim();
7376
}
7477
}
7578
if(theHeader.getElementsByTagName(ReqIFConst.CREATION_TIME).getLength() > 0) {
@@ -83,7 +86,9 @@ public ReqIFHeader(Element theHeader) {
8386
}
8487
}
8588
if(theHeader.getElementsByTagName(ReqIFConst.TITLE).getLength() > 0) {
86-
this.title = theHeader.getElementsByTagName(ReqIFConst.TITLE).item(0).getTextContent().replace("_Template", "");
89+
// The title is returned as written in the document; stripping a
90+
// "_Template" suffix was a tool-specific hack in a generic parser.
91+
this.title = theHeader.getElementsByTagName(ReqIFConst.TITLE).item(0).getTextContent();
8792
}
8893
}
8994

src/main/java/de/uni_stuttgart/ils/reqif4j/specification/ExceptionSpecObject.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@
55
public class ExceptionSpecObject extends RuntimeException {
66

77
public ExceptionSpecObject(String message, AttributeDefinition attributeDefinition) {
8-
super(message + "Attribute Definition:\nID: " + attributeDefinition.getID() + "Name: " + attributeDefinition.getName() + "Type: " + attributeDefinition.getDataType());
8+
super(buildMessage(message, attributeDefinition));
9+
}
10+
11+
private static String buildMessage(String message, AttributeDefinition attributeDefinition) {
12+
13+
if (attributeDefinition == null) {
14+
return message;
15+
}
16+
return message
17+
+ "Attribute Definition:\n"
18+
+ "ID: " + attributeDefinition.getID() + "\n"
19+
+ "Name: " + attributeDefinition.getName() + "\n"
20+
+ "Type: " + (attributeDefinition.getDataType() == null
21+
? "<unresolved>"
22+
: attributeDefinition.getDataType().getType());
923
}
1024
}

src/main/java/de/uni_stuttgart/ils/reqif4j/specification/Specification.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ public class Specification {
3434
private Map<String, AttributeValue> attributeValues = new HashMap<String, AttributeValue>();
3535
private Map<String, SpecHierarchy> children = new LinkedHashMap<String, SpecHierarchy>();
3636
private List<SpecHierarchy> allSpecHierarchies = new ArrayList<SpecHierarchy>();
37-
//private Map<Integer, List<SpecObject>> allSpecObjects = new HashMap<Integer, List<SpecObject>>(); // TODO
3837

3938

4039

@@ -43,12 +42,14 @@ public String getID() {
4342
return this.id;
4443
}
4544

46-
///
45+
/**
46+
* @return the value of an attribute named "Description", or null if the
47+
* specification has no such attribute
48+
*/
4749
public String getDescription() {
4850
AttributeValue description = this.attributeValues.get("Description");
4951
return description == null ? null : (String) description.getValue();
5052
}
51-
//*/
5253

5354
public String getName() {
5455
return this.name;

0 commit comments

Comments
 (0)