From bbabe5415fd7995b15e49b53d8ba49e1f8a9e1ba Mon Sep 17 00:00:00 2001 From: ruhan Date: Fri, 12 Dec 2025 10:22:03 +0700 Subject: [PATCH] Upgrade Atlas to 1.1.9 and add NPM model classes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Upgrade org.commonjava.atlas from 1.1.4 to 1.1.9 for bug fixes and improvements - Add NPM package model classes (13 models + 1 content class) from indy-promote-service - Add PathUtils utility class for path normalization - All model classes are pure POJOs without API documentation annotations These NPM models are now shared in indy-model for reuse across services, eliminating duplication and providing a single source of truth for NPM metadata. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- .../indy/pkg/npm/content/PackagePath.java | 157 ++++++ .../commonjava/indy/pkg/npm/model/Bugs.java | 53 ++ .../indy/pkg/npm/model/Commitplease.java | 67 +++ .../indy/pkg/npm/model/Directories.java | 115 +++++ .../commonjava/indy/pkg/npm/model/Dist.java | 46 ++ .../indy/pkg/npm/model/DistTag.java | 93 ++++ .../indy/pkg/npm/model/Engines.java | 87 ++++ .../indy/pkg/npm/model/License.java | 51 ++ .../indy/pkg/npm/model/NpmJsonOpts.java | 66 +++ .../pkg/npm/model/NpmOperationalInternal.java | 46 ++ .../indy/pkg/npm/model/PackageMetadata.java | 447 ++++++++++++++++ .../indy/pkg/npm/model/Repository.java | 52 ++ .../indy/pkg/npm/model/UserInfo.java | 94 ++++ .../indy/pkg/npm/model/VersionMetadata.java | 488 ++++++++++++++++++ .../org/commonjava/indy/util/PathUtils.java | 111 ++++ pom.xml | 2 +- 16 files changed, 1974 insertions(+), 1 deletion(-) create mode 100644 core-java/src/main/java/org/commonjava/indy/pkg/npm/content/PackagePath.java create mode 100644 core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Bugs.java create mode 100644 core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Commitplease.java create mode 100644 core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Directories.java create mode 100644 core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Dist.java create mode 100644 core-java/src/main/java/org/commonjava/indy/pkg/npm/model/DistTag.java create mode 100644 core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Engines.java create mode 100644 core-java/src/main/java/org/commonjava/indy/pkg/npm/model/License.java create mode 100644 core-java/src/main/java/org/commonjava/indy/pkg/npm/model/NpmJsonOpts.java create mode 100644 core-java/src/main/java/org/commonjava/indy/pkg/npm/model/NpmOperationalInternal.java create mode 100644 core-java/src/main/java/org/commonjava/indy/pkg/npm/model/PackageMetadata.java create mode 100644 core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Repository.java create mode 100644 core-java/src/main/java/org/commonjava/indy/pkg/npm/model/UserInfo.java create mode 100644 core-java/src/main/java/org/commonjava/indy/pkg/npm/model/VersionMetadata.java create mode 100644 core-java/src/main/java/org/commonjava/indy/util/PathUtils.java diff --git a/core-java/src/main/java/org/commonjava/indy/pkg/npm/content/PackagePath.java b/core-java/src/main/java/org/commonjava/indy/pkg/npm/content/PackagePath.java new file mode 100644 index 0000000..70f0bb0 --- /dev/null +++ b/core-java/src/main/java/org/commonjava/indy/pkg/npm/content/PackagePath.java @@ -0,0 +1,157 @@ +/** + * Copyright (C) 2022-2023 Red Hat, Inc. (https://github.com/Commonjava/indy-model) + * + * 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. + */ +package org.commonjava.indy.pkg.npm.content; + +import java.util.Optional; + +import static org.commonjava.indy.util.PathUtils.normalize; + +public class PackagePath +{ + + private String tarPath; + + private Boolean scoped; + + private String packageName; + + private String version; + + private String scopedName; + + public PackagePath(String tarPath ) + { + this.tarPath = tarPath; + init(); + } + + private void init() + { + String[] pathParts = tarPath.split( "/" ); + if ( tarPath.startsWith( "@" ) ) + { + scoped = Boolean.TRUE; + scopedName = pathParts[0]; + packageName = pathParts[1]; + if ( pathParts.length == 4 && "-".equals( pathParts[2] ) ) + { + String tarName = pathParts[3]; + version = tarName.substring( packageName.length() + 1, tarName.length() - 4 ); + } + else if ( pathParts.length == 3 ) + { + version = pathParts[2]; + } + } + else + { + scoped = Boolean.FALSE; + packageName = pathParts[0]; + if ( pathParts.length == 3 && "-".equals( pathParts[1] ) ) + { + String tarName = pathParts[2]; + version = tarName.substring( packageName.length() + 1, tarName.length() - 4 ); + } + else if ( pathParts.length == 2 ) + { + version = pathParts[1]; + } + } + } + + public String getTarPath() + { + return tarPath; + } + + public void setTarPath( String tarPath ) + { + this.tarPath = tarPath; + } + + public Boolean isScoped() + { + return scoped; + } + + public void setScoped( Boolean scoped ) + { + this.scoped = scoped; + } + + public String getPackageName() + { + return packageName; + } + + public void setPackageName( String packageName ) + { + this.packageName = packageName; + } + + public String getVersion() + { + return version; + } + + public void setVersion( String version ) + { + this.version = version; + } + + public String getScopedName() + { + return scopedName; + } + + public void setScopedName( String scopedName ) + { + this.scopedName = scopedName; + } + + public String getVersionPath() + { + return isScoped() ? normalize( scopedName, packageName, version ) : normalize( packageName, version ); + } + + public static Optional parse( final String tarPath ) + { + String path = tarPath; + if ( path.startsWith( "/" ) ) + { + path = path.substring( 1 ); + } + String[] parts = path.split( "/" ); + if ( parts.length < 2 ) + { + return Optional.empty(); + } + else if ( path.startsWith( "@" ) && parts.length < 3 ) + { + return Optional.empty(); + } + PackagePath packagePath = new PackagePath( path ); + return Optional.of( packagePath ); + } + + @Override + public String toString() + { + return "PackagePath{" + "tarPath='" + tarPath + '\'' + ", scoped=" + scoped + ", packageName='" + + packageName + '\'' + ", version='" + version + '\'' + ", scopedName='" + scopedName + '\'' + + '}'; + } +} diff --git a/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Bugs.java b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Bugs.java new file mode 100644 index 0000000..b5ca22e --- /dev/null +++ b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Bugs.java @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2022-2023 Red Hat, Inc. (https://github.com/Commonjava/indy-model) + * + * 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. + */ +package org.commonjava.indy.pkg.npm.model; + +public class Bugs +{ + + private final String url; + + private final String email; + + protected Bugs() + { + this.url = null; + this.email = null; + } + + public Bugs( final String url ) + { + this.url = url; + this.email = null; + } + + public Bugs( final String url, final String email ) + { + this.url = url; + this.email = email; + } + + public String getUrl() + { + return url; + } + + public String getEmail() + { + return email; + } + +} diff --git a/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Commitplease.java b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Commitplease.java new file mode 100644 index 0000000..bfac821 --- /dev/null +++ b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Commitplease.java @@ -0,0 +1,67 @@ +/** + * Copyright (C) 2022-2023 Red Hat, Inc. (https://github.com/Commonjava/indy-model) + * + * 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. + */ +package org.commonjava.indy.pkg.npm.model; + +import java.util.List; + +public class Commitplease +{ + + private final Boolean nohook; + + private final List components; + + private final String markerPattern; + + private final String ticketPattern; + + protected Commitplease() + { + this.nohook = null; + this.components = null; + this.markerPattern = null; + this.ticketPattern = null; + } + + public Commitplease( final Boolean nohook, final List components, final String markerPattern, + final String ticketPattern ) + { + this.nohook = nohook; + this.components = components; + this.markerPattern = markerPattern; + this.ticketPattern = ticketPattern; + } + + public Boolean getNohook() + { + return nohook; + } + + public List getComponents() + { + return components; + } + + public String getMarkerPattern() + { + return markerPattern; + } + + public String getTicketPattern() + { + return ticketPattern; + } +} diff --git a/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Directories.java b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Directories.java new file mode 100644 index 0000000..ebb1b18 --- /dev/null +++ b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Directories.java @@ -0,0 +1,115 @@ +/** + * Copyright (C) 2022-2023 Red Hat, Inc. (https://github.com/Commonjava/indy-model) + * + * 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. + */ +package org.commonjava.indy.pkg.npm.model; + +import java.util.HashMap; +import java.util.Map; + +public class Directories +{ + private static final String LIB = "lib"; + + private static final String BIN = "bin"; + + private static final String MAN = "man"; + + private static final String DOC = "doc"; + + private static final String EXAMPLE = "example"; + + private static final String TEST = "test"; + + private Map directoriesMap = new HashMap(); + + protected Directories() + { + } + + public String getLib() + { + return directoriesMap.get( LIB ); + } + + public void setLib( String lib ) + { + directoriesMap.put( LIB, lib ); + } + + public String getBin() + { + return directoriesMap.get( BIN ); + } + + public void setBin( String bin ) + { + directoriesMap.put( BIN, bin ); + } + + public String getMan() + { + return directoriesMap.get( MAN ); + } + + public void setMan( String man ) + { + directoriesMap.put( MAN, man ); + } + + public String getDoc() + { + return directoriesMap.get( DOC ); + } + + public void setDoc( String doc ) + { + directoriesMap.put( DOC, doc ); + } + + public String getExample() + { + return directoriesMap.get( EXAMPLE ); + } + + public void setExample( String example ) + { + directoriesMap.put( EXAMPLE, example ); + } + + public String getTest() + { + return directoriesMap.get( TEST ); + } + + public void setTest( String test ) + { + directoriesMap.put( TEST, test ); + } + + public Map fetchDirectoriesMap() + { + return directoriesMap; + } + + public String getDirectory( String name ) + { + return directoriesMap.get( name ); + } + + public void putDirectory( String name, String value ) + { + directoriesMap.put( name, value ); + } +} diff --git a/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Dist.java b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Dist.java new file mode 100644 index 0000000..0815556 --- /dev/null +++ b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Dist.java @@ -0,0 +1,46 @@ +/** + * Copyright (C) 2022-2023 Red Hat, Inc. (https://github.com/Commonjava/indy-model) + * + * 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. + */ +package org.commonjava.indy.pkg.npm.model; + +public class Dist +{ + + private final String shasum; + + private final String tarball; + + protected Dist() + { + this.shasum = null; + this.tarball = null; + } + + public Dist( final String shasum, final String tarball ) + { + this.shasum = shasum; + this.tarball = tarball; + } + + public String getShasum() + { + return shasum; + } + + public String getTarball() + { + return tarball; + } +} diff --git a/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/DistTag.java b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/DistTag.java new file mode 100644 index 0000000..fb73ab3 --- /dev/null +++ b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/DistTag.java @@ -0,0 +1,93 @@ +/** + * Copyright (C) 2022-2023 Red Hat, Inc. (https://github.com/Commonjava/indy-model) + * + * 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. + */ +package org.commonjava.indy.pkg.npm.model; + +import java.util.HashMap; +import java.util.Map; + +public class DistTag +{ + public static final String LATEST = "latest"; + + public static final String STABLE = "stable"; + + public static final String BETA = "beta"; + + public static final String DEV = "dev"; + + private static final String CANARY = "canary"; + + private Map tagsMap = new HashMap(); + + public DistTag() + { + } + + public String getLatest() { + return tagsMap.get(LATEST); + } + + public void setLatest(String latest) { + tagsMap.put(LATEST, latest); + } + + public String getStable() { + return tagsMap.get(STABLE); + } + + public void setStable(String stable) { + tagsMap.put(STABLE,stable); + } + + public String getBeta() { + return tagsMap.get(BETA); + } + + public void setBeta(String beta) { + tagsMap.put(BETA,beta); + } + + public String getDev() { + return tagsMap.get(DEV); + } + + public void setDev(String dev) { + tagsMap.put(DEV,dev); + } + + public String getCanary() + { + return tagsMap.get( CANARY ); + } + + public void setCanary( String canary ) + { + tagsMap.put( CANARY, canary ); + } + + public Map fetchTagsMap() + { + return tagsMap; + } + + public String getTag(String tag) { + return tagsMap.get(tag); + } + + public void putTag(String tag, String value) { + tagsMap.put(tag, value); + } +} diff --git a/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Engines.java b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Engines.java new file mode 100644 index 0000000..3210d48 --- /dev/null +++ b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Engines.java @@ -0,0 +1,87 @@ +/** + * Copyright (C) 2022-2023 Red Hat, Inc. (https://github.com/Commonjava/indy-model) + * + * 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. + */ +package org.commonjava.indy.pkg.npm.model; + +import java.util.HashMap; +import java.util.Map; + +public class Engines +{ + + private static final String NODE = "node"; + + private static final String NPM = "npm"; + + private Map enginesMap = new HashMap(); + + protected Engines() + { + } + + protected Engines( String engine ) + { + String[] strings = engine.split( String.valueOf( Character.SPACE_SEPARATOR ) ); + + if ( strings.length != 2 ) + { + return; + } + + if ( NPM.equals( strings[0] ) ) + { + enginesMap.put( NPM, strings[1] ); + } + else if ( NODE.equals( strings[0] ) ) + { + enginesMap.put( NODE, strings[1] ); + } + } + + public String getNode() + { + return enginesMap.get( NODE ); + } + + public void setNode( String node ) + { + enginesMap.put( NODE, node ); + } + + public String getNpm() + { + return enginesMap.get( NPM ); + } + + public void setNpm( String npm ) + { + enginesMap.put( NPM, npm ); + } + + public Map fetchEnginesMap() + { + return enginesMap; + } + + public String getEngine( String name ) + { + return enginesMap.get( name ); + } + + public void putEngine( String name, String value ) + { + enginesMap.put( name, value ); + } +} diff --git a/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/License.java b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/License.java new file mode 100644 index 0000000..53c3ac1 --- /dev/null +++ b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/License.java @@ -0,0 +1,51 @@ +/** + * Copyright (C) 2022-2023 Red Hat, Inc. (https://github.com/Commonjava/indy-model) + * + * 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. + */ +package org.commonjava.indy.pkg.npm.model; + +public class License +{ + private final String type; + + private final String url; + + protected License() + { + this.type = null; + this.url = null; + } + + public License( final String type ) + { + this.type = type; + this.url = null; + } + + public License( final String type, final String url ) + { + this.type = type; + this.url = url; + } + + public String getType() + { + return type; + } + + public String getUrl() + { + return url; + } +} diff --git a/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/NpmJsonOpts.java b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/NpmJsonOpts.java new file mode 100644 index 0000000..974d28d --- /dev/null +++ b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/NpmJsonOpts.java @@ -0,0 +1,66 @@ +/** + * Copyright (C) 2022-2023 Red Hat, Inc. (https://github.com/Commonjava/indy-model) + * + * 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. + */ +package org.commonjava.indy.pkg.npm.model; + +import java.util.List; + +public class NpmJsonOpts +{ + + private final String file; + + private final Boolean wscript; + + private final List contributors; + + private final Boolean serverjs; + + protected NpmJsonOpts() + { + this.file = null; + this.wscript = null; + this.contributors = null; + this.serverjs = null; + } + + public NpmJsonOpts( final String file, final Boolean wscript, final List contributors, final Boolean serverjs ) + { + this.file = file; + this.wscript = wscript; + this.contributors = contributors; + this.serverjs = serverjs; + } + + public String getFile() + { + return file; + } + + public Boolean getWscript() + { + return wscript; + } + + public List getContributors() + { + return contributors; + } + + public Boolean getServerjs() + { + return serverjs; + } +} diff --git a/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/NpmOperationalInternal.java b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/NpmOperationalInternal.java new file mode 100644 index 0000000..41fc38b --- /dev/null +++ b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/NpmOperationalInternal.java @@ -0,0 +1,46 @@ +/** + * Copyright (C) 2022-2023 Red Hat, Inc. (https://github.com/Commonjava/indy-model) + * + * 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. + */ +package org.commonjava.indy.pkg.npm.model; + +public class NpmOperationalInternal +{ + + private final String host; + + private final String tmp; + + protected NpmOperationalInternal() + { + this.host = null; + this.tmp = null; + } + + public NpmOperationalInternal( final String host, final String tmp ) + { + this.host = host; + this.tmp = tmp; + } + + public String getHost() + { + return host; + } + + public String getTmp() + { + return tmp; + } +} diff --git a/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/PackageMetadata.java b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/PackageMetadata.java new file mode 100644 index 0000000..5bf0d39 --- /dev/null +++ b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/PackageMetadata.java @@ -0,0 +1,447 @@ +/** + * Copyright (C) 2022-2023 Red Hat, Inc. (https://github.com/Commonjava/indy-model) + * + * 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. + */ +package org.commonjava.indy.pkg.npm.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.commonjava.atlas.maven.ident.util.VersionUtils; +import org.commonjava.atlas.maven.ident.version.SingleVersion; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Serializable; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +@JsonIgnoreProperties( { "_id", "_rev", "_attachments" } ) +public class PackageMetadata + implements Serializable, Comparable +{ + private static final long serialVersionUID = 1L; + + private static final String TIMEOUT_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; + + private static final String MODIFIED = "modified"; + + private static final String CREATED = "created"; + + private String name; + + private String description; + + @JsonProperty( "dist-tags" ) + private DistTag distTags = new DistTag(); + + private Map versions = new LinkedHashMap<>(); + + private List maintainers = new ArrayList<>(); + + private Map time = new LinkedHashMap<>(); + + private UserInfo author; + + private Map users = new LinkedHashMap<>(); + + private Repository repository; + + private String readme; + + private String readmeFilename; + + private String homepage; + + private List keywords = new ArrayList<>(); + + private Bugs bugs; + + private License license; + + public PackageMetadata() + { + } + + public PackageMetadata( String name ) + { + this.name = name; + } + + public String getName() + { + return name; + } + + public void setName( String name ) + { + this.name = name; + } + + public String getDescription() + { + return description; + } + + public void setDescription( String description ) + { + this.description = description; + } + + public DistTag getDistTags() + { + return distTags; + } + + public void setDistTags( DistTag distTags ) + { + this.distTags = distTags; + } + + public Map getVersions() + { + return versions; + } + + public void setVersions( Map versions ) + { + this.versions = versions; + } + + public List getMaintainers() + { + return maintainers; + } + + public void setMaintainers( List maintainers ) + { + this.maintainers = maintainers; + } + + public Map getTime() + { + return time; + } + + public void setTime( Map time ) + { + this.time = time; + } + + public UserInfo getAuthor() + { + return author; + } + + public void setAuthor( UserInfo author ) + { + this.author = author; + } + + public Map getUsers() + { + return users; + } + + public void setUsers( Map users ) + { + this.users = users; + } + + public Repository getRepository() + { + return repository; + } + + public void setRepository( Repository repository ) + { + this.repository = repository; + } + + public String getReadme() + { + return readme; + } + + public void setReadme( String readme ) + { + this.readme = readme; + } + + public String getReadmeFilename() + { + return readmeFilename; + } + + public void setReadmeFilename( String readmeFilename ) + { + this.readmeFilename = readmeFilename; + } + + public String getHomepage() + { + return homepage; + } + + public void setHomepage( String homepage ) + { + this.homepage = homepage; + } + + public List getKeywords() + { + return keywords; + } + + public void setKeywords( List keywords ) + { + this.keywords = keywords; + } + + public Bugs getBugs() + { + return bugs; + } + + public void setBugs( Bugs bugs ) + { + this.bugs = bugs; + } + + public License getLicense() + { + return license; + } + + public void setLicense( License license ) + { + this.license = license; + } + + public void addMaintainers( UserInfo userInfo ) + { + this.getMaintainers().add( userInfo ); + } + + public void addKeywords( String key ) + { + this.getKeywords().add( key ); + } + + @Override + public int compareTo( PackageMetadata o ) + { + return 0; + } + + public boolean merge( PackageMetadata source, boolean isForGroup ) + { + Logger logger = LoggerFactory.getLogger( getClass() ); + + boolean changed = false; + if ( source.getName() != null ) + { + this.setName( source.getName() ); + changed = true; + } + if ( source.getDescription() != null ) + { + this.setDescription( source.getDescription() ); + changed = true; + } + if ( source.getAuthor() != null ) + { + this.setAuthor( source.getAuthor() ); + changed = true; + } + if ( source.getRepository() != null ) + { + this.setRepository( source.getRepository() ); + changed = true; + } + if ( source.getReadme() != null ) + { + this.setReadme( source.getReadme() ); + changed = true; + } + if ( source.getReadmeFilename() != null ) + { + this.setReadmeFilename( source.getReadmeFilename() ); + changed = true; + } + if ( source.getHomepage() != null ) + { + this.setHomepage( source.getHomepage() ); + changed = true; + } + if ( source.getBugs() != null ) + { + this.setBugs( source.getBugs() ); + changed = true; + } + if ( source.getLicense() != null ) + { + this.setLicense( source.getLicense() ); + changed = true; + } + + // merge maintainers list + for ( UserInfo m : source.getMaintainers() ) + { + if ( m.getName() != null && !maintainers.contains( m ) ) + { + this.addMaintainers( new UserInfo( m.getName(), m.getEmail(), m.getUrl() ) ); + changed = true; + } + } + + // merge keywords list + for ( String key : source.getKeywords() ) + { + if ( !keywords.contains( key ) ) + { + this.addKeywords( key ); + changed = true; + } + } + + // merge users map + Map sourceUsers = source.getUsers(); + for ( final String user : sourceUsers.keySet() ) + { + if ( users.containsKey( user ) && users.get( user ).equals( sourceUsers.get( user ) ) ) + { + continue; + } + users.put( user, sourceUsers.get( user ) ); + changed = true; + } + + // merge time map + SimpleDateFormat sdf = new SimpleDateFormat( TIMEOUT_FORMAT ); + Map clone = new LinkedHashMap<>(); + + for ( final String key : time.keySet() ) + { + String value = time.get( key ); + Date date = null; + try + { + date = sdf.parse( value ); + } + catch ( ParseException e ) + { + logger.error( String.format( "Cannot parse date: %s. Reason: %s", value, e ) ); + } + clone.put( key, date ); + } + + Map sourceTimes = source.getTime(); + boolean added = false; + for ( final String key : sourceTimes.keySet() ) + { + String value = sourceTimes.get( key ); + Date date; + try + { + date = sdf.parse( value ); + } + catch ( ParseException e ) + { + logger.error( String.format( "Cannot parse date: %s. Reason: %s", value, e ) ); + continue; + } + + // if source's version update time is more recent(sort as the letter order), will update it into the original map. + if ( clone.containsKey( key ) && date.compareTo( clone.get( key ) ) <= 0 ) + { + continue; + } + clone.put( key, date ); + added = true; + changed = true; + } + + // only sorting the map when update occurred + if ( added ) + { + // sort as the time value in map + List> timeList = new ArrayList<>( clone.entrySet() ); + // sort the time as value (update time) asc + timeList.sort( Map.Entry.comparingByValue() ); + + Map result = new LinkedHashMap<>(); + // make the 'modified' and 'created' value as the first two keys in final map + if ( clone.get( MODIFIED ) != null ) + { + result.put( MODIFIED, sdf.format( clone.get( MODIFIED ) ) ); + } + if ( clone.get( CREATED ) != null ) + { + result.put( CREATED, sdf.format( clone.get( CREATED ) ) ); + } + + for ( final Map.Entry entry : timeList ) + { + if ( MODIFIED.equals( entry.getKey() ) || CREATED.equals( entry.getKey() ) ) + { + continue; + } + result.put( entry.getKey(), sdf.format( entry.getValue() ) ); + } + time = result; + } + + // merge dist-tag object + DistTag sourceDist = source.getDistTags(); + Map sourceDistMap = sourceDist.fetchTagsMap(); + Map thisDistMap = distTags.fetchTagsMap(); + if ( thisDistMap.isEmpty() && !sourceDistMap.isEmpty() ) + { + this.setDistTags( sourceDist ); + changed = true; + } + else + { + for ( final String tag : sourceDistMap.keySet() ) + { + SingleVersion sourceVersion = VersionUtils.createSingleVersion( sourceDistMap.get( tag ) ); + SingleVersion thisVersion = VersionUtils.createSingleVersion( thisDistMap.get( tag ) ); + if ( thisDistMap.containsKey( tag ) && sourceVersion.compareTo( thisVersion ) <= 0 ) + { + continue; + } + distTags.putTag( tag, sourceDistMap.get( tag ) ); + changed = true; + } + } + + //merge versions, keep the first version metadata for a given version that coming across + Map sourceVersions = source.getVersions(); + for ( final String v : sourceVersions.keySet() ) + { + VersionMetadata value = sourceVersions.get( v ); + // if the versions meet are same here: + // for group merging, versions only accepts the first one coming to the group, + // for publish merging, it always accepts the latest updated version meta + if ( !isForGroup || !versions.containsKey( v ) ) + { + versions.put( v, value ); + changed = true; + } + } + + return changed; + } +} diff --git a/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Repository.java b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Repository.java new file mode 100644 index 0000000..3ee4f13 --- /dev/null +++ b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/Repository.java @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2022-2023 Red Hat, Inc. (https://github.com/Commonjava/indy-model) + * + * 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. + */ +package org.commonjava.indy.pkg.npm.model; + +public class Repository +{ + private final String type; + + private final String url; + + protected Repository() + { + this.type = null; + this.url = null; + } + + public Repository( final String url ) + { + this.type = null; + this.url = url; + } + + public Repository( final String type, final String url ) + { + this.type = type; + this.url = url; + } + + public String getType() + { + return type; + } + + public String getUrl() + { + return url; + } + +} diff --git a/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/UserInfo.java b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/UserInfo.java new file mode 100644 index 0000000..98b64fe --- /dev/null +++ b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/UserInfo.java @@ -0,0 +1,94 @@ +/** + * Copyright (C) 2022-2023 Red Hat, Inc. (https://github.com/Commonjava/indy-model) + * + * 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. + */ +package org.commonjava.indy.pkg.npm.model; + +public class UserInfo +{ + private final String name; + + private final String email; + + private final String url; + + protected UserInfo() + { + this.name = null; + this.email = null; + this.url = null; + } + + public UserInfo( final String name ) + { + this.name = name; + this.email = null; + this.url = null; + } + + public UserInfo( final String name, final String email ) + { + this.name = name; + this.email = email; + this.url = null; + } + + public UserInfo( final String name, final String email, final String url ) + { + this.name = name; + this.email = email; + this.url = url; + } + + public String getName() + { + return name; + } + + public String getEmail() + { + return email; + } + + public String getUrl() + { + return url; + } + + @Override + public boolean equals( Object o ) + { + if ( this == o ) + { + return true; + } + if ( !( o instanceof UserInfo ) ) + { + return false; + } + + UserInfo that = (UserInfo) o; + + return getName().equals( that.getName() ); + } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + ( ( name == null ) ? 0 : name.hashCode() ); + return result; + } +} diff --git a/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/VersionMetadata.java b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/VersionMetadata.java new file mode 100644 index 0000000..87df154 --- /dev/null +++ b/core-java/src/main/java/org/commonjava/indy/pkg/npm/model/VersionMetadata.java @@ -0,0 +1,488 @@ +/** + * Copyright (C) 2022-2023 Red Hat, Inc. (https://github.com/Commonjava/indy-model) + * + * 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. + */ +package org.commonjava.indy.pkg.npm.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +@JsonIgnoreProperties( "_id" ) +public class VersionMetadata + implements Serializable, Comparable +{ + private static final long serialVersionUID = 1L; + + private String name; + + private String title; + + private String description; + + private String main; + + private String version; + + private String url; + + private String homepage; + + private List keywords; + + private UserInfo author; + + private List contributors; + + private List maintainers; + + private Repository repository; + + private Bugs bugs; + + @Deprecated + private List licenses; + + private License license; + + private Map dependencies; + + private Map devDependencies; + + private Map jsdomVersions; + + private Map scripts; + + private Dist dist; + + private Directories directories; + + private Commitplease commitplease; + + private List engines; + + @JsonProperty( "_engineSupported" ) + private Boolean engineSupported; + + private List files; + + private String deprecated; + + private String lib; + + private String gitHead; + + @JsonProperty( "_shasum" ) + private String shasum; + + @JsonProperty( "_from" ) + private String from; + + @JsonProperty( "_npmVersion" ) + private String npmVersion; + + @JsonProperty( "_nodeVersion" ) + private String nodeVersion; + + @JsonProperty( "_npmUser" ) + private UserInfo npmUser; + + @JsonProperty( "_npmJsonOpts" ) + private NpmJsonOpts npmJsonOpts; + + @JsonProperty( "_npmOperationalInternal" ) + private NpmOperationalInternal npmOperationalInternal; + + @JsonProperty( "_defaultsLoaded" ) + private Boolean defaultsLoaded; + + public VersionMetadata() + { + } + + public VersionMetadata( String name, String version ) + { + this.name = name; + this.version = version; + } + + public String getName() + { + return name; + } + + public void setName( String name ) + { + this.name = name; + } + + public String getTitle() + { + return title; + } + + public void setTitle( String title ) + { + this.title = title; + } + + public String getDescription() + { + return description; + } + + public void setDescription( String description ) + { + this.description = description; + } + + public String getMain() + { + return main; + } + + public void setMain( String main ) + { + this.main = main; + } + + public String getVersion() + { + return version; + } + + public void setVersion( String version ) + { + this.version = version; + } + + public String getUrl() + { + return url; + } + + public void setUrl( String url ) + { + this.url = url; + } + + public String getHomepage() + { + return homepage; + } + + public void setHomepage( String homepage ) + { + this.homepage = homepage; + } + + public List getKeywords() + { + return keywords; + } + + public void setKeywords( List keywords ) + { + this.keywords = keywords; + } + + public UserInfo getAuthor() + { + return author; + } + + public void setAuthor( UserInfo author ) + { + this.author = author; + } + + public List getContributors() + { + return contributors; + } + + public void setContributors( List contributors ) + { + this.contributors = contributors; + } + + public List getMaintainers() + { + return maintainers; + } + + public void setMaintainers( List maintainers ) + { + this.maintainers = maintainers; + } + + public Repository getRepository() + { + return repository; + } + + public void setRepository( Repository repository ) + { + this.repository = repository; + } + + public Bugs getBugs() + { + return bugs; + } + + public void setBugs( Bugs bugs ) + { + this.bugs = bugs; + } + + public List getLicenses() + { + return licenses; + } + + public void setLicenses( List licenses ) + { + this.licenses = licenses; + } + + public License getLicense() + { + return license; + } + + public void setLicense( License license ) + { + this.license = license; + } + + public Map getDependencies() + { + return dependencies; + } + + public void setDependencies( Map dependencies ) + { + this.dependencies = dependencies; + } + + public Map getDevDependencies() + { + return devDependencies; + } + + public void setDevDependencies( Map devDependencies ) + { + this.devDependencies = devDependencies; + } + + public Map getJsdomVersions() + { + return jsdomVersions; + } + + public void setJsdomVersions( Map jsdomVersions ) + { + this.jsdomVersions = jsdomVersions; + } + + public Map getScripts() + { + return scripts; + } + + public void setScripts( Map scripts ) + { + this.scripts = scripts; + } + + public Dist getDist() + { + return dist; + } + + public void setDist( Dist dist ) + { + this.dist = dist; + } + + public Directories getDirectories() + { + return directories; + } + + public void setDirectories( Directories directories ) + { + this.directories = directories; + } + + public Commitplease getCommitplease() + { + return commitplease; + } + + public void setCommitplease( Commitplease commitplease ) + { + this.commitplease = commitplease; + } + + public List getEngines() + { + return engines; + } + + public void setEngines( List engines ) + { + this.engines = engines; + } + + public Boolean getEngineSupported() + { + return engineSupported; + } + + public void setEngineSupported( Boolean engineSupported ) + { + this.engineSupported = engineSupported; + } + + public List getFiles() + { + return files; + } + + public void setFiles( List files ) + { + this.files = files; + } + + public String getDeprecated() + { + return deprecated; + } + + public void setDeprecated( String deprecated ) + { + this.deprecated = deprecated; + } + + public String getLib() + { + return lib; + } + + public void setLib( String lib ) + { + this.lib = lib; + } + + public String getGitHead() + { + return gitHead; + } + + public void setGitHead( String gitHead ) + { + this.gitHead = gitHead; + } + + public String getShasum() + { + return shasum; + } + + public void setShasum( String shasum ) + { + this.shasum = shasum; + } + + public String getFrom() + { + return from; + } + + public void setFrom( String from ) + { + this.from = from; + } + + public String getNpmVersion() + { + return npmVersion; + } + + public void setNpmVersion( String npmVersion ) + { + this.npmVersion = npmVersion; + } + + public String getNodeVersion() + { + return nodeVersion; + } + + public void setNodeVersion( String nodeVersion ) + { + this.nodeVersion = nodeVersion; + } + + public UserInfo getNpmUser() + { + return npmUser; + } + + public void setNpmUser( UserInfo npmUser ) + { + this.npmUser = npmUser; + } + + public NpmJsonOpts getNpmJsonOpts() + { + return npmJsonOpts; + } + + public void setNpmJsonOpts( NpmJsonOpts npmJsonOpts ) + { + this.npmJsonOpts = npmJsonOpts; + } + + public NpmOperationalInternal getNpmOperationalInternal() + { + return npmOperationalInternal; + } + + public void setNpmOperationalInternal( NpmOperationalInternal npmOperationalInternal ) + { + this.npmOperationalInternal = npmOperationalInternal; + } + + public Boolean getDefaultsLoaded() + { + return defaultsLoaded; + } + + public void setDefaultsLoaded( Boolean defaultsLoaded ) + { + this.defaultsLoaded = defaultsLoaded; + } + + @Override + public int compareTo( VersionMetadata o ) + { + return 0; + } +} diff --git a/core-java/src/main/java/org/commonjava/indy/util/PathUtils.java b/core-java/src/main/java/org/commonjava/indy/util/PathUtils.java new file mode 100644 index 0000000..4e59744 --- /dev/null +++ b/core-java/src/main/java/org/commonjava/indy/util/PathUtils.java @@ -0,0 +1,111 @@ +/** + * Copyright (C) 2022-2023 Red Hat, Inc. (https://github.com/Commonjava/indy-model) + * + * 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. + */ +package org.commonjava.indy.util; + +public final class PathUtils +{ + + public static final String ROOT = "/"; + + private static final String[] ROOT_ARRY = { ROOT }; + + private PathUtils() + { + } + + public static String[] parentPath( final String path ) + { + final String[] parts = path.split( "/" ); + if ( parts.length < 2 ) + { + return ROOT_ARRY; + } + else + { + final String[] parentParts = new String[parts.length - 1]; + System.arraycopy( parts, 0, parentParts, 0, parentParts.length ); + return parentParts; + } + } + + public static String normalize( final String... path ) + { + if ( path == null || path.length < 1 || ( path.length == 1 && path[0] == null ) ) + { + return ROOT; + } + + final StringBuilder sb = new StringBuilder(); + int idx = 0; + parts: + for ( String part : path ) + { + if ( part == null || part.length() < 1 || "/".equals( part ) ) + { + continue; + } + + if ( idx == 0 && part.startsWith( "file:" ) ) + { + if ( part.length() > 5 ) + { + sb.append( part.substring( 5 ) ); + } + + continue; + } + + if ( idx > 0 ) + { + while ( part.charAt( 0 ) == '/' ) + { + if ( part.length() < 2 ) + { + continue parts; + } + + part = part.substring( 1 ); + } + } + + while ( part.charAt( part.length() - 1 ) == '/' ) + { + if ( part.length() < 2 ) + { + continue parts; + } + + part = part.substring( 0, part.length() - 1 ); + } + + if ( sb.length() > 0 ) + { + sb.append( '/' ); + } + + sb.append( part ); + idx++; + } + + if ( path[path.length - 1] != null && path[path.length - 1].endsWith( "/" ) ) + { + sb.append( "/" ); + } + + return sb.toString(); + } + +} diff --git a/pom.xml b/pom.xml index 70c395b..bc16f8a 100644 --- a/pom.xml +++ b/pom.xml @@ -40,7 +40,7 @@ https://github.com/Commonjava/indy-model - 1.1.4 + 1.1.9 3.6.9 1.2.13 2.15.2