NonsenseShipOrPub.java
package net.zer0bandwidth.android.lib.nonsense;
import android.content.Context;
import net.zer0bandwidth.android.lib.R;
import net.zer0bandwidth.android.lib.text.format.TitleFormatter;
import java.util.Collection;
import java.util.Random;
/**
* Builds a random name of a ship… or a pub… or something.
*
* <p>Both ships and pubs seem to have names that follow the general pattern of
* "The <adjective> <noun>", like "The Salty Dog" or "The Mourning
* Glory" or "The Rapacious Tardigrade". OK, maybe not the last one. Anyway,
* since {@link NonsenseBuilder} worked out so well, and this is actually a
* <i>simpler</i> algorithm, it seemed only right to go ahead with this now.</p>
*
* <p>As with {@code NonsenseBuilder}, this class makes use of two of the array
* resources that are included with the library:</p>
*
* <ul>
* <li>{@link R.array#asNonsenseAdjectives}</li>
* <li>{@link R.array#asNonsenseNouns}</li>
* </ul>
*
* <p>Applications using this class may choose to have overrides for either or
* both of these string resources, in order to customize the text that might be
* rendered in the randomized names.</p>
*
* @since zer0bandwidth-net/android 0.1.5 (#11)
*/
public class NonsenseShipOrPub
implements NonsenseGenerator
{
/**
* The internal RNG of the builder, used to select each token in the name.
*/
protected static final Random RANDOM = new Random() ;
/**
* By default, this class will always begin the name with a "The". Use the
* {@link #setArticleChance(int)} method to alter the instance's chance at
* runtime.
* @see #m_nArticleChance
*/
protected static final int DEFAULT_ARTICLE_CHANCE = 100 ;
/** A context in which the string resources are available. */
protected Context m_ctx = null ;
/**
* The percent chance that the builder will begin the random name with
* "The". By default, this chance is 100%; consumers may change this by
* calling {@link #setArticleChance(int)}.
* @see #DEFAULT_ARTICLE_CHANCE
*/
protected int m_nArticleChance = DEFAULT_ARTICLE_CHANCE ;
/**
* A list of adjectives. This may be overridden with {@link #setAdjectives}.
*/
protected String[] m_asAdjectives = null ;
/**
* A list of nouns. This may be overridden with {@link #setNouns}.
*/
protected String[] m_asNouns = null ;
/**
* A constructor which sets the resource context.
* @param ctx a context in which string resources are available
*/
public NonsenseShipOrPub( Context ctx )
{
this.setContext( ctx )
.setAdjectives( R.array.asNonsenseAdjectives )
.setNouns( R.array.asNonsenseNouns )
;
}
/**
* Sets the resource context.
* @param ctx the context in which string resources are available
* @return (fluid)
*/
@Override
public NonsenseShipOrPub setContext( Context ctx )
{ m_ctx = ctx ; return this ; }
/**
* Sets the chance that the builder will begin the name with "The". By
* default, this chance is 100%.
* If the parameter given is less than 0 or greater than 100, then the new
* value will be silently ignored.
* @param nChance an integer between 0 and 100 (inclusive)
* @return (fluid)
*/
public NonsenseShipOrPub setArticleChance( int nChance )
{
if( nChance < 0 || nChance > 100 ) return this ; // trivially
m_nArticleChance = nChance ;
return this ;
}
/**
* Defines the set of adjectives that should be considered when generating
* the name.
* @param resAdjectives the resource ID of an array of adjectives
* @return (fluid)
*/
public NonsenseShipOrPub setAdjectives( int resAdjectives )
{
m_asAdjectives = m_ctx.getResources().getStringArray( resAdjectives ) ;
return this ;
}
/**
* Defines the set of adjectives that should be considered when generating
* the name.
* @param asAdjectives a collection of adjective strings
* @return (fluid)
*/
public NonsenseShipOrPub setAdjectives( Collection<String> asAdjectives )
{
m_asAdjectives =
asAdjectives.toArray( new String[asAdjectives.size()] ) ;
return this ;
}
/**
* Defines the set of nouns that should be considered when generating the
* name.
* @param resNouns the resource ID of an array of nouns
* @return (fluid)
*/
public NonsenseShipOrPub setNouns( int resNouns )
{
m_asNouns = m_ctx.getResources().getStringArray( resNouns ) ;
return this ;
}
/**
* Defines the set of nouns that should be considered when generating the
* name.
* @param asNouns a collection of noun strings
* @return (fluid)
*/
public NonsenseShipOrPub setNouns( Collection<String> asNouns )
{
m_asNouns = asNouns.toArray( new String[asNouns.size()] ) ;
return this ;
}
/**
* Generates the name.
* @return the name of a ship, or a pub, or whatever
*/
@SuppressWarnings("StringBufferReplaceableByString")
@Override
public String getString()
{
StringBuilder sb = new StringBuilder() ;
sb.append( this.getArticle() )
.append( m_asAdjectives[ RANDOM.nextInt( m_asAdjectives.length ) ] )
.append( " " )
.append( this.getStrippedNoun() )
;
return TitleFormatter.format( m_ctx, sb.toString() ) ;
}
/**
* Might start us off with ah "The". Or it might not.
* @return "The " or an empty string
*/
protected String getArticle()
{
if( m_nArticleChance == 0 ) return "" ; // trivially
if( m_nArticleChance < 100 && RANDOM.nextInt(100) >= m_nArticleChance )
return "" ; // trivially
return "The " ;
}
/**
* Ensures that we strip any article that was already included with the
* noun resource.
* @return the naked noun
*/
protected String getStrippedNoun()
{
String sNoun = m_asNouns[ RANDOM.nextInt( m_asNouns.length ) ] ;
if( Utils.startsWithArticle(sNoun) )
return (sNoun.split( " ", 2 ))[1] ;
else
return sNoun ;
}
}