/*license*\
XBN-Java: Copyright (C) 2014, Jeff Epstein (aliteralmind __DASH__ github __AT__ yahoo __DOT__ com)
This software is dual-licensed under the:
- Lesser General Public License (LGPL) version 3.0 or, at your option, any later version;
- Apache Software License (ASL) version 2.0.
Either license may be applied at your discretion. More information may be found at
- http://en.wikipedia.org/wiki/Multi-licensing.
The text of both licenses is available in the root directory of this project, under the names "LICENSE_lgpl-3.0.txt" and "LICENSE_asl-2.0.txt". The latest copies may be downloaded at:
- LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
- ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
\*license*/
package com.github.xbn.neederneedable;
/**
<p>{@code Needer}s need another object, as created by a {@code Needable}.</p>
<p><i>This interface results in a number of unchecked-cast warnings, due to the possibility of multiple types of objects being needed by the same class. Type-safety is ensured by the {@code needed_class} parameter in {@link #startConfig(Class) startConfig(cls)}.</i></p>
* @see Needable
* @since 0.1.0
* @author Copyright (C) 2014, Jeff Epstein ({@code aliteralmind __DASH__ github __AT__ yahoo __DOT__ com}), dual-licensed under the LGPL (version 3.0 or later) or the ASL (version 2.0). See source code for details. <a href="http://xbnjava.aliteralmind.com">{@code http://xbnjava.aliteralmind.com}</a>, <a href="https://github.com/aliteralmind/xbnjava">{@code https://github.com/aliteralmind/xbnjava}</a>
**/
public interface Needer {
/**
<p>Start the configuration of a new object of a specific type.</p>
<p>This<ol>
<li>Calls <code><i>[{@link com.github.xbn.neederneedable.Needable Needable}]</i>.<!-- GENERIC PARAMETERS FAIL IN @link --><a href="Needable.html#startConfigReturnNeedable(R)">startConfigReturnNeedable</a>(this)</code></li>
<li>Sets {@link #isConfigActive() isConfigActive}{@code ()} to {@code true}.</li>
</ol>
* @param needed_class The type of object needed. Get with {@link #getNeededType() getNeededType}{@code ()}. For example: {@code Integer.class} or
<br/> {@code (Class<ListLister<E>>)((Class)ListLister.class))}
<br/>Why the crazy casting is necessary with generics:
<p><TABLE ALIGN="center" WIDTH="100%" BORDER="1" CELLSPACING="0" CELLPADDING="4" BGCOLOR="#EEEEEE"><TR ALIGN="left" VALIGN="middle">
<TD>From (viewed 1/4/2014)
<br/> <code><a href="http://stackoverflow.com/questions/7502243/java-casting-class-operator-used-on-a-generic-type-e-g-list-to-classlist">http://stackoverflow.com/questions/7502243/java-casting-class-operator-used-on-a-generic-type-e-g-list-to-classlist</a></code><P/>
<pre>{@literal Class<List<Integer>> tListInt3 =
(Class<List<Integer>>)((Class<Integer>)List.class);}</pre>
<p>doesn't work. you probably meant</p>
<pre>{@literal Class<List<Integer>> tListInt3 =
(Class<List<Integer>>)((Class)List.class);}</pre>
<p>we can always cast from one type to another by up-cast then down-cast
<br/> {@code Integer x = (Integer)(Object)"string";}</p>
<p>The type of {@code List.class} is {@code Class<List>} it is not a subtype/supertype of {@code Class<List<Whatever>>} therefore direct cast between the two types is illegal.</p>
<p>It can be argued that {@code Class<List<Integer>>} doesn't exist - there is only a class for {@code List} there is no such class for {@code List<Integer>} (which really is just {@code List} at runtime)</p>
</p>However, this is a flaw of Java type system; in practice we do need things like {@code Class<List<Integer>>}. Our solution - casting and pretending {@code Class<List<Int>>} exists - is likewise flawed - but it's not our fault.</TD>
</TR></TABLE></p>
* @exception IllegalStateException If {@link #isConfigActive() isConfigActive}{@code ()} is {@code true}.
*/
void startConfig(Class<?> needed_class);
/**
<p>Is an object being configured?.</p>
* @return {@code true} If {@link #startConfig(Class) startConfig(cls)} was more-recently called than {@link #neeadableSetsNeeded(Object) neeadableSetsNeeded(o)}.
*/
boolean isConfigActive();
/**
<p>The type of object currently being configured.</p>
* @see <code><!-- GENERIC PARAMETERS FAIL IN @link --><a href="Needable.html#startConfigReturnNeedable(R)">startConfigReturnNeedable</a>(R)</code>
* @see #isConfigActive()
*/
Class getNeededType();
/**
<p>Called by the {@code Needable} to set the fully configured object. This {@link com.github.xbn.neederneedable.Needable Needable} is the same one as called in the first step of {@link #startConfig(Class) startConfig(cls)}. This function is never called directly.</p>
<p>This sets<ol>
<li>{@code fully_configured} to an internal object.</li>
<li>{@link #isConfigActive() isConfigActive}{@code ()} to {@code false}.</li>
</ol>
* @exception IllegalStateException If {@code isConfigActive()} is {@code null}.
* @exception ClassCastException If <code>({@link #getNeededType() getNeededType}().isInstance(fully_configured))</code> is {@code false}. <i>{@code Needer}-s may need multiple types of objects, so {@code Needer<ASingleClassType>} is not possible. {@code <i>[Class]</i>.isInstance(o)} ensures that the needable-configuration completes as expected, and avoids an {@code instanceof} "switch" (if-then-else) block.</i>
*/
void neeadableSetsNeeded(Object fully_configured);
}