Skip to content

Commit 7e690fb

Browse files
authored
Initial version of AsciiDoc plugin (#4)
* Support reading specification items from AsciiDoc files Created an Importer that supports reading Specification Items written in AsciiDoc, including unit tests. Also created the requirements and design documents using the proposed approach and amended the developer guide. * Incorporate feedback * Improve test
1 parent 771d2c5 commit 7e690fb

File tree

11 files changed

+899
-30
lines changed

11 files changed

+899
-30
lines changed

.vscode/settings.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,13 @@
1414
"sonarlint.connectedMode.project": {
1515
"connectionId": "itsallcode",
1616
"projectKey": "org.itsallcode:openfasttrace-asciidoc-plugin"
17-
}
17+
},
18+
"java.format.settings.url": "doc/itsallcode_formatter.xml",
19+
"java.test.config": {
20+
"name": "openfasttrace",
21+
"vmArgs": [
22+
"-Djava.util.logging.config.file=src/test/resources/logging.properties"
23+
]
24+
},
25+
"asciidoc.antora.enableAntoraSupport": false
1826
}

doc/developer_guide.md

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,34 +24,40 @@ dependencies {
2424

2525
## Dependencies
2626

27-
### Runtime Dependencies
28-
29-
| Dependency | Purpose | License |
30-
|------------|---------|---------|
31-
| TBD | TBD | TBD |
32-
3327
### Build Dependencies
3428

35-
| Dependency | Purpose | License |
36-
|------------|---------|---------|
37-
| TBD | TBD | TBD |
29+
The list below shows all build time dependencies in alphabetical order. Note that except the Maven build tool all required modules are downloaded automatically by Maven.
30+
31+
| Dependency | Purpose | License |
32+
| ----------------------------------------------------------------- | ------------------------------------- | ----------------------------- |
33+
| [Apache Maven](https://maven.apache.org/) | Build tool | Apache License 2.0 |
34+
| [AsciiDoctorJ](https://docs.asciidoctor.org/asciidoctorj/latest/) | Framework for parsing AsciiDoc | Apache License 2.0 |
35+
| [OpenFastTrace API](https://github.com/itsallcode/openfasttrace) | Interface to the OpenFaceTrace engine | GNU General Public License V3 |
3836

3937
### Test Dependencies
4038

41-
| Dependency | Purpose | License |
42-
|------------|---------|---------|
43-
| TBD | TBD | TBD |
39+
| Dependency | Purpose | License |
40+
| ---------------------------------------------------------------------------- | --------------------------------------- | ----------------------------- |
41+
| [Hamcrest Auto Matcher](https://github.com/itsallcode/hamcrest-auto-matcher) | Speed-up for building Hamcrest matchers | GNU General Public License V3 |
42+
| [JUnit](https://junit.org/junit5) | Unit testing framework | Eclipse Public License 1.0 |
43+
| [Mockito](https://github.com/mockito/mockito) | Mocking framework | MIT License |
44+
45+
### Runtime Dependencies
46+
47+
| Dependency | Purpose | License |
48+
| ------------------------------------------------------------ | ------------------------ | ----------------------------- |
49+
| [OpenFastTrace](https://github.com/itsallcode/openfasttrace) | The OpenFaceTrace engine | GNU General Public License V3 |
4450

4551
### Preparations
4652

47-
<!-- Description -->
53+
OpenFastTrace uses [Apache Maven](https://maven.apache.org) as technical project management tool that resolves and downloads the build-dependencies before building the packages.
4854

4955
### Installation of Initial Build Dependencies on Linux
5056

5157
#### Debian or Ubuntu
5258

5359
```bash
54-
apt-get install openjdk-11-jdk maven
60+
apt-get install openjdk-17-jdk maven
5561
```
5662

5763
## Configure Maven Toolchains

doc/spec/design.adoc

Lines changed: 312 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,312 @@
1-
<!-- Please add a design in the style of the OFT design document -->
1+
= OpenFastTrace AsciiDoc Plugin Design
2+
:toc: left
3+
:toclevels: 3
4+
:stylesheet: oft_spec.css
5+
:bib_arc42: https://arc42.org
6+
:bib_srs: link:system_requirements.adoc
7+
:bib_abnf: https://www.rfc-editor.org/rfc/rfc5234.html
8+
9+
== Introduction
10+
11+
=== Acknowledgments
12+
13+
This documents structure is derived from the {bib_arc42}[arc42] architectural template by Dr. Gernot Starke, Dr. Peter Hruschka.
14+
15+
If you build your own modifications based on this document, please keep the attrbiutions.
16+
17+
=== Terminology
18+
19+
The terminology from the {bib_srs}[system requirement specification] applies.
20+
21+
=== Conventions
22+
23+
==== Syntax Definitions
24+
Syntax definitions in this document use the {bib_abnf}[Augmented Backus-Naur Form].
25+
26+
The following definitions are used frequently throughout the document:
27+
28+
* ANY - any valid character
29+
* LINEBREAK = the line break character of the platform
30+
31+
== Constraints
32+
33+
== Solution Ideas and Strategy
34+
35+
=== Embedding Specification Item Information into AsciiDoc
36+
37+
AsciiDoc allows https://docs.asciidoctor.org/asciidoc/latest/attributes/element-attributes/[_attributes_] to be assigned to a document's block and inline elements using an _attribute list_.
38+
39+
An AsciiDoc block can be marked up to contain OFT specification item information by means of assigning a corresponding _role attribute_ to its attribute list.
40+
The specification item information can then be encoded into _named attributes_ and/or inline elements of the block which in turn can be marked up using corresponding role attributes.
41+
42+
== Context
43+
44+
=== Technical Constraints
45+
46+
The plugin must be implemented in Java in order to work with the OFT engine.
47+
48+
=== Conventions
49+
50+
== Building Block View
51+
52+
=== AsciiDoc Importer
53+
54+
The AsciiDoc Importer reads specification items from ASciiDoc files.
55+
56+
== Runtime View
57+
58+
=== Import
59+
60+
The OFT engine discovers the AsciiDoc Importer during startup by means of Java's Service Discovery mechanism. The OFT engine then invokes the importer for all files having an `.adoc` extension to read specification items from the files. The importer emits corresponding events that are consumed by the OFT engine's [import event listener](#import-event-listener).
61+
62+
Common parts of the import like filtering out unnecessary items or attributes are handled by the listener.
63+
64+
== Deployment View
65+
66+
The AsciiDoc Importer is provided by means of a set of Java Archive (jar) files.
67+
68+
== Concepts
69+
70+
[.specitem, oft-skipped="dsn", oft-needs="impl, utest", oft-covers="req~asciidoc-file-extensions~1"]
71+
--
72+
--
73+
74+
== Data Structures
75+
76+
=== AsciiDoc-style Structures
77+
78+
[.specitem, oft-sid="dsn~adoc-specification-item-markup~1", oft-covers="req~asciidoc-standard-syntax~1", oft-needs="impl, utest"]
79+
==== AsciiDoc Specification Item Markup
80+
81+
A block or inline element of an AsciiDoc document is marked up as an _AsciiDoc specification item_ by means of assigning the `.specitem` _role attribute_ to it.
82+
83+
.Example
84+
[example]
85+
----
86+
[.specitem, oft-sid="req~first-requirement~1", oft-needs="dsn"]
87+
== First Requirement
88+
89+
This is the specification item's description.
90+
----
91+
92+
[.specitem, oft-sid="dsn~adoc-specification-item-id~1", oft-covers="req~asciidoc-standard-syntax~1", oft-needs="impl, utest"]
93+
==== AsciiDoc Specification Item ID
94+
95+
The identifier of an AsciiDoc specification item is set by means of assigning the `oft-sid` _named attribute_ to it.
96+
The value of the attribute is a standard OFT specification item ID.
97+
98+
.Example
99+
[example]
100+
----
101+
[.specitem, oft-sid="req~first-requirement~1", oft-needs="dsn"]
102+
== First Requirement
103+
104+
This is the description of the first requirement.
105+
----
106+
107+
.Rationale
108+
[.rationale]
109+
Using a named attribute for setting the specification item ID allows to easily retrieve the ID from a block using the existing AsciiDoctorJ API.
110+
111+
[.specitem, oft-sid="dsn~adoc-specification-item-title~1", oft-covers="req~asciidoc-standard-syntax~1, req~asciidoc-outline-readable~1", oft-needs="impl, utest"]
112+
==== AsciiDoc Specification Item Title
113+
114+
If the block or inline element marked up as a specification item has an AsciiDoc title, then the AsciiDoc title is used as the title for the specification item.
115+
116+
.Rationale
117+
[.rationale]
118+
AsciiDoc titles show up in the outline and are a natural way of defining a requirement title.
119+
120+
[.specitem, oft-sid="dsn~adoc-specification-item-description~1", oft-covers="req~asciidoc-standard-syntax~1", oft-needs="impl, utest"]
121+
==== AsciiDoc Specification Item Description
122+
123+
If the first nested block inside the AsciiDoc specification item has no `.rationale` nor `.comment` role attribute, then it is used as the specification item description. Otherwise, the first nested block having the `.description` role attribute is used. If no such block exists, the specification item has no description.
124+
125+
.Implicit Description
126+
[example]
127+
----
128+
[.specitem, oft-sid="req~first-requirement~1", oft-needs="dsn"]
129+
== First Requirement
130+
131+
The description is taken from the first block.
132+
----
133+
134+
.Explicit Description
135+
[example]
136+
----
137+
[.specitem, oft-sid="req~first-requirement~1", oft-needs="dsn"]
138+
== First Requirement
139+
140+
.Description
141+
[.description]
142+
The description is contained in a delimited block with the `.description` role attribute.
143+
----
144+
145+
[.specitem, oft-sid="dsn~adoc-specification-item-rationale~1", oft-covers="req~asciidoc-standard-syntax~1", oft-needs="impl, utest"]
146+
==== AsciiDoc Specification Item Rationale
147+
148+
The rationale for an AsciiDoc specification item can be provided by means of adding a delimited block to it which has the `.rationale` role attribute.
149+
150+
.Example
151+
[example]
152+
----
153+
[.specitem, oft-sid="req~first-requirement~1", oft-needs="dsn"]
154+
== First Requirement
155+
156+
This is the specification item's description.
157+
158+
.Rationale
159+
[.rationale]
160+
The reason for this requirement is ...
161+
----
162+
163+
[.specitem, oft-sid="dsn~adoc-specification-item-comment~1", oft-covers="req~asciidoc-standard-syntax~1", oft-needs="impl, utest"]
164+
==== AsciiDoc Specification Item Comment
165+
166+
A comment can be added to an AsciiDoc specification item by means of adding a delimited block to it which has the `.comment` role attribute.
167+
168+
.Example
169+
[example]
170+
----
171+
[.specitem, oft-sid="req~first-requirement~1", oft-needs="dsn"]
172+
== First Requirement
173+
174+
This is the specification item's description.
175+
176+
.Comment
177+
[.comment]
178+
On a side note, this requirement has emerged after years of experience with similar systems ...
179+
----
180+
181+
[.specitem, oft-sid="dsn~adoc-covers-list~1", oft-covers="req~asciidoc-standard-syntax~1", oft-needs="impl, utest"]
182+
==== AsciiDoc "Covers" list
183+
184+
The list of specification items covered by an AsciiDoc specification item can be set by means of assigning the `oft-covers` _named attribute_ to it. The value of the attribute is a comma separated list of `requirement-id`s.
185+
186+
.Example
187+
[example]
188+
----
189+
[.specitem, oft-sid="req~first-requirement~1", oft-needs="dsn"]
190+
== First Requirement
191+
192+
[.specitem, oft-sid="dsn~first-design-item~1", oft-needs="impl, utest", oft-covers="req~first-requirement~1"]
193+
== First Design Item
194+
----
195+
196+
.Rationale
197+
[.rationale]
198+
Refererencing the covered specification items by means of an attribute has the advantage of not being rendered by standard AsciiDoc processors and thus not cluttering the output with (meaningless) identifiers.
199+
200+
[.specitem, oft-sid="dsn~adoc-depends-list~1", oft-covers="req~asciidoc-standard-syntax~1", oft-needs="impl, utest"]
201+
==== AsciiDoc "Depends" list
202+
203+
The list of specification items that an AsciiDoc specification item depends on can be set by means of assigning the `oft-depends` _named attribute_ to it. The value of the attribute is a comma separated list of `requirement-id`s.
204+
205+
.Example
206+
[example]
207+
----
208+
[.specitem, oft-sid="req~first-requirement~1", oft-needs="dsn"]
209+
== First Requirement
210+
211+
This is the description of the first requirement.
212+
213+
[.specitem, oft-sid="req~second-requirement~1", oft-needs="dsn", oft-depends="req~first-requirement~1"]
214+
== Second Requirement
215+
216+
This is the description of the second requirement.
217+
----
218+
219+
.Rationale
220+
[.rationale]
221+
Referencing the depended upon specification items by means of an attribute has the advantage of not being rendered by standard AsciiDoc processors and thus not cluttering the output with (meaningless) identifiers.
222+
223+
[.specitem, oft-sid="dsn~adoc-needs-coverage-list~1", oft-covers="req~asciidoc-standard-syntax~1", oft-needs="impl, utest"]
224+
==== AsciiDoc "Needs" List
225+
226+
The list of artifact types that are needed to fully cover another specification item can be set by means of assigning the `oft-needs` _named attribute_ to it. The value of the attribute is a comma separated list of artifact types.
227+
228+
.Example
229+
[example]
230+
----
231+
[.specitem, oft-sid="dsn~first-design-item~1", oft-needs="impl, utest"]
232+
== First Design Item
233+
234+
This is the description of the first design item.
235+
----
236+
237+
238+
[.specitem, oft-sid="dsn~adoc-artifact-forwarding-notation~1", oft-covers="req~artifact-type-forwarding-in-asciidoc~1", oft-needs="impl, utest"]
239+
==== AsciiDoc Artifact Forwarding Notation
240+
241+
The AsciiDoc Importer supports forwarding required coverage from one artifact type to one or more different artifact types by means of adding an empty block with the following attribute list:
242+
243+
1. The `.specitem` role.
244+
2. The `oft-skipped` named attribute. The value of the attribute is artifact type being skipped,
245+
3. The `oft-needs` named attribute. The value of the attribute is a comma separated list of artifact types to forward to.
246+
4. The `oft-covered` named attribute. The value of the attribute is the specification item ID being covered.
247+
248+
.Example
249+
[example]
250+
----
251+
[.specitem, oft-skipped="dsn", oft-needs="impl, utest", oft-covered="req~first-requirement~1"]
252+
--
253+
--
254+
----
255+
256+
NOTE: The absence of the `oft-sid` attribute in this case is intentional.
257+
258+
== Design Decisions
259+
260+
=== Representation of Specification Item Properties in AsciiDoc
261+
262+
The AsciiDoc Importer uses AsciiDoc Element Attributes to explicitly mark up specification item properties.
263+
264+
Rationale:
265+
266+
* Only the specification item's content itself (description, rationale, comments) appears in the rendered document by default. This should also help with authoring specifications using languages other than English.
267+
* The specification item's properties can easily (and specifically) be retrieved using the existing AsciiDoctorJ framework's document query API
268+
269+
==== Why is this relevant?
270+
271+
The way that the specification item properties are represented in the AsciiDoc document determines the whole approach of retrieving and processing the information into Specifification Items. Changing this approach later on will be costly.
272+
273+
==== Alternatives considered
274+
275+
1. Follow the same Approach as the one taken for plain Markdown.
276+
+
277+
--
278+
This would mean to put all data into the content of the AsciiDoc blocks and use _well known_ labels like `Rationale` or `Needs` to mark up information.
279+
280+
Pros:
281+
282+
* AsciiDoc specifications are consistent with specifications written in plain Markdown
283+
* Might be able to reuse/copy code from the Markdown Importer
284+
285+
Cons:
286+
287+
* Specification item identifiers cluttering the rendered document, making it hard to read
288+
--
289+
290+
[.specitem, oft-sid="dsn~asciidoc-utf8-support~1", oft-covers="req~asciidoc-utf8-support~1"]
291+
=== AsciiDoc Parsing
292+
293+
The AsciiDoc Importer uses the https://github.com/asciidoctor/asciidoctorj[AsciiDoctorJ] library for parsing specification items from AsciiDoc files.
294+
295+
Rationale:
296+
297+
* Using an AsciiDoc parser library makes it easy to extract information contained in standard AsciiDoc document elements like _blocks, attributes, sections_ etc.
298+
* Given that the Importer itself is implemented in Java, using a Java-based parser library makes it very easy to integrate.
299+
* The https://asciidoctor.org[Asciidoctor project] provides a popular Ruby-based processing and publishing framework for AsciiDoc. It also provides Java bindings by means of the https://docs.asciidoctor.org/asciidoctorj/latest/[AsciiDoctorJ library].
300+
* _AsciiDoctorJ_ supports reading UTF-8 encoded AsciiDoc files.
301+
302+
==== Why is this relevant?
303+
304+
The Importer's main function is to extract information from AsciiDoc documents. Using an existing library/tool for processing AsciiDoc has the potential to save a lot of work with implementing and testing the basic parsing functionality which is not specific to OFT.
305+
306+
==== Alternatives considered
307+
308+
1. Use https://github.com/asciidoctor/asciidoctor.js[AsciiDoctorJS].
309+
+
310+
Cons:
311+
312+
* Requires running JavaScript from Java which is not as well supported as using a Java library.

0 commit comments

Comments
 (0)