All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.metaeffekt.mirror.contents.eol.EolLifecycle Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2021-2024 the original author or authors.
 *
 * 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.metaeffekt.mirror.contents.eol;

import com.metaeffekt.artifact.analysis.utils.FileUtils;
import com.metaeffekt.artifact.analysis.version.Version;
import com.metaeffekt.artifact.analysis.vulnerability.enrichment.VersionComparator;
import com.metaeffekt.mirror.contents.eol.state.LtsState;
import com.metaeffekt.mirror.contents.eol.state.SupportState;
import org.apache.lucene.document.Document;
import org.json.JSONArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class EolLifecycle {

    private static final Logger LOG = LoggerFactory.getLogger(EolLifecycle.class);

    private final String product;
    private final List cycles;

    public EolLifecycle(String product, List cycles) {
        this.product = product;
        this.cycles = cycles;
    }

    public EolLifecycle(String product) {
        this.product = product;
        this.cycles = new ArrayList<>();
    }

    public String getProduct() {
        return product;
    }

    public List getCycles() {
        return cycles;
    }

    public List getOrderedCycles() {
        try {
            return cycles.stream().sorted(Comparator.comparing(o -> Version.of(o.getCycle()))).collect(Collectors.toList());
        } catch (Exception e) {
            LOG.debug("Error sorting cycles for product [{}], returning unordered list: {}", product, cycles, e);
            return cycles;
        }
    }

    public void addCycle(EolCycle cycle) {
        this.cycles.add(cycle);
    }

    public EolCycle findCycleFromVersion(String cycleQueryVersion) {
        if (cycleQueryVersion == null) {
            return null;
        }
        return cycles.stream()
                .max((Comparator.comparingInt(o -> o.matchVersion(cycleQueryVersion))))
                .orElse(null);
    }

    public EolCycle findCycleFromCycle(String cycle) {
        if (cycle == null) {
            return null;
        }
        return cycles.stream()
                .filter(c -> c.getCycle().equals(cycle))
                .findFirst()
                .orElse(null);
    }

    public List findCyclesAfter(EolCycle cycle) {
        if (cycle == null) {
            return null;
        }

        final List result = new ArrayList<>();
        boolean found = false;

        for (EolCycle c : cycles) {
            if (found) {
                result.add(c);
            }
            if (c.equals(cycle)) {
                found = true;
            }
        }

        return result;
    }

    public List findCyclesBefore(EolCycle cycle) {
        if (cycle == null) {
            return null;
        }

        final List result = new ArrayList<>();
        boolean found = false;

        for (EolCycle c : cycles) {
            if (c.equals(cycle)) {
                found = true;
            }
            if (!found) {
                result.add(c);
            }
        }

        return result;
    }

    public EolCycle findNextSupportedCycle(EolCycle cycle) {
        if (cycle == null) {
            return null;
        }

        final List cyclesAfter = findCyclesAfter(cycle);
        if (cyclesAfter.isEmpty()) {
            return null;
        }

        for (EolCycle c : cyclesAfter) {
            final SupportState supportState = c.getSupportState();
            if (supportState == SupportState.SUPPORT || supportState == SupportState.UPCOMING_SUPPORT_END_DATE || supportState == SupportState.DISTANT_SUPPORT_END_DATE) {
                return c;
            }
        }

        return null;
    }

    public EolCycle findNextExtendedSupportCycle(EolCycle cycle) {
        if (cycle == null) {
            return null;
        }

        final List cyclesAfter = findCyclesAfter(cycle);
        if (cyclesAfter.isEmpty()) {
            return null;
        }

        for (EolCycle c : cyclesAfter) {
            final SupportState supportState = c.getExtendedSupportState();
            if (supportState == SupportState.SUPPORT || supportState == SupportState.UPCOMING_SUPPORT_END_DATE || supportState == SupportState.DISTANT_SUPPORT_END_DATE) {
                return c;
            }
        }

        return null;
    }

    /**
     * Finds the closest active LTS (Long Term Support) version cycle to the given cycle.
     * 

* Only returns cycles that have LTS support. Will first try to find a cycle that comes after the given cycle, then * as fallback will go back from the cycle and return the first cycle backwards that has LTS support. * * @param cycle the cycle to find the closest active LTS version cycle for * @return the closest active LTS version cycle, or null if no active LTS version cycle is found */ public EolCycle findClosestActiveLtsVersionCycle(EolCycle cycle) { if (cycle == null) { return null; } { final LtsState ltsState = cycle.getLtsState(); if (ltsState == LtsState.LTS || ltsState == LtsState.LTS_DATE_REACHED) { return cycle; } } final List cyclesAfter = findCyclesAfter(cycle); for (EolCycle c : cyclesAfter) { final LtsState ltsState = c.getLtsState(); if (ltsState == LtsState.LTS || ltsState == LtsState.LTS_DATE_REACHED) { return c; } } final List cyclesBefore = findCyclesBefore(cycle); for (int i = cyclesBefore.size() - 1; i >= 0; i--) { final EolCycle c = cyclesBefore.get(i); final LtsState ltsState = c.getLtsState(); if (ltsState == LtsState.LTS || ltsState == LtsState.LTS_DATE_REACHED) { return c; } } return null; } public EolCycle findLatestActiveLtsVersionCycle(EolCycle cycle) { if (cycle == null) { return null; } final List cyclesAfter = findCyclesAfter(cycle); for (int i = cyclesAfter.size() - 1; i >= 0; i--) { final EolCycle c = cyclesAfter.get(i); final LtsState ltsState = c.getLtsState(); if (ltsState == LtsState.LTS || ltsState == LtsState.LTS_DATE_REACHED) { return c; } } return null; } public JSONArray toJson() { final JSONArray json = new JSONArray(); for (EolCycle cycle : cycles) { json.put(cycle.toJson()); } return json; } public List toDocuments() { final List documents = new ArrayList<>(); for (EolCycle cycle : cycles) { documents.add(cycle.toDocument()); } return documents; } public static EolLifecycle fromJson(String product, JSONArray json) { final EolLifecycle productInfo = new EolLifecycle(product); for (int i = 0; i < json.length(); i++) { final EolCycle cycle = EolCycle.fromJson(json.getJSONObject(i)); cycle.setProduct(product); productInfo.addCycle(cycle); } return productInfo; } /** * Writes the product information to the given directory using the {@link EolLifecycle#toJson() JSON format} into * a file named {product}.json. * * @param dir the directory to write the product information to * @throws IOException if an I/O error occurs while writing the file */ public void writeToDirectory(File dir) throws IOException { final File file = new File(dir, product + ".json"); FileUtils.write(file, toJson().toString(), StandardCharsets.UTF_8); } public String toLink() { return "https://endoflife.date/" + product; } @Override public String toString() { return toJson().toString(); } public String getLatestVersion() { return cycles.stream() .map(EolCycle::getLatest) .peek(cycle -> { if (cycle == null) { LOG.warn("Cycle is null for product, will filter out: {}", product); LOG.warn(" All data: {}", this); } }) .filter(Objects::nonNull) .max(VersionComparator.INSTANCE) .orElse(null); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy