View Javadoc
1   /*
2    * This file is part of dependency-check-core.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * Copyright (c) 2020 Jeremy Long. All Rights Reserved.
17   */
18  package org.owasp.dependencycheck.data.update.cpe;
19  
20  import java.util.HashMap;
21  import java.util.Map;
22  import org.apache.commons.lang3.StringUtils;
23  
24  import org.owasp.dependencycheck.utils.Pair;
25  import org.slf4j.Logger;
26  import org.slf4j.LoggerFactory;
27  
28  /**
29   *
30   * @author Jeremy Long
31   */
32  public final class CpeEcosystemCache {
33  
34      /**
35       * The keyword/ecosystem used when multiple ecosystems have been identified.
36       */
37      private static final String MULTIPLE_ECOSYSTEMS_IDENTIFIED = "MULTIPLE";
38      /**
39       * The cache of CPE to ecosystem mappings.
40       */
41      private static Map<Pair<String, String>, String> cache = new HashMap<>();
42      /**
43       * The map of ecosystem entries that have been updated.
44       */
45      private static Map<Pair<String, String>, String> changed = new HashMap<>();
46  
47      private CpeEcosystemCache() {
48          //empty constructor for utility class
49      }
50      /**
51       * The logger.
52       */
53      private static final Logger LOGGER = LoggerFactory.getLogger(CpeEcosystemCache.class);
54  
55      //CSOFF: EmptyBlock
56      /**
57       * Returns the ecosystem for the given CPE (vendor, product). If the CPE has
58       * a different ecosystem previously identified the ecosystem will be updated
59       * to Multiple; otherwise, if an ecosystem is provided it will be cached for
60       * future matching.
61       *
62       * @param vendor the vendor for the CPE
63       * @param product the product for the CPE
64       * @param identifiedEcosystem the ecosystem identified for a CVE.
65       * @return the ecosystem
66       */
67      public static synchronized String getEcosystem(String vendor, String product, String identifiedEcosystem) {
68          final Pair<String, String> key = new Pair<>(vendor, product);
69          final String current = cache.get(key);
70          String result = null;
71          if (current == null) {
72              if (!StringUtils.isBlank(identifiedEcosystem)) {
73                  cache.put(key, identifiedEcosystem);
74                  changed.put(key, identifiedEcosystem);
75                  result = identifiedEcosystem;
76              }
77          } else if (MULTIPLE_ECOSYSTEMS_IDENTIFIED.equals(current)) {
78              //do nothing - result is already null
79          } else if (current.equals(identifiedEcosystem) || identifiedEcosystem == null) {
80              result = current;
81          } else {
82              cache.put(key, MULTIPLE_ECOSYSTEMS_IDENTIFIED);
83              changed.put(key, MULTIPLE_ECOSYSTEMS_IDENTIFIED);
84          }
85          return result;
86      }
87      //CSON: EmptyBlock
88  
89      /**
90       * Sets the ecosystem cache and resets the changed map.
91       *
92       * @param cache the new CPE to ecosystem mapping
93       */
94      public static synchronized void setCache(Map<Pair<String, String>, String> cache) {
95          CpeEcosystemCache.cache = cache;
96          CpeEcosystemCache.changed = new HashMap<>();
97      }
98  
99      /**
100      * Returns the map of changed CPE to ecosystem mappings.
101      *
102      * @return the map of changed CPE to ecosystem mappings
103      */
104     public static synchronized Map<Pair<String, String>, String> getChanged() {
105         return CpeEcosystemCache.changed;
106     }
107 
108     /**
109      * Returns <code>true</code> if the ecosystem cache is empty; otherwise
110      * <code>false</code>.
111      *
112      * @return <code>true</code> if the ecosystem cache is empty; otherwise
113      * <code>false</code>
114      */
115     public static synchronized boolean isEmpty() {
116         return CpeEcosystemCache.cache.isEmpty();
117     }
118 }