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

sirius.kernel.di.transformers.Composable Maven / Gradle / Ivy

Go to download

Provides common core classes and the microkernel powering all Sirius applications

There is a newer version: 12.9.1
Show newest version
/*
 * Made with all the love in the world
 * by scireum in Remshalden, Germany
 *
 * Copyright by scireum GmbH
 * http://www.scireum.de - [email protected]
 */

package sirius.kernel.di.transformers;

import com.google.common.collect.Maps;
import sirius.kernel.commons.Strings;
import sirius.kernel.di.std.Part;

import javax.annotation.Nonnull;
import java.util.Map;
import java.util.Optional;

/**
 * Provides a basic implementation fo {@link Transformable} which supports a composition pattern.
 * 

* Next to the Adapter Pattern supported via {@link Transformers}, this implementation permits to * add components via the attach methods which can later be queried via tryAs, as and is. *

* This class can be used as base class or embedded into another class (using {@link #Composable(Object)}) to * make it Transformable. *

*/ public class Composable implements Transformable { private Object source; protected Map, Object> components; private static final Object NULL = new Object(); @Part private static Transformers adapters; /** * Default constructor used, when Composable is used as parent class. */ public Composable() { this.source = this; } /** * Provides a constructor which can be used to support the composition pattern. * * @param source the class or object which is made {@link Transformable}. */ public Composable(Object source) { this.source = source; } @Override public boolean is(@Nonnull Class adapterType) { if (adapterType.isAssignableFrom(source.getClass())) { return true; } if (components != null) { Object result = components.get(adapterType); if (result != null) { return result != NULL; } } return tryAs(adapterType).isPresent(); } @SuppressWarnings("unchecked") @Override public A as(@Nonnull Class adapterType) { if (adapterType.isAssignableFrom(source.getClass())) { return (A) this; } return tryAs(adapterType).orElseThrow(() -> { return new IllegalArgumentException(Strings.apply("Cannot transform %s into %s", getClass().getName(), adapterType.getName())); }); } @SuppressWarnings("unchecked") @Override public Optional tryAs(@Nonnull Class adapterType) { if (adapterType.isAssignableFrom(source.getClass())) { return Optional.of((A) this); } if (components != null) { Object result = components.get(adapterType); if (result != null) { return unwrapComponent(result); } } Object result = adapters.make(source, adapterType); if (result == null) { result = NULL; } attach(adapterType, result); return unwrapComponent(result); } @SuppressWarnings("unchecked") private Optional unwrapComponent(Object result) { if (result == NULL) { return Optional.empty(); } else { return Optional.of((A) result); } } /** * Adds the given component as instance for the given type. * * @param type the type of the component which can be used to later retrieve the component * @param component the component itself * @param the generic type which ensures, that the component actually implements the given type */ public void attach(Class type, T component) { if (components == null) { components = Maps.newHashMap(); } components.put(type, component); } /** * Adds the given component as instance for its class. *

* This is a boilerplate method for {@code attach(component.getClass(), component)}. * * @param component the component to attach for its own class */ public void attach(Object component) { attach(component.getClass(), component); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy