();
for( VoterService service: vsRun.newVoterServiceArray() )
{
if( service instanceof PollService ) sList_poll.add( (PollService)service );
else sList_other.add( service );
}
serviceArray_polls = sList_poll.toArray( new PollService[sList_poll.size()] );
serviceArray_other = sList_other.toArray( new VoterService[sList_other.size()] );
}
private ConstructionContext cc() { return (ConstructionContext)constructionContext; } // nulled after init
// ````````````````````````````````````````````````````````````````````````````````````
// init for early use
private final File startupConfigurationFile = cc().startupConfigurationFile();
// ------------------------------------------------------------------------------------
/** The runtime configuration file for this meta-service. The language is JavaScript.
* There are restrictions on the {@linkplain votorola.g.script.JavaScriptIncluder
* character encoding}.
*
* @see mail-meta-service-run.js (example script)
* @see ../manual.xht#mail-meta-service-run.js
*/
@Warning( "thread restricted object, holds lock()" )
public JavaScriptIncluder runtimeConfigurationScript()
{
assert lock.isHeldByCurrentThread(); // this method is safe, but not the object
return runtimeConfigurationScript;
}
private final JavaScriptIncluder runtimeConfigurationScript = new JavaScriptIncluder(
new File( serviceDirectory(), "mail-meta-service-run.js" ));
/** Constructs the email address of a voter service.
*
* @return canonical email address
*
* @see #serviceName(InternetAddress)
* @see InternetAddressX#canonicalAddress(String)
*/
public String serviceEmail( final VoterService service )
{
assert lock.isHeldByCurrentThread();
try
{
final String serviceEmail = (String)runtimeConfigurationScript.invokeKnownFunction(
"serviceEmail", service );
return InternetAddressX.canonicalAddress( serviceEmail );
}
catch( Exception x ) { throw VotorolaRuntimeException.castOrWrapped( x ); }
}
/** Converts service email address into a service name.
*
* @see #serviceEmail(VoterService)
*/
public String serviceName( final InternetAddress serviceEmail )
{
assert lock.isHeldByCurrentThread();
try
{
final String serviceName = (String)runtimeConfigurationScript.invokeKnownFunction(
"serviceName", InternetAddressX.localPart( serviceEmail ));
return serviceName;
}
catch( Exception x ) { throw VotorolaRuntimeException.castOrWrapped( x ); }
}
// - V o t e r - S e r v i c e --------------------------------------------------------
public @Override Exception help( final String[] argv, final CommandResponder.Session session )
{
assert lock.isHeldByCurrentThread();
final ReplyBuilder replyB = session.replyBuilder();
helpA( session );
replyB.lappendlnn( "s.mail.MailMetaService.help.reply.summary.trailer(1)", name );
helpB( session );
helpC( session );
final String generalTitle =
replyB.bundle().getString( "s.mail.MailMetaService.help.reply.general" );
replyB.setWrapping( false ).appendln( generalTitle );
for( int c = generalTitle.length(); c > 0; --c ) replyB.append( '=' );
replyB.appendlnn().setWrapping( true );
replyB.indent( 4 );
replyB.lappendlnn( "s.mail.MailMetaService.help.reply.general.body" );
replyB.indent( 4 );
replyB.lappendlnn( "a.response.CR_Help.commandName" );
replyB.exdent( 8 );
if( serviceArray_other == null ) init_2(); // lazily, after all services have been created (not just the standard ones), including this meta-service
assert serviceArray_other.length > 0: "this meta-service is listed, at the very least";
if( serviceArray_polls.length > 0 )
{
listServices(
replyB.bundle().getString( "s.mail.MailMetaService.serviceTypeTitle.polls" ),
serviceArray_polls, session );
}
listServices( replyB.bundle().getString( "s.mail.MailMetaService.serviceTypeTitle.other" ),
serviceArray_other, session );
return null;
}
/** @see ../manual.xht#mail-meta-service.js
*/
public @ThreadSafe @Override File startupConfigurationFile()
{
return startupConfigurationFile;
}
/** A brief description of this meta-service, same as {@linkplain
* VoteServer#summaryDescription() the vote-server's}.
*/
public @Override String summaryDescription() { return vsRun.voteServer().summaryDescription(); }
/** The title of this meta-service, which is the same as the {@linkplain
* VoteServer#title() vote-server's title}.
*/
public @Override String title() { return vsRun.voteServer().title(); }
// ====================================================================================
/** A context for configuring the mail interface's {@linkplain MailMetaService voter
* meta-service}. The meta-service is configured by its {@linkplain
* #startupConfigurationFile startup configuration file}, which contains a script (s)
* for that purpose. During construction of the meta-service, an instance of this
* context (metaCC) is passed to s, via s::constructingMailMetaService(metaCC).
*
* There are no configuration items, at present.
*/
public static @ThreadSafe final class ConstructionContext
extends VoterService.ConstructionContext
{
/** Constructs the complete configuration of the meta-service, and runs sanity
* tests on it.
*
* @param s the compiled startup configuration script
*/
public static ConstructionContext configure( final VoteServer voteServer,
JavaScriptIncluder s ) throws ScriptException
{
final ConstructionContext cc = new ConstructionContext( voteServer, s );
s.invokeKnownFunction( "constructingMailMetaService", cc );
return cc;
}
private ConstructionContext( VoteServer voteServer, JavaScriptIncluder s )
{
// super( voteServer.name(), s );
/// but since names aren't supposed to change anymore, this is better:
super( "mail", s );
}
// --------------------------------------------------------------------------------
// nothing here, at the moment
}
//// P r i v a t e ///////////////////////////////////////////////////////////////////////
private void listServices( final String serviceTypeTitle,
final VoterService[] serviceArray, final CommandResponder.Session session )
{
assert lock.isHeldByCurrentThread();
final ReplyBuilder replyB = session.replyBuilder();
replyB.setWrapping( false ).appendln( serviceTypeTitle );
for( int c = serviceTypeTitle.length(); c > 0; --c ) replyB.append( '=' );
replyB.appendlnn().setWrapping( true ).indent( 4 );
for( VoterService service: serviceArray )
{
replyB.appendlnn( service.name() );
replyB.indent( 4 );
replyB.appendln( service.title() );
replyB.appendlnn( serviceEmail( service ));
if( service.equals( MailMetaService.this ))
{
replyB.lappendlnn( "s.mail.MailMetaService.help.reply.self" );
}
replyB.exdent( 4 );
}
replyB.exdent( 4 );
}
private PollService[] serviceArray_polls; // final after init_2()
private VoterService[] serviceArray_other; // final after init_2()
}