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

mockit.internal.faking.FakeStates Maven / Gradle / Ivy

/*
 * Copyright (c) 2006 Rogério Liesenfeld
 * This file is subject to the terms of the MIT license (see LICENSE.txt).
 */
package mockit.internal.faking;

import java.util.*;
import java.util.Map.*;
import java.util.regex.*;
import javax.annotation.*;

import mockit.internal.util.*;

/**
 * Holds state associated with fake class containing {@linkplain mockit.Mock annotated fakes}.
 */
public final class FakeStates
{
   private static final Pattern SPACE = Pattern.compile(" ");

   /**
    * For each fake instance and each {@code @Mock} method containing the {@code Invocation} parameter, a runtime state
    * will be kept here.
    */
   @Nonnull private final Map> fakesToFakeStates;
   @Nonnull private final Map> startupFakesToFakeStates;

   public FakeStates()
   {
      startupFakesToFakeStates = new IdentityHashMap>(2);
      fakesToFakeStates = new IdentityHashMap>(8);
   }

   void addStartupFakeAndItsFakeStates(@Nonnull Object fake, @Nonnull List fakeStates)
   {
      startupFakesToFakeStates.put(fake, fakeStates);
   }

   void addFakeAndItsFakeStates(@Nonnull Object fake, @Nonnull List fakeStates)
   {
      fakesToFakeStates.put(fake, fakeStates);
   }

   public void copyFakeStates(@Nonnull Object previousFake, @Nonnull Object newFake)
   {
      List fakeStates = fakesToFakeStates.get(previousFake);

      if (fakeStates != null) {
         List copiedFakeStates = new ArrayList(fakeStates.size());

         for (FakeState fakeState : fakeStates) {
            copiedFakeStates.add(new FakeState(fakeState));
         }

         fakesToFakeStates.put(newFake, copiedFakeStates);
      }
   }

   public void removeClassState(@Nonnull Class redefinedClass, @Nullable String internalNameForOneOrMoreFakeClasses)
   {
      removeFakeStates(redefinedClass);

      if (internalNameForOneOrMoreFakeClasses != null) {
         if (internalNameForOneOrMoreFakeClasses.indexOf(' ') < 0) {
            removeFakeStates(internalNameForOneOrMoreFakeClasses);
         }
         else {
            String[] fakeClassesInternalNames = SPACE.split(internalNameForOneOrMoreFakeClasses);

            for (String fakeClassInternalName : fakeClassesInternalNames) {
               removeFakeStates(fakeClassInternalName);
            }
         }
      }
   }

   private void removeFakeStates(@Nonnull Class redefinedClass)
   {
      Iterator> itr = fakesToFakeStates.values().iterator();

      while (itr.hasNext()) {
         List fakeStates = itr.next();
         FakeState fakeState = fakeStates.get(0);

         if (fakeState.getRealClass() == redefinedClass) {
            fakeStates.clear();
            itr.remove();
         }
      }
   }

   private void removeFakeStates(@Nonnull String fakeClassInternalName)
   {
      Class fakeClass = ClassLoad.loadClass(fakeClassInternalName.replace('/', '.'));
      Iterator>> itr = fakesToFakeStates.entrySet().iterator();

      while (itr.hasNext()) {
         Entry> fakeAndFakeStates = itr.next();
         Object fake = fakeAndFakeStates.getKey();

         if (fake.getClass() == fakeClass) {
            itr.remove();
         }
      }
   }

   public boolean updateFakeState(@Nonnull Object fake, int fakeStateIndex)
   {
      FakeState fakeState = getFakeState(fake, fakeStateIndex);
      return fakeState.update();
   }

   @Nonnull
   FakeState getFakeState(@Nonnull Object fake, int fakeStateIndex)
   {
      List fakeStates = startupFakesToFakeStates.get(fake);

      if (fakeStates == null) {
         fakeStates = fakesToFakeStates.get(fake);
      }

      FakeState fakeState = fakeStates.get(fakeStateIndex);
      assert fakeState != null;
      return fakeState;
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy