@Before
  public void setUp() {
    this.serializer = new DefaultStringEntityReferenceSerializer();

    this.resolver = new DefaultStringEntityReferenceResolver();
    final EntityReferenceValueProvider mockValueProvider =
        this.mockery.mock(EntityReferenceValueProvider.class);
    ReflectionUtils.setFieldValue(this.resolver, "provider", mockValueProvider);

    this.mockery.checking(
        new Expectations() {
          {
            allowing(mockValueProvider).getDefaultValue(EntityType.WIKI);
            will(returnValue(DEFAULT_WIKI));
            allowing(mockValueProvider).getDefaultValue(EntityType.SPACE);
            will(returnValue(DEFAULT_SPACE));
            allowing(mockValueProvider).getDefaultValue(EntityType.DOCUMENT);
            will(returnValue(DEFAULT_PAGE));
            allowing(mockValueProvider).getDefaultValue(EntityType.ATTACHMENT);
            will(returnValue(DEFAULT_ATTACHMENT));
            allowing(mockValueProvider).getDefaultValue(EntityType.OBJECT);
            will(returnValue(DEFAULT_OBJECT));
            allowing(mockValueProvider).getDefaultValue(EntityType.OBJECT_PROPERTY);
            will(returnValue(DEFAULT_OBJECT_PROPERTY));
            allowing(mockValueProvider).getDefaultValue(EntityType.CLASS_PROPERTY);
            will(returnValue(DEFAULT_CLASS_PROPERTY));
          }
        });
  }
  /**
   * @param manager the component manager to use to dynamically register components
   * @param classLoader the classloader to use to look for the Component list declaration file (
   *     {@code META-INF/components.txt})
   * @param componentDeclarations the declarations of components to register
   * @since 4.0M1
   */
  public void unregister(
      ComponentManager manager,
      ClassLoader classLoader,
      List<ComponentDeclaration> componentDeclarations) {
    for (ComponentDeclaration componentDeclaration : componentDeclarations) {
      try {
        for (ComponentDescriptor<?> componentDescriptor :
            getComponentsDescriptors(
                classLoader.loadClass(componentDeclaration.getImplementationClassName()))) {
          manager.unregisterComponent(componentDescriptor);

          if (componentDescriptor.getRoleType() instanceof ParameterizedType) {
            Class roleClass = ReflectionUtils.getTypeClass(componentDescriptor.getRoleType());

            DefaultComponentDescriptor<?> classComponentDescriptor =
                new DefaultComponentDescriptor(componentDescriptor);
            classComponentDescriptor.setRoleType(roleClass);

            manager.unregisterComponent(classComponentDescriptor);
          }
        }
      } catch (ClassNotFoundException e) {
        getLogger()
            .warn(
                "Can't find any existing component with class [{}]. Ignoring it.",
                componentDeclaration.getImplementationClassName());
      }
    }
  }
  // Only do once, because components are stored statically within various classes,
  // which causes problems with changing genetics mocks
  @BeforeClass
  @SuppressWarnings("unchecked")
  public static void setupComponents() throws ComponentLookupException, CacheException {
    ComponentManager componentManager = mock(ComponentManager.class);
    Provider<ComponentManager> mockProvider = mock(Provider.class);
    // This is a bit fragile, let's hope the field name doesn't change
    ReflectionUtils.setFieldValue(new ComponentManagerRegistry(), "cmProvider", mockProvider);
    when(mockProvider.get()).thenReturn(componentManager);

    CacheManager cacheManager = mock(CacheManager.class);
    when(componentManager.getInstance(CacheManager.class)).thenReturn(cacheManager);

    CacheFactory cacheFactory = mock(CacheFactory.class);
    when(cacheManager.getLocalCacheFactory()).thenReturn(cacheFactory);

    Cache<Exome> cache = mock(Cache.class);
    doReturn(cache).when(cacheFactory).newCache(Matchers.any(CacheConfiguration.class));
    doReturn(null).when(cache).get(Matchers.anyString());

    // Wire up mocked genetics
    exomeManager = mock(ExomeManager.class);
    when(componentManager.getInstance(ExomeManager.class, "exomiser")).thenReturn(exomeManager);

    // Use a real GenotypeManager
    PatientGenotypeManager genotypeManager = new DefaultPatientGenotypeManager();
    when(componentManager.getInstance(PatientGenotypeManager.class)).thenReturn(genotypeManager);
  }
  /**
   * @param superType the type implemented/extended by the root class
   * @param rootClass the class containing the parameters
   * @param parameters the generic parameters
   * @param targetClass the target class
   * @return the passed type with the real parameters
   */
  private static Type resolveType(
      Type superType, Class<?> rootClass, Type[] parameters, Class<?> targetClass) {
    Type newType = superType;

    Class<?> interfaceClass;
    Type[] interfaceParameters;

    if (newType instanceof ParameterizedType) {
      ParameterizedType interfaceParameterizedType = (ParameterizedType) newType;

      interfaceClass = ReflectionUtils.getTypeClass(newType);
      Type[] variableParameters = interfaceParameterizedType.getActualTypeArguments();

      interfaceParameters =
          ReflectionUtils.resolveSuperArguments(variableParameters, rootClass, parameters);

      if (interfaceParameters == null) {
        newType = interfaceClass;
      } else if (interfaceParameters != variableParameters) {
        newType =
            new DefaultParameterizedType(
                interfaceParameterizedType.getOwnerType(), interfaceClass, interfaceParameters);
      }
    } else if (newType instanceof Class) {
      interfaceClass = (Class<?>) newType;
      interfaceParameters = null;
    } else {
      return null;
    }

    if (interfaceClass == targetClass) {
      return newType;
    }

    return resolveType(interfaceClass, interfaceParameters, targetClass);
  }
  /**
   * @param method the method associated to the element
   * @param index the method parameter index
   * @param type the method parameter type
   * @return the associated {@link FilterElementParameterDescriptor}
   */
  private FilterElementParameterDescriptor<?> createFilterElementParameter(
      Method method, int index, Type type) {
    // @Name
    List<Name> nameAnnotations =
        ReflectionMethodUtils.getMethodParameterAnnotations(method, index, Name.class, true);

    String name;
    if (!nameAnnotations.isEmpty()) {
      name = nameAnnotations.get(0).value();
    } else {
      // Fallback on reflection to get the parameter name
      Parameter parameter = method.getParameters()[index];
      name = parameter.isNamePresent() ? method.getParameters()[index].getName() : null;
    }

    // @Default
    List<Default> defaultAnnotations =
        ReflectionMethodUtils.getMethodParameterAnnotations(method, index, Default.class, true);

    Object defaultValue;
    if (!defaultAnnotations.isEmpty()) {
      defaultValue = defaultAnnotations.get(0).value();

      if (defaultValue != null) {
        try {
          defaultValue = this.converter.convert(type, defaultValue);
        } catch (ConversionException e) {
          // TODO: remove that hack when String -> Map support is added to xwiki-properties
          if (ReflectionUtils.getTypeClass(type) == Map.class
              && ((String) defaultValue).isEmpty()) {
            defaultValue = Collections.EMPTY_MAP;
          } else {
            throw e;
          }
        }
      }
    } else {
      defaultValue = null;
    }

    return new FilterElementParameterDescriptor<Object>(index, name, type, defaultValue);
  }
  /**
   * Check that an extension is effectively available in the given namespace and that the
   * corresponding component manager provide the expected default implementation.
   *
   * @param role the role expected to be provided by the extension
   * @param implementation the implementation expected for the given role
   * @param namespace the namespace where the extension is expected to installed
   * @param <T> the role class
   * @return the effective role class in the extension class loader
   * @throws Exception on error
   */
  private <T> Type checkJarExtensionAvailability(
      Type role, Class<? extends T> implementation, String namespace) throws Exception {
    ClassLoader extensionLoader = getExtensionClassloader(namespace);
    Assert.assertNotNull(extensionLoader);
    Assert.assertNotSame(this.testApplicationClassloader, extensionLoader);

    Type loadedRole = getLoadedType(role, extensionLoader);
    // Ensure the loaded role does not came from the application classloader (a check to validate
    // the test)
    Assert.assertFalse(loadedRole.equals(role));

    if (namespace != null) {
      try {
        this.jarExtensionClassLoader
            .getURLClassLoader(null, false)
            .loadClass(ReflectionUtils.getTypeClass(loadedRole).getName());
        Assert.fail("the interface should not be in the root class loader");
      } catch (ClassNotFoundException expected) {
        // expected
      }
    }

    // check components managers
    Class<?> componentInstanceClass = null;
    if (namespace != null) {
      componentInstanceClass =
          getExtensionComponentManager(namespace).getInstance(loadedRole).getClass();

      try {
        getComponentManager().getInstance(loadedRole);
        Assert.fail("the component should not be in the root component manager");
      } catch (ComponentLookupException expected) {
        // expected
      }
    } else {
      componentInstanceClass = getComponentManager().getInstance(loadedRole).getClass();
    }
    Assert.assertEquals(implementation.getName(), componentInstanceClass.getName());
    Assert.assertNotSame(implementation, componentInstanceClass);

    return loadedRole;
  }
  /**
   * Create a component descriptor for the passed component implementation class, hint and component
   * role class.
   *
   * @param componentClass the component implementation class
   * @param hint the hint
   * @param componentRoleClass the component role class
   * @return the component descriptor with resolved component dependencies
   */
  private ComponentDescriptor createComponentDescriptor(
      Class<?> componentClass, String hint, Class<?> componentRoleClass) {
    DefaultComponentDescriptor descriptor = new DefaultComponentDescriptor();
    descriptor.setRole(componentRoleClass);
    descriptor.setImplementation(componentClass);
    descriptor.setRoleHint(hint);
    descriptor.setInstantiationStrategy(createComponentInstantiationStrategy(componentClass));

    // Set the injected fields.
    // Note: that we need to find all fields since we can have some inherited fields which are
    // annotated in a
    // superclass. Since Java doesn't offer a method to return all fields we have to traverse all
    // parent classes
    // looking for declared fields.
    for (Field field : ReflectionUtils.getAllFields(componentClass)) {
      ComponentDependency dependency = createComponentDependency(field);
      if (dependency != null) {
        descriptor.addComponentDependency(dependency);
      }
    }

    return descriptor;
  }
