Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implementation for externalReferences #17

Merged
merged 11 commits into from
Nov 25, 2021
5 changes: 5 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.

## unreleased

* Added
* Support for ExternalReferences in BOM and Component (via [#17])

[#17]: https://github.com/CycloneDX/cyclonedx-php-library/pull/17

## 1.0.3 - 2021-11-15

* Fixed
Expand Down
75 changes: 75 additions & 0 deletions src/Core/Enums/ExternalReferenceType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

declare(strict_types=1);

/*
* This file is part of CycloneDX PHP Library.
*
* Licensed 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
*
* http://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.
*
* SPDX-License-Identifier: Apache-2.0
* Copyright (c) Steve Springett. All Rights Reserved.
*/

namespace CycloneDX\Core\Enums;

/**
* See {@link https://cyclonedx.org/schema/bom/1.1 Schema 1.1} for `externalReferenceType`.
* See {@link https://cyclonedx.org/schema/bom/1.2 Schema 1.2} for `externalReferenceType`.
* See {@link https://cyclonedx.org/schema/bom/1.3 Schema 1.3} for `externalReferenceType`.
*
* @author jkowalleck
*/
abstract class ExternalReferenceType
{
/** Version Control System */
public const VCS = 'vcs';
/** Issue or defect tracking system, or an Application Lifecycle Management (ALM) system */
public const ISSUE_TRACKER = 'issue-tracker';
/** Website */
public const WEBSITE = 'website';
/** Security advisories */
public const ADVISORIES = 'advisories';
/** Bill-of-material document (CycloneDX, SPDX, SWID, etc) */
public const BOM = 'bom';
/** Mailing list or discussion group */
public const MAILING_LIST = 'mailing-list';
/** Social media account */
public const SOCIAL = 'social';
/** Real-time chat platform */
public const CHAT = 'chat';
/** Documentation, guides, or how-to instructions */
public const DOCUMENTATION = 'documentation';
/** Community or commercial support */
public const SUPPORT = 'support';
/*** Direct or repository download location.*/
public const DISTRIBUTION = 'distribution';
/** The URL to the license file. If a license URL has been defined in the licensenode, it should also be defined as an external reference for completeness. */
public const LICENSE = 'license';
/** Build-system specific meta file (i.e. pom.xml, package.json, .nuspec, etc). */
public const BUILD_META = 'build-meta';
/** URL to an automated build system. */
public const BUILD_SYSTEM = 'build-system';
/** Use this if no other types accurately describe the purpose of the external reference. */
public const OTHER = 'other';

/**
* @psalm-assert-if-true self::* $value
*/
public static function isValidValue(string $value): bool
{
$values = (new \ReflectionClass(self::class))->getConstants();

return \in_array($value, $values, true);
}
}
24 changes: 24 additions & 0 deletions src/Core/Models/Bom.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
namespace CycloneDX\Core\Models;

use CycloneDX\Core\Repositories\ComponentRepository;
use CycloneDX\Core\Repositories\ExternalReferenceRepository;
use DomainException;

/**
Expand Down Expand Up @@ -56,6 +57,14 @@ class Bom
*/
private $metaData;

/**
* Provides the ability to document external references related to the BOM or
* to the project the BOM describes.
*
* @var ExternalReferenceRepository|null
*/
private $externalReferenceRepository;

public function __construct(?ComponentRepository $componentRepository = null)
{
$this->setComponentRepository($componentRepository ?? new ComponentRepository());
Expand Down Expand Up @@ -124,4 +133,19 @@ public function setMetaData(?MetaData $metaData): self

return $this;
}

public function getExternalReferenceRepository(): ?ExternalReferenceRepository
{
return $this->externalReferenceRepository;
}

/**
* @return $this
*/
public function setExternalReferenceRepository(?ExternalReferenceRepository $externalReferenceRepository): self
{
$this->externalReferenceRepository = $externalReferenceRepository;

return $this;
}
}
24 changes: 24 additions & 0 deletions src/Core/Models/Component.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use CycloneDX\Core\Models\License\LicenseExpression;
use CycloneDX\Core\Repositories\BomRefRepository;
use CycloneDX\Core\Repositories\DisjunctiveLicenseRepository;
use CycloneDX\Core\Repositories\ExternalReferenceRepository;
use CycloneDX\Core\Repositories\HashRepository;
use DomainException;
use PackageUrl\PackageUrl;
Expand Down Expand Up @@ -137,6 +138,14 @@ class Component
*/
private $version;

/**
* Provides the ability to document external references related to the
* component or to the project the component describes.
*
* @var ExternalReferenceRepository|null
*/
private $externalReferenceRepository;

public function getBomRef(): BomRef
{
return $this->bomRef;
Expand Down Expand Up @@ -331,6 +340,21 @@ public function setDependenciesBomRefRepository(?BomRefRepository $dependenciesB
return $this;
}

public function getExternalReferenceRepository(): ?ExternalReferenceRepository
{
return $this->externalReferenceRepository;
}

/**
* @return $this
*/
public function setExternalReferenceRepository(?ExternalReferenceRepository $externalReferenceRepository): self
{
$this->externalReferenceRepository = $externalReferenceRepository;

return $this;
}

/**
* @psalm-assert Classification::* $type
*
Expand Down
150 changes: 150 additions & 0 deletions src/Core/Models/ExternalReference.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
<?php

declare(strict_types=1);

/*
* This file is part of CycloneDX PHP Library.
*
* Licensed 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
*
* http://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.
*
* SPDX-License-Identifier: Apache-2.0
* Copyright (c) Steve Springett. All Rights Reserved.
*/

namespace CycloneDX\Core\Models;

use CycloneDX\Core\Enums\ExternalReferenceType;
use CycloneDX\Core\Repositories\HashRepository;
use DomainException;

/**
* External references provide a way to document systems, sites, and information that may be relevant
* but which are not included with the BOM.
*
* @author jkowalleck
*/
class ExternalReference
{
/**
* Specifies the type of external reference. There are built-in types to describe common
* references. If a type does not exist for the reference being referred to, use the "other" type.
*
* @var string
* @psalm-var ExternalReferenceType::*
* @psalm-suppress PropertyNotSetInConstructor
*/
private $type;

/**
* The URL to the external reference.
*
* @var string
* @psalm-suppress PropertyNotSetInConstructor
*/
private $url;

/**
* An optional comment describing the external reference.
*
* @var string|null
*/
private $comment;

/**
* @var HashRepository|null
*/
private $hashRepository;

/**
* @psalm-return ExternalReferenceType::*
*/
public function getType(): string
{
return $this->type;
}

/**
* @param string $type A valid {@see \CycloneDX\Core\Enums\ExternalReferenceType}
* @psalm-assert ExternalReferenceType::* $type
*
* @throws DomainException if value is unknown
*
* @return $this
*/
public function setType(string $type): self
{
if (false === ExternalReferenceType::isValidValue($type)) {
throw new DomainException("Invalid type: $type");
}
/** @psalm-var ExternalReferenceType::* $type */
$this->type = $type;

return $this;
}

public function getUrl(): string
{
return $this->url;
}

/**
* @return $this
*/
public function setUrl(string $url): self
{
$this->url = $url;

return $this;
}

public function getComment(): ?string
{
return $this->comment;
}

/**
* @return $this
*/
public function setComment(?string $comment): self
{
$this->comment = $comment;

return $this;
}

public function getHashRepository(): ?HashRepository
{
return $this->hashRepository;
}

/**
* @return $this
*/
public function setHashRepository(?HashRepository $hashRepository): self
{
$this->hashRepository = $hashRepository;

return $this;
}

/**
* @psalm-assert ExternalReferenceType::* $type
*
* @throws DomainException if type is unknown
*/
public function __construct(string $type, string $url)
{
$this->setType($type);
$this->setUrl($url);
}
}
72 changes: 72 additions & 0 deletions src/Core/Repositories/ExternalReferenceRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

declare(strict_types=1);

/*
* This file is part of CycloneDX PHP Library.
*
* Licensed 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
*
* http://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.
*
* SPDX-License-Identifier: Apache-2.0
* Copyright (c) Steve Springett. All Rights Reserved.
*/

namespace CycloneDX\Core\Repositories;

use CycloneDX\Core\Models\ExternalReference;

/**
* @author jkowalleck
*/
class ExternalReferenceRepository implements \Countable
{
/**
* @var ExternalReference[]
* @psalm-var list<ExternalReference>
*/
private $externalReferences = [];

public function __construct(ExternalReference ...$externalReferences)
{
$this->addExternalReference(...$externalReferences);
}

/**
* @return $this
*/
public function addExternalReference(ExternalReference ...$externalReferences): self
{
foreach ($externalReferences as $externalReference) {
if (\in_array($externalReference, $this->externalReferences, true)) {
continue;
}
$this->externalReferences[] = $externalReference;
}

return $this;
}

/**
* @return ExternalReference[]
* @psalm-return list<ExternalReference>
*/
public function getExternalReferences(): array
{
return $this->externalReferences;
}

public function count(): int
{
return \count($this->externalReferences);
}
}
Loading