Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (C) 2023-2024 Philip Helger (www.helger.com)
* philip[at]helger[dot]com
*
* 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 com.helger.phive.ves.engine.load;
import java.time.OffsetDateTime;
import java.util.Iterator;
import java.util.Set;
import java.util.function.Predicate;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.helger.commons.ValueEnforcer;
import com.helger.commons.collection.impl.ICommonsList;
import com.helger.commons.collection.iterate.ReverseListIterator;
import com.helger.commons.compare.ESortOrder;
import com.helger.commons.datetime.PDTFactory;
import com.helger.commons.string.StringHelper;
import com.helger.diver.api.coord.DVRCoordinate;
import com.helger.diver.api.version.DVRPseudoVersionRegistry;
import com.helger.diver.api.version.DVRVersion;
import com.helger.diver.api.version.IDVRPseudoVersion;
import com.helger.diver.repo.IRepoStorageReadItem;
import com.helger.diver.repo.RepoStorageKeyOfArtefact;
import com.helger.diver.repo.RepoStorageReadableResource;
import com.helger.diver.repo.toc.IRepoStorageWithToc;
import com.helger.diver.repo.toc.RepoToc;
import com.helger.phive.api.config.PhivePseudoVersionRegistrarSPIImpl;
import com.helger.phive.api.diver.IPseudoVersionResolver;
import com.helger.phive.api.executorset.status.IValidationExecutorSetStatus;
import com.helger.phive.ves.model.v1.VESStatus1Helper;
import com.helger.phive.ves.model.v1.VESStatus1Marshaller;
import com.helger.phive.ves.v10.VesStatusType;
/**
* Helper class used by {@link VESLoader} to resolve the pseudo versions based
* on a repository table of contents and the status objects.
*
* @author Philip Helger
*/
public final class VESLoaderPseudoVersionResolver implements IPseudoVersionResolver
{
private final IRepoStorageWithToc m_aRepo;
public VESLoaderPseudoVersionResolver (@Nonnull final IRepoStorageWithToc aRepo)
{
ValueEnforcer.notNull (aRepo, "Repo");
m_aRepo = aRepo;
}
@Nullable
private DVRCoordinate _findFirstMatchingByVersion (@Nullable final String sGroupID,
@Nullable final String sArtifactID,
@Nullable final Set aVersionsToIgnore,
final boolean bIncludeSnapshots,
@Nonnull final ESortOrder eSortOrder,
@Nullable final Predicate aResultDecider)
{
if (StringHelper.hasText (sGroupID) && StringHelper.hasText (sArtifactID))
{
// Get all versions of group and artifact
final RepoToc aToc = m_aRepo.readTocModel (sGroupID, sArtifactID);
if (aToc != null)
{
// Build version acceptor
final Predicate aVersionAcceptor = DVRVersion.getStaticVersionAcceptor (aVersionsToIgnore,
bIncludeSnapshots);
// Get iterator through all versions, so that the first match can be
// used
final ICommonsList aVersions = aToc.getAllVersionsAsList ();
final Iterator it;
if (eSortOrder.isAscending ())
it = aVersions.iterator ();
else
it = new ReverseListIterator <> (aVersions);
// Iterate version list
while (it.hasNext ())
{
final DVRVersion aCurVersion = it.next ();
if (aVersionAcceptor.test (aCurVersion))
{
// Matches the version requirement
final DVRCoordinate ret = new DVRCoordinate (sGroupID, sArtifactID, aCurVersion);
if (aResultDecider == null || aResultDecider.test (ret))
return ret;
}
}
}
}
return null;
}
@Nullable
public DVRCoordinate getOldestVersion (@Nullable final String sGroupID,
@Nullable final String sArtifactID,
@Nullable final Set aVersionsToIgnore)
{
// Oldest version on top
return _findFirstMatchingByVersion (sGroupID, sArtifactID, aVersionsToIgnore, true, ESortOrder.ASCENDING, null);
}
@Nullable
public DVRCoordinate getOldestReleaseVersion (@Nullable final String sGroupID,
@Nullable final String sArtifactID,
@Nullable final Set aVersionsToIgnore)
{
// Oldest version on top
return _findFirstMatchingByVersion (sGroupID, sArtifactID, aVersionsToIgnore, false, ESortOrder.ASCENDING, null);
}
@Nullable
public DVRCoordinate getLatestVersion (@Nullable final String sGroupID,
@Nullable final String sArtifactID,
@Nullable final Set aVersionsToIgnore)
{
// Newest version on top
return _findFirstMatchingByVersion (sGroupID, sArtifactID, aVersionsToIgnore, true, ESortOrder.DESCENDING, null);
}
@Nullable
public DVRCoordinate getLatestReleaseVersion (@Nullable final String sGroupID,
@Nullable final String sArtifactID,
@Nullable final Set aVersionsToIgnore)
{
// Newest version on top
return _findFirstMatchingByVersion (sGroupID, sArtifactID, aVersionsToIgnore, false, ESortOrder.DESCENDING, null);
}
/**
* This helper class does the real status loading and interpretation.
*
* @author Philip Helger
*/
private final class VESIDSelectorByStatusValidity implements Predicate
{
private final OffsetDateTime m_aRealCheckDateTime;
VESIDSelectorByStatusValidity (@Nonnull final OffsetDateTime aCheckDateTime)
{
// Make sure we have a non-null check date time
m_aRealCheckDateTime = aCheckDateTime != null ? aCheckDateTime : PDTFactory.getCurrentOffsetDateTime ();
}
public boolean test (@Nonnull final DVRCoordinate aVESID)
{
// Check if there is a "status" object available in the repo
final RepoStorageKeyOfArtefact aRepoKeyStatus = RepoStorageKeyOfArtefact.of (aVESID, VESLoader.FILE_EXT_STATUS);
final IRepoStorageReadItem aRepoContentStatus = m_aRepo.read (aRepoKeyStatus);
if (aRepoContentStatus != null)
{
// We found a status - interpret it
final VesStatusType aVESStatus = new VESStatus1Marshaller ().read (new RepoStorageReadableResource (aRepoKeyStatus,
aRepoContentStatus.getContent ()));
if (aVESStatus != null)
{
// Convert JAXB data model to Java date model
final IValidationExecutorSetStatus aStatus = VESStatus1Helper.convert (aVESStatus);
return aStatus.isValidPer (m_aRealCheckDateTime);
}
}
// Accept if no status is present etc.
return true;
}
}
@Nullable
public DVRCoordinate getLatestActiveVersion (@Nullable final String sGroupID,
@Nullable final String sArtifactID,
@Nullable final Set aVersionsToIgnore,
@Nullable final OffsetDateTime aCheckDateTime)
{
// Newest version on top
return _findFirstMatchingByVersion (sGroupID,
sArtifactID,
aVersionsToIgnore,
true,
ESortOrder.DESCENDING,
new VESIDSelectorByStatusValidity (aCheckDateTime));
}
@Nullable
public DVRCoordinate getLatestReleaseActiveVersion (@Nullable final String sGroupID,
@Nullable final String sArtifactID,
@Nullable final Set aVersionsToIgnore,
@Nullable final OffsetDateTime aCheckDateTime)
{
// Newest version on top
return _findFirstMatchingByVersion (sGroupID,
sArtifactID,
aVersionsToIgnore,
false,
ESortOrder.DESCENDING,
new VESIDSelectorByStatusValidity (aCheckDateTime));
}
/**
* Resolve the provided VESID with a pseudo version to a static version.
*
* @param aRepo
* The repository that contains the effective versions to be resolved.
* May not be null.
* @param aVESID
* The VESID with the pseudo version. May not be null.
* @param aVersionsToIgnore
* An optional set of static versions that should be ignored and not
* returned. May be null.
* @param aCheckDateTime
* The date and time for which the resolution should be performed. If
* null the current date and time will be used.
* @return null if the pseudo version could not be resolved.
* @since 9.2.1
*/
@Nullable
public static DVRCoordinate resolvePseudoVersion (@Nonnull final IRepoStorageWithToc aRepo,
@Nonnull final DVRCoordinate aVESID,
@Nullable final Set aVersionsToIgnore,
@Nullable final OffsetDateTime aCheckDateTime)
{
ValueEnforcer.notNull (aRepo, "Repo");
ValueEnforcer.notNull (aVESID, "VESID");
ValueEnforcer.isTrue ( () -> aVESID.getVersionObj ().isPseudoVersion (), "VESID Version must be a pseudo version");
final IDVRPseudoVersion aPseudoVersion = aVESID.getVersionObj ().getPseudoVersion ();
final VESLoaderPseudoVersionResolver aResolver = new VESLoaderPseudoVersionResolver (aRepo);
if (aPseudoVersion.equals (DVRPseudoVersionRegistry.OLDEST))
return aResolver.getOldestVersion (aVESID.getGroupID (), aVESID.getArtifactID (), aVersionsToIgnore);
if (aPseudoVersion.equals (DVRPseudoVersionRegistry.LATEST_RELEASE))
return aResolver.getLatestReleaseVersion (aVESID.getGroupID (), aVESID.getArtifactID (), aVersionsToIgnore);
if (aPseudoVersion.equals (DVRPseudoVersionRegistry.LATEST))
return aResolver.getLatestVersion (aVESID.getGroupID (), aVESID.getArtifactID (), aVersionsToIgnore);
if (aPseudoVersion.equals (PhivePseudoVersionRegistrarSPIImpl.LATEST_ACTIVE))
return aResolver.getLatestActiveVersion (aVESID.getGroupID (),
aVESID.getArtifactID (),
aVersionsToIgnore,
aCheckDateTime);
if (aPseudoVersion.equals (PhivePseudoVersionRegistrarSPIImpl.LATEST_RELEASE_ACTIVE))
return aResolver.getLatestReleaseActiveVersion (aVESID.getGroupID (),
aVESID.getArtifactID (),
aVersionsToIgnore,
aCheckDateTime);
throw new IllegalStateException ("Unsupported pseudo version " + aPseudoVersion);
}
}