|
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