1313import org .apache .commons .lang3 .StringUtils ;
1414import org .apache .maven .model .MailingList ;
1515import org .apache .maven .model .Model ;
16+ import org .cyclonedx .Format ;
1617import org .cyclonedx .Version ;
1718import org .cyclonedx .exception .GeneratorException ;
1819import org .cyclonedx .generators .BomGeneratorFactory ;
@@ -73,10 +74,7 @@ public class CycloneDxSbomGenerator {
7374
7475 private static final String CLASSIFIER_CYCLONEDX = "cyclonedx" ;
7576 private static final String FORMAT_ALL = "all" ;
76- private static final String FORMAT_JSON = "json" ;
77- private static final String FORMAT_XML = "xml" ;
78- private static final String DEFAULT_FORMAT = FORMAT_JSON ;
79- private static final List <String > SUPPORTED_FORMATS = List .of (FORMAT_JSON , FORMAT_XML );
77+ private static final String DEFAULT_FORMAT = "json" ;
8078
8179 public static CycloneDxSbomGenerator newInstance () {
8280 return new CycloneDxSbomGenerator ();
@@ -138,37 +136,57 @@ public CycloneDxSbomGenerator setIncludeLicenseText(boolean includeLicenseText)
138136 return this ;
139137 }
140138
139+ public List <String > generateText () {
140+ final Bom bom = createSbom ();
141+ if (FORMAT_ALL .equals (format )) {
142+ Format [] formats = Format .values ();
143+ final List <String > result = new ArrayList <>(formats .length );
144+ for (Format format : formats ) {
145+ result .add (formatSbom (bom , format .getExtension ()));
146+ }
147+ return result ;
148+ }
149+ return List .of (formatSbom (bom , format ));
150+ }
151+
141152 public List <SbomResult > generate () {
142- ensureNotGenerated ();
143- Objects .requireNonNull (manifest , "Manifest is null" );
144153 if (outputFile == null && outputDir == null ) {
145154 throw new IllegalArgumentException ("Either outputDir or outputFile must be provided" );
146155 }
147- generated = true ;
156+ final Bom bom = createSbom () ;
148157
149- var bom = new Bom ();
150- bom .setMetadata (new Metadata ());
151- addToolInfo (bom );
152-
153- addApplicationComponent (bom , manifest .getMainComponent ());
154- for (var c : manifest .getComponents ()) {
155- addComponent (bom , c );
156- }
157158 if (FORMAT_ALL .equalsIgnoreCase (format )) {
158159 if (outputFile != null ) {
159160 throw new IllegalArgumentException ("Can't use output file " + outputFile + " with format '"
160161 + FORMAT_ALL + "', since it implies generating multiple files" );
161162 }
162- final List <SbomResult > result = new ArrayList <>(SUPPORTED_FORMATS .size ());
163- for (String format : SUPPORTED_FORMATS ) {
164- result .add (persistSbom (bom , getOutputFile (format ), format ));
163+ Format [] formats = Format .values ();
164+ final List <SbomResult > result = new ArrayList <>(formats .length );
165+ for (Format format : formats ) {
166+ result .add (persistSbom (bom , getOutputFile (format .getExtension ()), format .getExtension ()));
165167 }
166168 return result ;
167169 }
168170 var outputFile = getOutputFile (format == null ? DEFAULT_FORMAT : format );
169171 return List .of (persistSbom (bom , outputFile , getFormat (outputFile )));
170172 }
171173
174+ private Bom createSbom () {
175+ ensureNotGenerated ();
176+ Objects .requireNonNull (manifest , "Manifest is null" );
177+ generated = true ;
178+
179+ var bom = new Bom ();
180+ bom .setMetadata (new Metadata ());
181+ addToolInfo (bom );
182+
183+ addApplicationComponent (bom , manifest .getMainComponent ());
184+ for (var c : manifest .getComponents ()) {
185+ addComponent (bom , c );
186+ }
187+ return bom ;
188+ }
189+
172190 private void addComponent (Bom bom , ApplicationComponent component ) {
173191 final org .cyclonedx .model .Component c = getComponent (component );
174192 bom .addComponent (c );
@@ -421,25 +439,7 @@ private static List<ArtifactCoords> sortAlphabetically(Collection<ArtifactCoords
421439 }
422440
423441 private SbomResult persistSbom (Bom bom , Path sbomFile , String format ) {
424-
425- var specVersion = getSchemaVersion ();
426- final String sbomContent ;
427- if (format .equalsIgnoreCase ("json" )) {
428- try {
429- sbomContent = BomGeneratorFactory .createJson (specVersion , bom ).toJsonString ();
430- } catch (Throwable e ) {
431- throw new RuntimeException ("Failed to generate an SBOM in JSON format" , e );
432- }
433- } else if (format .equalsIgnoreCase ("xml" )) {
434- try {
435- sbomContent = BomGeneratorFactory .createXml (specVersion , bom ).toXmlString ();
436- } catch (GeneratorException e ) {
437- throw new RuntimeException ("Failed to generate an SBOM in XML format" , e );
438- }
439- } else {
440- throw new RuntimeException (
441- "Unsupported SBOM artifact type " + format + ", supported types are json and xml" );
442- }
442+ final String sbomContent = formatSbom (bom , format );
443443
444444 var outputDir = sbomFile .getParent ();
445445 if (outputDir != null ) {
@@ -462,6 +462,33 @@ private SbomResult persistSbom(Bom bom, Path sbomFile, String format) {
462462 manifest .getRunnerPath ());
463463 }
464464
465+ private String formatSbom (Bom bom , String format ) {
466+ var specVersion = getSchemaVersion ();
467+ final String sbomContent ;
468+ if (format .equalsIgnoreCase ("json" )) {
469+ try {
470+ sbomContent = BomGeneratorFactory .createJson (specVersion , bom ).toJsonString ();
471+ } catch (Throwable e ) {
472+ throw new RuntimeException ("Failed to generate an SBOM in JSON format" , e );
473+ }
474+ } else if (format .equalsIgnoreCase ("xml" )) {
475+ try {
476+ sbomContent = BomGeneratorFactory .createXml (specVersion , bom ).toXmlString ();
477+ } catch (GeneratorException e ) {
478+ throw new RuntimeException ("Failed to generate an SBOM in XML format" , e );
479+ }
480+ } else {
481+ var msg = new StringBuilder ("Unsupported SBOM format " ).append (format );
482+ var supportedFormats = Format .values ();
483+ msg .append (". Supported formats are " ).append (supportedFormats [0 ].getExtension ());
484+ for (int i = 1 ; i < supportedFormats .length ; i ++) {
485+ msg .append (", " ).append (supportedFormats [i ].getExtension ());
486+ }
487+ throw new IllegalArgumentException (msg .toString ());
488+ }
489+ return sbomContent ;
490+ }
491+
465492 private Path getOutputFile (String defaultFormat ) {
466493 if (outputFile == null ) {
467494 var fileName = toSbomFileName (manifest .getRunnerPath ().getFileName ().toString (), defaultFormat );
0 commit comments