Skip to main content
summaryrefslogtreecommitdiffstats
blob: 4c82476bc66f70820711131ee54a04c764f0f607 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*********************************************************************
 * Copyright (c) 2004, 2007 Boeing
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Boeing - initial API and implementation
 **********************************************************************/

package org.eclipse.osee.framework.skynet.core.artifact;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.eclipse.osee.framework.core.data.ArtifactId;
import org.eclipse.osee.framework.core.data.ArtifactToken;
import org.eclipse.osee.framework.core.data.ArtifactTypeToken;
import org.eclipse.osee.framework.core.data.BranchId;
import org.eclipse.osee.framework.core.model.event.DefaultBasicGuidArtifact;
import org.eclipse.osee.framework.core.model.event.IBasicGuidRelation;
import org.eclipse.osee.framework.skynet.core.artifact.cache.ArtifactIdCache;

/**
 * @author Ryan D. Brooks
 */
public final class ArtifactCache {

   private static final ArtifactIdCache ID_CACHE = new ArtifactIdCache(2000);

   private ArtifactCache() {
      super();
   }

   /**
    * Cache the artifact so that we can avoid creating duplicate instances of an artifact
    */
   static void cache(Artifact artifact) {
      if (!artifact.isHistorical()) {
         ID_CACHE.cache(artifact);
      }
   }

   /**
    * <p>
    * This should NOT be called by applications unless extreme care is taken. Grabbing an artifact, then decaching, then
    * searching/loading the artifact by another operation can cause 2 current versions of the same artifact in the JVM.
    * This can cause problems changing the artifact and/or processing incoming events.
    * </p>
    */
   public static void deCache(Artifact artifact) {
      if (!artifact.isHistorical()) {
         ID_CACHE.deCache(artifact);
      }
   }

   /**
    * <p>
    * De-caches all artifacts from <code>HISTORICAL_CACHE</code> and <code>ACTIVE_CACHE</code> for a specific branch.
    * This method is usually called by a purge operation or at the end of a unit test/suite.</br>
    * </br>
    * This should NOT be called by applications unless extreme care is taken. Grabbing an artifact, then decaching, then
    * searching/loading the artifact by another operation can cause 2 current versions of the same artifact in the JVM.
    * This can cause problems changing the artifact and/or processing incoming events.
    * </p>
    *
    * @param branch of which artifacts (all) will be de-cache'ed.
    */
   public static void deCache(BranchId branch) {
      for (Artifact artifact : ID_CACHE.getAll()) {
         if (artifact.isOnBranch(branch)) {
            ID_CACHE.deCache(artifact);
         }
      }
   }

   public static String report() {
      StringBuilder sb = new StringBuilder();
      sb.append("Active:");
      sb.append(ID_CACHE.toString());
      return sb.toString();
   }

   public static Collection<Artifact> getDirtyArtifacts() {
      return ID_CACHE.getAllDirties();
   }

   /**
    * This method is called by attributes and relations when their dirty state changes. This way, when an artifact is
    * dirty we can hold onto a strong reference and when it is not dirty we can have a weak reference.
    */
   public static void updateCachedArtifact(ArtifactToken artifact) {
      ID_CACHE.updateReferenceType(artifact);
   }

   public static List<Artifact> getArtifactsByType(ArtifactTypeToken artifactType) {
      List<Artifact> artifacts = new LinkedList<>();
      for (Artifact artifact : ID_CACHE.getAll()) {
         if (artifact.isOfType(artifactType)) {
            artifacts.add(artifact);
            deCache(artifact);
         }
      }
      return artifacts;
   }

   public static Collection<Artifact> getActive(Collection<? extends DefaultBasicGuidArtifact> basicGuidArtifacts) {
      Set<Artifact> artifacts = new HashSet<>();
      for (DefaultBasicGuidArtifact guidArt : basicGuidArtifacts) {
         Artifact art = ID_CACHE.getByGuid(guidArt.getGuid(), guidArt.getBranch());
         if (art != null) {
            artifacts.add(art);
         }
      }
      return artifacts;
   }

   public static Artifact getActive(DefaultBasicGuidArtifact guidArt) {
      return getActive(guidArt.getGuid(), guidArt.getBranch());
   }

   private static Artifact getActiveA(IBasicGuidRelation guidRel) {
      return getActive(guidRel.getArtA().getGuid(), guidRel.getArtA().getBranch());
   }

   private static Artifact getActiveB(IBasicGuidRelation guidRel) {
      return getActive(guidRel.getArtB().getGuid(), guidRel.getArtB().getBranch());
   }

   /**
    * Returns loaded artifacts from either side of the relation
    */
   public static Collection<Artifact> getActive(IBasicGuidRelation guidRel) {
      return getActive(guidRel, null);
   }

   /**
    * Returns loaded artifacts from either side of the relation of type clazz
    */
   @SuppressWarnings("unchecked")
   public static <A extends Artifact> Collection<A> getActive(IBasicGuidRelation guidRel, Class<A> clazz) {
      List<A> arts = new ArrayList<>();
      Artifact artA = getActiveA(guidRel);
      if (artA != null) {
         if (clazz == null || clazz.isInstance(artA)) {
            arts.add((A) artA);
         }
      }
      Artifact artB = getActiveB(guidRel);
      if (artB != null) {
         if (clazz == null || clazz.isInstance(artB)) {
            arts.add((A) artB);
         }
      }
      return arts;
   }

   public static Artifact getActive(ArtifactId artId, BranchId branch) {
      return getActive(ArtifactToken.valueOf(artId, branch));
   }

   public static Artifact getActive(ArtifactToken artifact) {
      return ID_CACHE.getById(artifact);
   }

   public static Artifact getActive(String artGuid, BranchId branch) {
      return ID_CACHE.getByGuid(artGuid, branch);
   }

   public static Artifact getActive(Long artId, BranchId branch) {
      return getActive(ArtifactToken.valueOf(artId, branch));
   }
}

Back to the top