Example #8
0
 /**
  * @return the component role as class
  * @since 4.0M1
  */
 @SuppressWarnings("unchecked")
 public Class<T> getRoleClass() {
   return ReflectionUtils.getTypeClass(this.role);
 }
  public Set<Type> findComponentRoleTypes(Class<?> componentClass, Type[] parameters) {
    // Note: We use a Set to ensure that we don't register duplicate roles.
    Set<Type> types = new LinkedHashSet<Type>();

    Component component = componentClass.getAnnotation(Component.class);
    if (component != null && component.roles().length > 0) {
      types.addAll(Arrays.asList(component.roles()));
    } else {
      // Look in both superclass and interfaces for @ComponentRole or javax.inject.Provider
      for (Type interfaceType : componentClass.getGenericInterfaces()) {
        Class<?> interfaceClass;
        Type[] interfaceParameters;

        if (interfaceType instanceof ParameterizedType) {
          ParameterizedType interfaceParameterizedType = (ParameterizedType) interfaceType;

          interfaceClass = ReflectionUtils.getTypeClass(interfaceType);
          Type[] variableParameters = interfaceParameterizedType.getActualTypeArguments();

          interfaceParameters =
              ReflectionUtils.resolveSuperArguments(variableParameters, componentClass, parameters);

          if (interfaceParameters == null) {
            interfaceType = interfaceClass;
          } else if (interfaceParameters != variableParameters) {
            interfaceType =
                new DefaultParameterizedType(
                    interfaceParameterizedType.getOwnerType(), interfaceClass, interfaceParameters);
          }
        } else if (interfaceType instanceof Class) {
          interfaceClass = (Class<?>) interfaceType;
          interfaceParameters = null;
        } else {
          continue;
        }

        // Handle superclass of interfaces
        types.addAll(findComponentRoleTypes(interfaceClass, interfaceParameters));

        // Handle interfaces directly declared in the passed component class
        if (ReflectionUtils.getDirectAnnotation(Role.class, interfaceClass) != null) {
          types.add(interfaceType);
        }

        // Handle javax.inject.Provider
        if (Provider.class.isAssignableFrom(interfaceClass)) {
          types.add(interfaceType);
        }

        // Handle ComponentRole (retro-compatibility since 4.0M1)
        if (ReflectionUtils.getDirectAnnotation(ComponentRole.class, interfaceClass) != null) {
          types.add(interfaceClass);
        }
      }

      // Note that we need to look into the superclass since the super class can itself implements
      // an interface
      // that has the @ComponentRole annotation.
      Type superType = componentClass.getGenericSuperclass();
      if (superType != null && superType != Object.class) {
        if (superType instanceof ParameterizedType) {
          ParameterizedType superParameterizedType = (ParameterizedType) superType;
          types.addAll(
              findComponentRoleTypes(
                  (Class) superParameterizedType.getRawType(),
                  ReflectionUtils.resolveSuperArguments(
                      superParameterizedType.getActualTypeArguments(),
                      componentClass,
                      parameters)));
        } else if (superType instanceof Class) {
          types.addAll(findComponentRoleTypes((Class) superType, null));
        }
      }
    }

    return types;
  }