diff --git a/src/main/java/com/github/packageurl/MalformedPackageURLException.java b/src/main/java/com/github/packageurl/MalformedPackageURLException.java index 775a131..a6d21d6 100644 --- a/src/main/java/com/github/packageurl/MalformedPackageURLException.java +++ b/src/main/java/com/github/packageurl/MalformedPackageURLException.java @@ -34,8 +34,6 @@ public class MalformedPackageURLException extends Exception { /** * Constructs a {@code MalformedPackageURLException} with no detail message. - * - * @since 1.0.0 */ public MalformedPackageURLException() {} @@ -44,7 +42,6 @@ public MalformedPackageURLException() {} * specified detail message. * * @param msg the detail message - * @since 1.0.0 */ public MalformedPackageURLException(@Nullable String msg) { super(msg); diff --git a/src/main/java/com/github/packageurl/PackageURL.java b/src/main/java/com/github/packageurl/PackageURL.java index a7adc5b..18db0f9 100644 --- a/src/main/java/com/github/packageurl/PackageURL.java +++ b/src/main/java/com/github/packageurl/PackageURL.java @@ -46,9 +46,9 @@ * *
* Components are separated by a specific character for unambiguous parsing. - * A purl must NOT contain a URL Authority i.e. there is no support for username, + * A purl must NOT contain a URL Authority, i.e., there is no support for username, * password, host and port components. A namespace segment may sometimes look - * like a host but its interpretation is specific to a type. + * like a host, but its interpretation is specific to a type. *
*SPEC: https://github.com/package-url/purl-spec
* @@ -112,7 +112,6 @@ public final class PackageURL implements Serializable { * @param purl a valid package URL string to parse * @throws MalformedPackageURLException if parsing fails * @throws NullPointerException if {@code purl} is {@code null} - * @since 1.0.0 */ public PackageURL(final String purl) throws MalformedPackageURLException { parse(requireNonNull(purl, "purl")); @@ -125,24 +124,22 @@ public PackageURL(final String purl) throws MalformedPackageURLException { * @param type the type of package (i.e. maven, npm, gem, etc) * @param name the name of the package * @throws MalformedPackageURLException if parsing fails - * @since 1.0.0 */ public PackageURL(final String type, final String name) throws MalformedPackageURLException { - this(type, null, name, null, null, null); + this(type, null, name, null, (MapUse {@link PackageURL#isCoordinatesEquals} instead.
* * @param purl the Package URL to evaluate @@ -869,8 +863,9 @@ public boolean isBaseEquals(final PackageURL purl) { /** * Evaluates if the specified Package URL has the same values up to, but excluding - * the qualifier (querystring). This includes equivalence of: scheme, type, namespace, - * name, and version, but excludes qualifier and subpath from evaluation. + * the qualifier (querystring). + * This includes equivalence of the scheme, type, namespace, name, and version, but excludes qualifier and subpath + * from evaluation. * * @param purl the Package URL to evaluate, not {@code null} * @return true if equivalence passes, false if not @@ -931,47 +926,195 @@ public int hashCode() { /** * Convenience constants that defines common Package-URL 'type's. - * - * @since 1.0.0 */ public static final class StandardTypes { + /** + * Arch Linux and other users of the libalpm/pacman package manager. + * + * @since 1.6.0 + */ public static final String ALPM = "alpm"; + /** + * APK-based packages. + * + * @since 1.6.0 + */ public static final String APK = "apk"; + /** + * Bitbucket-based packages. + */ public static final String BITBUCKET = "bitbucket"; + /** + * Bitnami-based packages. + * + * @since 1.6.0 + */ public static final String BITNAMI = "bitnami"; + /** + * Rust. + * + * @since 1.2.0 + */ public static final String CARGO = "cargo"; + /** + * CocoaPods. + * + * @since 1.6.0 + */ public static final String COCOAPODS = "cocoapods"; + /** + * Composer PHP packages. + */ public static final String COMPOSER = "composer"; + /** + * Conan C/C++ packages. + * + * @since 1.6.0 + */ public static final String CONAN = "conan"; + /** + * Conda packages. + * + * @since 1.6.0 + */ public static final String CONDA = "conda"; + /** + * CPAN Perl packages. + * + * @since 1.6.0 + */ public static final String CPAN = "cpan"; + /** + * CRAN R packages. + * + * @since 1.6.0 + */ public static final String CRAN = "cran"; + /** + * Debian, Debian derivatives, and Ubuntu packages. + * + * @since 1.6.0 + */ public static final String DEB = "deb"; + /** + * Docker images. + */ public static final String DOCKER = "docker"; + /** + * RubyGems. + */ public static final String GEM = "gem"; + /** + * Plain, generic packages that do not fit anywhere else, such as for "upstream-from-distro" packages. + */ public static final String GENERIC = "generic"; + /** + * GitHub-based packages. + */ public static final String GITHUB = "github"; + /** + * Go packages. + */ public static final String GOLANG = "golang"; + /** + * Haskell packages. + */ public static final String HACKAGE = "hackage"; + /** + * Hex packages. + * + * @since 1.6.0 + */ public static final String HEX = "hex"; + /** + * Hugging Face ML models. + * + * @since 1.6.0 + */ public static final String HUGGINGFACE = "huggingface"; + /** + * Lua packages installed with LuaRocks. + * + * @since 1.6.0 + */ public static final String LUAROCKS = "luarocks"; + /** + * Maven JARs and related artifacts. + */ public static final String MAVEN = "maven"; + /** + * MLflow ML models (Azure ML, Databricks, etc.). + * + * @since 1.6.0 + */ public static final String MLFLOW = "mlflow"; + /** + * Nixos packages + * + * @since 1.6.0 + */ public static final String NIX = "nix"; + /** + * Node NPM packages. + */ public static final String NPM = "npm"; + /** + * NuGet .NET packages. + */ public static final String NUGET = "nuget"; + /** + * All artifacts stored in registries that conform to the + * OCI Distribution Specification, including + * container images built by Docker and others. + * + * @since 1.6.0 + */ public static final String OCI = "oci"; + /** + * Dart and Flutter packages. + * + * @since 1.6.0 + */ public static final String PUB = "pub"; + /** + * Python packages. + */ public static final String PYPI = "pypi"; + /** + * QNX packages. + * + * @since 1.6.0 + */ public static final String QPKG = "qpkg"; + /** + * RPMs. + */ public static final String RPM = "rpm"; + /** + * ISO-IEC 19770-2 Software Identification (SWID) tags. + * + * @since 1.6.0 + */ public static final String SWID = "swid"; + /** + * Swift packages. + * + * @since 1.6.0 + */ public static final String SWIFT = "swift"; - + /** + * Debian, Debian derivatives, and Ubuntu packages. + * + * @deprecated use {@link #DEB} instead + */ @Deprecated public static final String DEBIAN = "deb"; - + /** + * Nixos packages. + * + * @since 1.1.0 + * @deprecated use {@link #NIX} instead + */ @Deprecated public static final String NIXPKGS = "nix"; diff --git a/src/main/java/com/github/packageurl/PackageURLBuilder.java b/src/main/java/com/github/packageurl/PackageURLBuilder.java index a82c7f8..ccdb8de 100644 --- a/src/main/java/com/github/packageurl/PackageURLBuilder.java +++ b/src/main/java/com/github/packageurl/PackageURLBuilder.java @@ -31,6 +31,8 @@ /** * A builder construct for Package-URL objects. + * + * @since 1.1.0 */ public final class PackageURLBuilder { private @Nullable String type = null; @@ -53,14 +55,25 @@ public static PackageURLBuilder aPackageURL() { return new PackageURLBuilder(); } + private static PackageURLBuilder toBuilder(PackageURL packageURL) { + return PackageURLBuilder.aPackageURL() + .withType(packageURL.getType()) + .withNamespace(packageURL.getNamespace()) + .withName(packageURL.getName()) + .withVersion(packageURL.getVersion()) + .withQualifiers(packageURL.getQualifiers()) + .withSubpath(packageURL.getSubpath()); + } + /** * Obtains a reference to a new builder object initialized with the existing {@link PackageURL} object. * * @param packageURL the existing Package URL object * @return a new builder object + * @since 1.6.0 */ public static PackageURLBuilder aPackageURL(final PackageURL packageURL) { - return packageURL.toBuilder(); + return toBuilder(packageURL); } /** @@ -69,9 +82,10 @@ public static PackageURLBuilder aPackageURL(final PackageURL packageURL) { * @param purl the existing Package URL string * @return a new builder object * @throws MalformedPackageURLException if an error occurs while parsing the input + * @since 1.6.0 */ public static PackageURLBuilder aPackageURL(final String purl) throws MalformedPackageURLException { - return new PackageURL(purl).toBuilder(); + return toBuilder(new PackageURL(purl)); } /** @@ -143,7 +157,7 @@ public PackageURLBuilder withSubpath(final @Nullable String subpath) { * If {@code value} is empty or {@code null}, the given qualifier is removed instead. * * - * @param key the package qualifier key, not {@code null} + * @param key the package qualifier key, not {@code null} * @param value the package qualifier value or {@code null} * @return a reference to the builder * @throws NullPointerException if {@code key} is {@code null} @@ -170,6 +184,7 @@ public PackageURLBuilder withQualifier(final String key, final @Nullable String * @param qualifiers the package qualifiers, or {@code null} * @return a reference to the builder * @see PackageURL#getQualifiers() + * @since 1.6.0 */ public PackageURLBuilder withQualifiers(final @Nullable MapJava implementation of the Package-URL Specification.
*https://github.com/package-url/purl-spec
diff --git a/src/main/java/com/github/packageurl/validator/PackageURL.java b/src/main/java/com/github/packageurl/validator/PackageURL.java index cfbb695..3da2095 100644 --- a/src/main/java/com/github/packageurl/validator/PackageURL.java +++ b/src/main/java/com/github/packageurl/validator/PackageURL.java @@ -37,11 +37,25 @@ @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = PackageURLConstraintValidator.class) public @interface PackageURL { - + /** + * Gets the error message. + * + * @return the error message + */ String message() default "The Package URL (purl) must be a valid URI and conform to https://github.com/package-url/purl-spec"; + /** + * Gets the validation groups. + * + * @return the validation groups + */ Class>[] groups() default {}; + /** + * Gets the payload for the constraint. + * + * @return the payload for the constraint + */ Class extends Payload>[] payload() default {}; } diff --git a/src/main/java/com/github/packageurl/validator/package-info.java b/src/main/java/com/github/packageurl/validator/package-info.java index 5cd633e..55302df 100644 --- a/src/main/java/com/github/packageurl/validator/package-info.java +++ b/src/main/java/com/github/packageurl/validator/package-info.java @@ -19,6 +19,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ + /** * This package contains a validator for Jakarta Validation. */ diff --git a/src/test/java/com/github/packageurl/PackageURLBuilderTest.java b/src/test/java/com/github/packageurl/PackageURLBuilderTest.java index 046184a..4dda8a9 100644 --- a/src/test/java/com/github/packageurl/PackageURLBuilderTest.java +++ b/src/test/java/com/github/packageurl/PackageURLBuilderTest.java @@ -176,12 +176,11 @@ void packageURLBuilderException6() { @Test void editBuilder1() throws MalformedPackageURLException { - PackageURL p = new PackageURL("pkg:generic/namespace/name@1.0.0?k=v#s"); - PackageURLBuilder b = p.toBuilder(); + PackageURLBuilder b = PackageURLBuilder.aPackageURL(p); assertBuilderMatch(p, b); - assertBuilderMatch(new PackageURL("pkg:generic/namespace/name@1.0.0#s"), b.withNoQualifiers()); + assertBuilderMatch(new PackageURL("pkg:generic/namespace/name@1.0.0#s"), b.withoutQualifiers()); b.withType("maven") .withNamespace("org.junit") .withName("junit5") diff --git a/src/test/java/com/github/packageurl/PackageURLTest.java b/src/test/java/com/github/packageurl/PackageURLTest.java index 9dd58ee..18fb345 100644 --- a/src/test/java/com/github/packageurl/PackageURLTest.java +++ b/src/test/java/com/github/packageurl/PackageURLTest.java @@ -29,6 +29,7 @@ import java.io.IOException; import java.util.Locale; +import java.util.Map; import java.util.stream.Stream; import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.AfterAll; @@ -62,7 +63,8 @@ static void resetLocale() { @Test void validPercentEncoding() throws MalformedPackageURLException { - PackageURL purl = new PackageURL("maven", "com.google.summit", "summit-ast", "2.2.0\n", null, null); + PackageURL purl = + new PackageURL("maven", "com.google.summit", "summit-ast", "2.2.0\n", (Map