<?xml version="1.0"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      https://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<project name="component-test" default="antunit">

  <import file="shared.xml" />

  <target name="testComponentNameIsRequired">
    <au:expectfailure expectedMessage="component name is required"
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:componentbom outputdirectory="${output}" format="xml"
                        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <component/>
      </cdx:componentbom>
    </au:expectfailure>
  </target>

  <target name="testComponentsDetectCircularReferences">
    <au:expectfailure expectedMessage="This data type contains a circular reference"
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:componentbom outputdirectory="${output}" format="xml"
                        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <component name="level1" id="top">
          <component name="level2">
            <component refid="top"/>
          </component>
        </component>
      </cdx:componentbom>
    </au:expectfailure>
  </target>

  <target name="testComponentBomRefsMustBeUnique">
    <au:expectfailure expectedMessage="BOM contains multiple components with bom-ref 1"
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:componentbom outputdirectory="${output}" format="xml"
                        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <component name="c1" bomref="1"/>
        <additionalComponent name="c2" bomref="1"/>
      </cdx:componentbom>
    </au:expectfailure>
    <au:expectfailure expectedMessage="BOM contains multiple components with bom-ref 1"
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:componentbom outputdirectory="${output}" format="xml"
                        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <component name="c1" bomref="1">
          <component name="c2" bomref="1"/>
        </component>
      </cdx:componentbom>
    </au:expectfailure>
  </target>

  <target name="testMinimalComponentData">
    <cdx:componentbom outputdirectory="${output}" format="xml"
                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component name="testname"/>
    </cdx:componentbom>
    <xmlproperty file="${output}/bom.xml"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.name"
        value="testname"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component(type)"
        value="library"/>
  </target>

  <target name="testComponentTypeCanBeSet">
    <cdx:componentbom outputdirectory="${output}" format="xml"
                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component name="testname" type="APPLICATION"/>
    </cdx:componentbom>
    <xmlproperty file="${output}/bom.xml"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component(type)"
        value="application"/>
  </target>

  <target name="testComponentTypeCanBeSetInLowerCase">
    <cdx:componentbom outputdirectory="${output}" format="xml"
                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component name="testname" type="application"/>
    </cdx:componentbom>
    <xmlproperty file="${output}/bom.xml"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component(type)"
        value="application"/>
  </target>

  <target name="testCalculatesPurlAndBomRef">
    <cdx:componentbom outputdirectory="${output}" format="xml"
                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component name="testname" group="org.example" version="1.0"/>
    </cdx:componentbom>
    <xmlproperty file="${output}/bom.xml"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.purl"
        value="pkg:maven/org.example/testname@1.0?type=jar"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component(bom-ref)"
        value="pkg:maven/org.example/testname@1.0?type=jar"/>
  </target>

  <target name="testPurlAndBomRefCanBeSet">
    <cdx:componentbom outputdirectory="${output}" format="xml"
                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component name="testname" group="org.example" version="1.0"
                 purl="foo" bomRef="bar"/>
    </cdx:componentbom>
    <xmlproperty file="${output}/bom.xml"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.purl"
        value="foo"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component(bom-ref)"
        value="bar"/>
  </target>

  <target name="testScopeIsProhibitedForMainComponent">
    <au:expectfailure expectedMessage="scope must not be set for the main bom component"
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:componentbom outputdirectory="${output}" format="xml"
                        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <component name="foo" scope="optional"/>
      </cdx:componentbom>
    </au:expectfailure>
  </target>

  <target name="testIsExternalTrueIsProhibitedForMainComponent">
    <au:expectfailure expectedMessage="isExternal can not be true for the main bom component"
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:componentbom outputdirectory="${output}" format="xml"
                        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <component name="foo" isExternal="true"/>
      </cdx:componentbom>
    </au:expectfailure>
  </target>

  <target name="testIsExternalFalseIsPermittedForMainComponent">
    <cdx:componentbom outputdirectory="${output}" format="xml"
                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component name="foo" isExternal="false"/>
    </cdx:componentbom>
  </target>

  <target name="testScopeCanBeSetForAdditionalComponent">
    <cdx:componentbom outputdirectory="${output}" format="xml"
                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component name="foo"/>
      <additionalComponent name="bar" scope="optional"/>
    </cdx:componentbom>
    <xmlproperty file="${output}/bom.xml"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.components.component.scope"
        value="optional"/>
  </target>

  <target name="testScopeCanBeSetInUpperCaseForAdditionalComponent">
    <cdx:componentbom outputdirectory="${output}" format="xml"
                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component name="foo"/>
      <additionalComponent name="bar" scope="OPTIONAL"/>
    </cdx:componentbom>
    <xmlproperty file="${output}/bom.xml"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.components.component.scope"
        value="optional"/>
  </target>

  <target name="testIsExternalCanBeSetForAdditionalComponent">
    <cdx:componentbom outputdirectory="${output}" format="xml"
                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component name="foo"/>
      <additionalComponent name="bar" isExternal="true"/>
    </cdx:componentbom>
  </target>

  <target name="createMaximalComponentData" depends="setUp">
    <checksum property="ant.file.sha256" file="${ant.file}" algorithm="SHA-256"/>
    <cdx:componentbom outputdirectory="${output}" format="all"
                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component
          name="testname"
          group="org.example"
          version="1.0"
          description="My Test Library"
          publisher="test publisher"
          copyright="Copyright 2026 ACME Com"
          mimeType="text/plain"
          >
        <file file="${ant.file}"/>
        <manufacturer name="Example">
          <url url="https://example.org/"/>
        </manufacturer>
        <supplier name="Example 2">
          <url url="https://example.com/"/>
        </supplier>
        <license name="My License"/>
        <externalReference type="WEBSITE" url="https://example.com/"/>
        <component name="other-test" group="org.example" version="1.1"
                   unknownDependencies="true"/>
        <author name="Author" email="author@example.org"/>
        <tag>label</tag>
        <property name="foo" value="bar"/>
        <dependency bomRef="some-dependency"/>
      </component>
      <additionalComponent name="dep" bomRef="some-dependency"/>
    </cdx:componentbom>
  </target>

  <target name="testMaximalComponentData" depends="createMaximalComponentData">
    <xmlproperty file="${output}/bom.xml"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.name"
        value="testname"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component(type)"
        value="library"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.group"
        value="org.example"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.version"
        value="1.0"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.publisher"
        value="test publisher"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.copyright"
        value="Copyright 2026 ACME Com"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component(mime-type)"
        value="text/plain"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.purl"
        value="pkg:maven/org.example/testname@1.0?type=jar"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component(bom-ref)"
        value="pkg:maven/org.example/testname@1.0?type=jar"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.description"
        value="My Test Library"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.authors.author.name"
        value="Author"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.authors.author.email"
        value="author@example.org"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.manufacturer.name"
        value="Example"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.manufacturer.url"
        value="https://example.org/"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.supplier.name"
        value="Example 2"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.supplier.url"
        value="https://example.com/"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.licenses.license.name"
        value="My License"/>
    <au:assertResourceContains
        xmlns:au="antlib:org.apache.ant.antunit"
        resource="${output}/bom.xml"
        value='&lt;hash alg="SHA-256"&gt;${ant.file.sha256}&lt;/hash&gt;'/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.tags.tag"
        value="label"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.properties.property(name)"
        value="foo"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.properties.property"
        value="bar"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.components.component.name"
        value="other-test"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.components.component(type)"
        value="library"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.components.component.group"
        value="org.example"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.components.component.version"
        value="1.1"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.components.component.purl"
        value="pkg:maven/org.example/other-test@1.1?type=jar"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.components.component(bom-ref)"
        value="pkg:maven/org.example/other-test@1.1?type=jar"/>
    <au:assertResourceContains
        xmlns:au="antlib:org.apache.ant.antunit"
        resource="${output}/bom.xml"
        value='&lt;url&gt;https://example.com/&lt;/url&gt;'/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.dependencies.dependency(ref)"
        value="pkg:maven/org.example/testname@1.0?type=jar,some-dependency"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.dependencies.dependency.dependency(ref)"
        value="some-dependency"/>
  </target>

  <target name="testSupplierIsNotCopiedToManufacturerByDefault">
    <cdx:componentbom outputdirectory="${output}" format="xml"
                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component name="foo">
        <supplier name="Example">
          <url url="https://example.com/"/>
        </supplier>
      </component>
    </cdx:componentbom>
    <xmlproperty file="${output}/bom.xml"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.supplier.name"
        value="Example"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.supplier.url"
        value="https://example.com/"/>
    <au:fail message="expected bom.metadata.components.component.manufacturer.name to not be set"
             xmlns:au="antlib:org.apache.ant.antunit">
      <not>
        <isset property="bom.metadata.component.manufacturer.name"/>
      </not>
    </au:fail>
  </target>

  <target name="testSupplierIsCopiedToManufacturerWhenRequested">
    <cdx:componentbom outputdirectory="${output}" format="xml"
                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component name="foo" supplierIsManufacturer="true">
        <supplier name="Example">
          <url url="https://example.com/"/>
        </supplier>
      </component>
    </cdx:componentbom>
    <xmlproperty file="${output}/bom.xml"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.manufacturer.name"
        value="Example"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.manufacturer.url"
        value="https://example.com/"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.supplier.name"
        value="Example"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.supplier.url"
        value="https://example.com/"/>
  </target>

  <target name="testSupplierIsManufacturerMustNotBeTrueWhenSupplierIsPresent">
    <au:expectfailure expectedMessage="component with manufacturer can't use supplier as manufacturer"
                      xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:componentbom outputdirectory="${output}" format="xml"
                        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <component name="foo" supplierIsManufacturer="true">
          <manufacturer name="Example">
            <url url="https://example.com/"/>
          </manufacturer>
          <supplier name="Example 2">
            <url url="https://example.org/"/>
          </supplier>
        </component>
      </cdx:componentbom>
    </au:expectfailure>
  </target>

  <target name="testLicenseWorksAsReference">
    <cdx:license
        licenseId="Apache-2.0"
        id="apache-2"
        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <url url="https://www.apache.org/licenses/LICENSE-2.0.txt"/>
    </cdx:license>
    <cdx:componentbom outputdirectory="${output}" format="xml"
                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component name="testname">
        <license refid="apache-2"/>
      </component>
    </cdx:componentbom>
    <xmlproperty file="${output}/bom.xml"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.licenses.license.id"
        value="Apache-2.0"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.licenses.license.url"
        value="https://www.apache.org/licenses/LICENSE-2.0.txt"/>
  </target>

  <target name="testExternalReferenceWorksNestedIntoSet">
    <cdx:componentbom outputdirectory="${output}" format="xml"
                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component name="testname">
        <externalreferenceset>
          <externalReference
              type="VCS"
              url="https://github.com/apache/ant-antlibs-cyclonedx"/>
        </externalreferenceset>
      </component>
    </cdx:componentbom>
    <xmlproperty file="${output}/bom.xml"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.externalReferences.reference(type)"
        value="vcs"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.externalReferences.reference.url"
        value="https://github.com/apache/ant-antlibs-cyclonedx"/>
  </target>

  <target name="testExternalReferenceSetWorksAsReference">
    <cdx:externalreferenceset
        xmlns:cdx="antlib:org.apache.ant.cyclonedx"
        id="test-reference">
      <externalReference
          type="VCS"
          url="https://github.com/apache/ant-antlibs-cyclonedx"/>
    </cdx:externalreferenceset>
    <cdx:componentbom outputdirectory="${output}" format="xml"
                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component name="testname">
        <externalreferenceset refid="test-reference"/>
      </component>
    </cdx:componentbom>
    <xmlproperty file="${output}/bom.xml"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.externalReferences.reference(type)"
        value="vcs"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.externalReferences.reference.url"
        value="https://github.com/apache/ant-antlibs-cyclonedx"/>
  </target>

  <target name="testDependenciesAreEmptyByDefault">
    <cdx:componentbom outputdirectory="${output}" format="json"
                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component name="foo" bomRef="foo"/>
    </cdx:componentbom>
    <au:assertResourceContains
        xmlns:au="antlib:org.apache.ant.antunit"
        resource="${output}/bom.json"
        value='"dependsOn" : [ ]'/>
  </target>

  <target name="testDependenciesAreNotPresentIfUnknown">
    <cdx:componentbom outputdirectory="${output}" format="json"
                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component name="foo" bomRef="foo" unknownDependencies="true"/>
    </cdx:componentbom>
    <au:assertResourceContains
        xmlns:au="antlib:org.apache.ant.antunit"
        resource="${output}/bom.json"
        value='"dependencies" : [ ]'/>
  </target>

  <target name="testDependenciesRequireEitherBomRefOrComponentRef">
    <au:expectfailure expectedMessage="bomRef or componentRef is required"
                      xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:componentbom outputdirectory="${output}" format="json"
                        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <component name="foo" bomRef="foo">
          <dependency/>
        </component>
      </cdx:componentbom>
    </au:expectfailure>
  </target>

  <target name="testDependencyBomRefAndComponentRefAreExclusive">
    <cdx:component name="bar" bomRef="bar" id="bar"
                   xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    <au:expectfailure expectedMessage="only one of bomRef and componentRef are permitted"
                      xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:componentbom outputdirectory="${output}" format="json"
                        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <component name="foo" bomRef="foo">
          <dependency bomRef="bar" componentRef="bar"/>
        </component>
      </cdx:componentbom>
    </au:expectfailure>
  </target>

  <target name="testDependencyComponentRefMustExist">
    <cdx:component name="bar" bomRef="bar"
                   xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    <au:expectfailure expectedMessage="Reference bar not found."
                      xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:componentbom outputdirectory="${output}" format="json"
                        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <component name="foo" bomRef="foo">
          <dependency componentRef="bar"/>
        </component>
      </cdx:componentbom>
    </au:expectfailure>
  </target>

  <target name="testDependencyComponentRefMustPointToComponent">
    <cdx:license
        licenseId="Apache-2.0"
        id="bar"
        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <url url="https://www.apache.org/licenses/LICENSE-2.0.txt"/>
    </cdx:license>
    <au:expectfailure expectedMessage="componentRef 'bar' doesn't refer to a component"
                      xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:componentbom outputdirectory="${output}" format="json"
                        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <component name="foo" bomRef="foo">
          <dependency componentRef="bar"/>
        </component>
      </cdx:componentbom>
    </au:expectfailure>
  </target>

  <target name="testDependencyComponentRefMustPointToComponentWithBomRef">
    <cdx:component name="bar" id="bar"
                   xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    <au:expectfailure expectedMessage="component with id 'bar' doesn't provide a bomRef"
                      xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:componentbom outputdirectory="${output}" format="json"
                        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <component name="foo" bomRef="foo">
          <dependency componentRef="bar"/>
        </component>
      </cdx:componentbom>
    </au:expectfailure>
  </target>

  <target name="testDependeesRequireABomRef">
    <au:expectfailure expectedMessage="components without bomRef cannot have dependencies"
                      xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:componentbom outputdirectory="${output}" format="json"
                        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <component name="foo">
          <dependency bomRef="bar"/>
        </component>
      </cdx:componentbom>
    </au:expectfailure>
  </target>

  <target
      name="testComponentWithRefIdDoesntAllowOtherAttributes">
    <cdx:component name="foo" bomRef="foo" id="foo"
                   xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    <au:expectfailure
        expectedMessage='You must not specify more than one attribute when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component name="foo" refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify more than one attribute when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component type="library" refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify more than one attribute when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component group="foo" refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify more than one attribute when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component version="1.0" refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify more than one attribute when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component purl="foo" refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify more than one attribute when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component bomRef="foo" refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify more than one attribute when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component scope="optional" refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify more than one attribute when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component isExternal="false" refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify more than one attribute when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component description="foo" refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify more than one attribute when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component publisher="foo" refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify more than one attribute when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component copyright="foo" refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify more than one attribute when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component mimetype="foo" refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify more than one attribute when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component unknownDependencies="false" refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify more than one attribute when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component supplierIsManufacturer="false" refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    </au:expectfailure>
  </target>

  <target
      name="testComponentWithRefIdDoesntAllowNestedChildren">
    <cdx:component name="foo" bomRef="foo" id="foo"
                   xmlns:cdx="antlib:org.apache.ant.cyclonedx"/>
    <au:expectfailure
        expectedMessage='You must not specify nested elements when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <file file="${ant.file}"/>
      </cdx:component>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify nested elements when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <manufacturer/>
      </cdx:component>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify nested elements when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <supplier/>
      </cdx:component>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify nested elements when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <author/>
      </cdx:component>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify nested elements when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <tag/>
      </cdx:component>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify nested elements when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <property/>
      </cdx:component>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify nested elements when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <license/>
      </cdx:component>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify nested elements when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <externalReference/>
      </cdx:component>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify nested elements when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <externalreferenceset/>
      </cdx:component>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify nested elements when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <dependency/>
      </cdx:component>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify nested elements when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <component/>
      </cdx:component>
    </au:expectfailure>
    <au:expectfailure
        expectedMessage='You must not specify nested elements when using refid'
        xmlns:au="antlib:org.apache.ant.antunit">
      <cdx:component refid="foo"
                     xmlns:cdx="antlib:org.apache.ant.cyclonedx">
        <sbomLink/>
      </cdx:component>
    </au:expectfailure>
  </target>

  <target name="testSbomLinkUsesDataFromLinkedSbom" depends="createMaximalComponentData">
    <cdx:componentbom
        bomName="merged"
        outputdirectory="${output}"
        format="xml"
        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component>
        <sbomLink>
          <file file="${output}/bom.json"/>
        </sbomLink>
      </component>
    </cdx:componentbom>
    <xmlproperty file="${output}/merged.xml"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.name"
        value="testname"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component(type)"
        value="library"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.group"
        value="org.example"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.version"
        value="1.0"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.publisher"
        value="test publisher"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.copyright"
        value="Copyright 2026 ACME Com"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component(mime-type)"
        value="text/plain"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.purl"
        value="pkg:maven/org.example/testname@1.0?type=jar"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component(bom-ref)"
        value="pkg:maven/org.example/testname@1.0?type=jar"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.description"
        value="My Test Library"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.authors.author.name"
        value="Author"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.authors.author.email"
        value="author@example.org"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.manufacturer.name"
        value="Example"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.manufacturer.url"
        value="https://example.org/"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.supplier.name"
        value="Example 2"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.supplier.url"
        value="https://example.com/"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.licenses.license.name"
        value="My License"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.tags.tag"
        value="label"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.properties.property(name)"
        value="foo"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.properties.property"
        value="bar"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.components.component.name"
        value="other-test"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.components.component(type)"
        value="library"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.components.component.group"
        value="org.example"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.components.component.version"
        value="1.1"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.components.component.purl"
        value="pkg:maven/org.example/other-test@1.1?type=jar"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.components.component(bom-ref)"
        value="pkg:maven/org.example/other-test@1.1?type=jar"/>
    <au:assertResourceContains
        xmlns:au="antlib:org.apache.ant.antunit"
        resource="${output}/bom.xml"
        value='&lt;url&gt;https://example.com/&lt;/url&gt;'/>
    <!-- some-dependency is not here as we explicitly set the its
         dependencies to unknown. We don't want top open the can of
         transitive dependency worms -->
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.dependencies.dependency(ref)"
        value="pkg:maven/org.example/testname@1.0?type=jar"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.dependencies.dependency.dependency(ref)"
        value="some-dependency"/>
    <!-- ensure hashes are not taken from the linked SBOM -->
    <au:assertResourceDoesntContain
        xmlns:au="antlib:org.apache.ant.antunit"
        resource="${output}/merged.xml"
        value='&lt;hash alg="SHA-256"&gt;${ant.file.sha256}&lt;/hash&gt;'/>
  </target>

  <target
      name="testSbomLinkDoesNotUseLinkedManufacturerIfSupplierIsManufacturer"
      depends="createMaximalComponentData">
    <cdx:componentbom
        bomName="merged"
        outputdirectory="${output}"
        format="xml"
        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component supplierIsManufacturer="true">
        <sbomLink>
          <file file="${output}/bom.json"/>
        </sbomLink>
      </component>
    </cdx:componentbom>
    <xmlproperty file="${output}/merged.xml"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.manufacturer.name"
        value="Example 2"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.manufacturer.url"
        value="https://example.com/"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.supplier.name"
        value="Example 2"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.supplier.url"
        value="https://example.com/"/>
  </target>

  <target
      name="testDataFromLinkedSbomCanBeOverwrittenOrMerged"
      depends="createMaximalComponentData">
    <cdx:componentbom
        bomName="merged"
        outputdirectory="${output}"
        format="xml"
        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component
          type="APPLICATION"
          name="testname2"
          group="org.example2"
          version="2.0"
          description="My Second Test Library"
          publisher="test2 publisher"
          copyright="Copyright 2026 ACME Corp"
          mimeType="text/xml"
          >
        <file file="${ant.file}"/>
        <manufacturer name="Example 3">
          <url url="https://example.org/3"/>
        </manufacturer>
        <supplier name="Example 4">
          <url url="https://example.com/4"/>
        </supplier>
        <license name="My Other License"/>
        <externalReference type="WEBSITE" url="https://example.org/site"/>
        <component name="yet-another-test" group="org.example2"
                   version="1.2" unknownDependencies="true"/>
        <author name="Author2" email="author2@example.org"/>
        <tag>label2</tag>
        <property name="xyzzy" value="baz"/>
        <dependency bomRef="my-own-dependency"/>
        <sbomLink>
          <file file="${output}/bom.json"/>
        </sbomLink>
      </component>
      <additionalComponent name="my-own-dependency" bomRef="my-own-dependency"/>
    </cdx:componentbom>
    <xmlproperty file="${output}/merged.xml"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.name"
        value="testname2"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component(type)"
        value="application"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.group"
        value="org.example2"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.version"
        value="2.0"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.publisher"
        value="test2 publisher"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.copyright"
        value="Copyright 2026 ACME Corp"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component(mime-type)"
        value="text/xml"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.purl"
        value="pkg:maven/org.example2/testname2@2.0?type=jar"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component(bom-ref)"
        value="pkg:maven/org.example2/testname2@2.0?type=jar"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.description"
        value="My Second Test Library"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.authors.author.name"
        value="Author2"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.authors.author.email"
        value="author2@example.org"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.manufacturer.name"
        value="Example 3"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.manufacturer.url"
        value="https://example.org/3"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.supplier.name"
        value="Example 4"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.supplier.url"
        value="https://example.com/4"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.licenses.license.name"
        value="My Other License"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.tags.tag"
        value="label,label2"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.properties.property(name)"
        value="xyzzy"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.properties.property"
        value="baz"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.components.component.name"
        value="yet-another-test"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.components.component(type)"
        value="library"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.components.component.group"
        value="org.example2"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.components.component.version"
        value="1.2"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.components.component.purl"
        value="pkg:maven/org.example2/yet-another-test@1.2?type=jar"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.metadata.component.components.component(bom-ref)"
        value="pkg:maven/org.example2/yet-another-test@1.2?type=jar"/>
    <au:assertResourceContains
        xmlns:au="antlib:org.apache.ant.antunit"
        resource="${output}/merged.xml"
        value='&lt;url&gt;https://example.org/site&lt;/url&gt;'/>
    <au:assertResourceContains
        xmlns:au="antlib:org.apache.ant.antunit"
        resource="${output}/merged.xml"
        value='&lt;hash alg="SHA-256"&gt;${ant.file.sha256}&lt;/hash&gt;'/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.dependencies.dependency(ref)"
        value="pkg:maven/org.example2/testname2@2.0?type=jar,my-own-dependency"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.dependencies.dependency.dependency(ref)"
        value="my-own-dependency"/>
  </target>

  <target name="testReMappingOfLinkedDependencies">
    <cdx:componentbom
        outputdirectory="${output}"
        format="json"
        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component
          name="testname"
          group="org.example"
          version="1.0">
        <dependency bomRef="pkg:maven/commons-codec/commons-codec@1.21.0?type=jar"/>
      </component>
      <additionalComponent
          name="commons-codec"
          group="commons-codec"
          version="1.21.0"/>
    </cdx:componentbom>
    <cdx:componentbom
        outputdirectory="${output}"
        bomName="merged"
        format="xml"
        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
      <component>
        <sbomLink>
          <file file="${output}/bom.json"/>
        </sbomLink>
      </component>
      <additionalComponent
          name="commons-codec"
          group="commons-codec"
          version="1.22.0"/>
    </cdx:componentbom>
    <xmlproperty file="${output}/merged.xml"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.dependencies.dependency(ref)"
        value="pkg:maven/org.example/testname@1.0?type=jar,pkg:maven/commons-codec/commons-codec@1.22.0?type=jar"/>
    <au:assertPropertyEquals
        xmlns:au="antlib:org.apache.ant.antunit"
        name="bom.dependencies.dependency.dependency(ref)"
        value="pkg:maven/commons-codec/commons-codec@1.22.0?type=jar"/>
  </target>
</project>
