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

io.github.amayaframework.di.Artifact Maven / Gradle / Ivy

Go to download

A framework responsible for monitoring and automating the dependency injection process.

There is a newer version: 2.2.0
Show newest version
package io.github.amayaframework.di;

import java.util.Arrays;
import java.util.Objects;

/**
 * The main entity necessary to formalize the task of injecting dependencies.
 * It is a universal descriptor for services containing a java type and some metadata array.
 * The need to use an {@link Artifact}, rather than an instance of a {@link Class},
 * is due to the need to specialize additional meta-information about types.
 * For example, in the case shown below, in order to unambiguously solve the dependency,
 * in addition to type information, it is necessary to save information about generics:
 * 
 *     class AuthorizeService {
 *         public AuthorizeService(
 *          Database<User> users,
 *          Database<Session> sessions) {
 *             ...
 *         }
 *     }
 * 
* However, given the variety of existing approaches to organizing DI, only information about generics is not always * used, therefore, for universalization, metadata is presented as an ordered array of {@link Object} instances. * The {@link Artifact} can (and should) be used as a key in hash structures. * The implementation of {@link Artifact#hashCode()} and {@link Artifact#equals(Object)} takes into account * the order of metadata. */ public final class Artifact { private final Class type; private final Object[] metadata; /** * Constructs artifact, containing the specified class and metadata array. * * @param type the specified class, must be non-null * @param metadata the specified metadata, may be null */ public Artifact(Class type, Object[] metadata) { this.type = Objects.requireNonNull(type); this.metadata = metadata; } /** * Constructs artifact, containing the specified class and metadata object. * * @param type the specified class, must be non-null * @param metadata the specified metadata, may be null */ public Artifact(Class type, Object metadata) { this(type, new Object[]{metadata}); } /** * Constructs artifact, containing the specified class. * * @param type the specified class, must be non-null */ public Artifact(Class type) { this.type = Objects.requireNonNull(type); this.metadata = null; } /** * Creates artifact, containing the specified class and metadata objects. Varargs implementation. * The most preferred and safe way to create an artifact for the user. * Example of creating an artifact for a complex generic declaration: *
     *     Map<List<String>, List<Integer>[]> =>
     *     Artifact.of(Map.class,
     *         Artifact.of(List.class, String.class),
     *         Artifact.of(List[].class, Integer.class)
     *     )
     * 
* * @param type the specified class, must be non-null * @param metadata the specified metadata, may be null * @return {@link Artifact} instance */ public static Artifact of(Class type, Object... metadata) { return new Artifact(type, metadata); } /** * Creates artifact, containing the specified class. * The most preferred and safe way to create an artifact for the user. * * @param type the specified class, must be non-null * @return {@link Artifact} instance */ public static Artifact of(Class type) { return new Artifact(type); } /** * Returns artifact type. * * @return non-null {@link Class} instance */ public Class getType() { return type; } /** * Returns artifact metadata. Changing the resulting array will not change the artifact. * * @return null or {@link Object} array */ public Object[] getMetadata() { return metadata == null ? null : metadata.clone(); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; var artifact = (Artifact) o; return type.equals(artifact.type) && Arrays.equals(metadata, artifact.metadata); } @Override public int hashCode() { if (metadata == null) { return type.hashCode(); } var ret = 31 + type.hashCode(); for (var element : metadata) { ret = 31 * ret + (element == null ? 0 : element.hashCode()); } return ret; } @Override public String toString() { return "Artifact{" + "type=" + type + ", metadata=" + Arrays.toString(metadata) + '}'; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy