Event definition loader
Implemented the ImportEvents command line tool, which allows event definitions to be imported. In all cases the tool will try to import all definitions; if an error occurs, the process continues but the transaction is rolled back. It skips existing definitions rather than taking the risk of doing something inappropriate (e.g. deletion of existing events).
This commit is contained in:
parent
c8f19a4c06
commit
75c5245764
15 changed files with 1334 additions and 0 deletions
|
@ -31,6 +31,7 @@ cat > data-source.xml <<EOF
|
|||
EOF
|
||||
|
||||
java legacyworlds-server-main-*.jar --run-tool ImportText data/i18n-text.xml || exit 1
|
||||
java legacyworlds-server-main-*.jar --run-tool ImportEvents data/event-definitions.xml || exit 1
|
||||
java legacyworlds-server-main-*.jar --run-tool ImportResources data/resources.xml || exit 1
|
||||
java legacyworlds-server-main-*.jar --run-tool ImportTechs data/techs.xml || exit 1
|
||||
java legacyworlds-server-main-*.jar --run-tool ImportTechGraph data/tech-graph.xml || exit 1
|
||||
|
|
|
@ -0,0 +1,715 @@
|
|||
package com.deepclone.lw.cli;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.postgresql.util.PGobject;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.context.support.FileSystemXmlApplicationContext;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import com.deepclone.lw.cli.xmlimport.EventDefinitionLoader;
|
||||
import com.deepclone.lw.cli.xmlimport.data.DataImportException;
|
||||
import com.deepclone.lw.cli.xmlimport.data.evdef.EntityEventField;
|
||||
import com.deepclone.lw.cli.xmlimport.data.evdef.EventDefinition;
|
||||
import com.deepclone.lw.cli.xmlimport.data.evdef.EventDefinitions;
|
||||
import com.deepclone.lw.cli.xmlimport.data.evdef.EventFieldBase;
|
||||
import com.deepclone.lw.cli.xmlimport.data.evdef.IntegerEventField;
|
||||
import com.deepclone.lw.cli.xmlimport.data.evdef.RealEventField;
|
||||
import com.deepclone.lw.cli.xmlimport.data.evdef.TextEventField;
|
||||
import com.deepclone.lw.utils.StoredProc;
|
||||
|
||||
|
||||
|
||||
public class ImportEvents
|
||||
extends CLITool
|
||||
{
|
||||
|
||||
/**
|
||||
* Error codes that may be returned by the various import stored procedures; see the
|
||||
* corresponding SQL code for details about each value.
|
||||
*/
|
||||
private static enum SPErrorCode {
|
||||
OK ,
|
||||
BAD_ID ,
|
||||
BAD_STRINGS ,
|
||||
DUPLICATE ,
|
||||
BAD_SPEC ,
|
||||
NO_DATA
|
||||
};
|
||||
|
||||
/** Logging system */
|
||||
private final Logger logger = Logger.getLogger( ImportResources.class );
|
||||
|
||||
/** File to read the definitions from */
|
||||
private File file;
|
||||
|
||||
/** Spring transaction template */
|
||||
private TransactionTemplate tTemplate;
|
||||
|
||||
/** Error counter */
|
||||
private int errors = 0;
|
||||
|
||||
/** Skipped definitions counter */
|
||||
private int skipped = 0;
|
||||
|
||||
/** Successful imports counter */
|
||||
private int successful = 0;
|
||||
|
||||
/** Stored procedure that starts recording an event definition */
|
||||
private StoredProc fEvdefStart;
|
||||
|
||||
/** Stored procedure that finalises an event definition's recording */
|
||||
private StoredProc fEvdefFinalise;
|
||||
|
||||
/** Stored procedure that defines a boolean field */
|
||||
private StoredProc fEvdefAddfldBool;
|
||||
|
||||
/** Stored procedure that defines an I18N reference field */
|
||||
private StoredProc fEvdefAddfldI18N;
|
||||
|
||||
/** Stored procedure that defines an entity reference field */
|
||||
private StoredProc fEvdefAddfldEntity;
|
||||
|
||||
/** Unbounded integer field definition procedure */
|
||||
private StoredProc fEvdefAddfldInt;
|
||||
|
||||
/** Stored procedure that defines an integer field with a lower bound */
|
||||
private StoredProc fEvdefAddfldIntMin;
|
||||
|
||||
/** Stored procedure that defines an integer field with a higher bound */
|
||||
private StoredProc fEvdefAddfldIntMax;
|
||||
|
||||
/** Stored procedure that defines a bounded integer field */
|
||||
private StoredProc fEvdefAddfldIntRange;
|
||||
|
||||
/** Unbounded double precision field definition procedure */
|
||||
private StoredProc fEvdefAddfldReal;
|
||||
|
||||
/** Stored procedure that defines a double precision field with a lower bound */
|
||||
private StoredProc fEvdefAddfldRealMin;
|
||||
|
||||
/** Stored procedure that defines a double precision field with a higher bound */
|
||||
private StoredProc fEvdefAddfldRealMax;
|
||||
|
||||
/** Stored procedure that defines a bounded double precision field */
|
||||
private StoredProc fEvdefAddfldRealRange;
|
||||
|
||||
/** Unbounded text field definition procedure */
|
||||
private StoredProc fEvdefAddfldText;
|
||||
|
||||
/** Stored procedure that defines a text field with a minimum length */
|
||||
private StoredProc fEvdefAddfldTextMin;
|
||||
|
||||
/** Stored procedure that defines a text field with a maximal length */
|
||||
private StoredProc fEvdefAddfldTextMax;
|
||||
|
||||
/** Stored procedure that defines a bounded text field */
|
||||
private StoredProc fEvdefAddfldTextRange;
|
||||
|
||||
|
||||
/**
|
||||
* Obtain the name of the definitions file
|
||||
*
|
||||
* <p>
|
||||
* Check the command line options, setting the definitions file accordingly.
|
||||
*/
|
||||
@Override
|
||||
public boolean setOptions( String... options )
|
||||
{
|
||||
if ( options.length != 1 ) {
|
||||
return false;
|
||||
}
|
||||
this.file = new File( options[ 0 ] );
|
||||
if ( ! ( this.file.isFile( ) && this.file.canRead( ) ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run the event definitions import tool
|
||||
*
|
||||
* <p>
|
||||
* Loads the data file, then connects to the database and creates all missing definitions.
|
||||
*/
|
||||
@Override
|
||||
public void run( )
|
||||
{
|
||||
EventDefinitions data;
|
||||
try {
|
||||
data = new EventDefinitionLoader( this.file ).load( );
|
||||
} catch ( DataImportException e ) {
|
||||
this.logger.error( "Error while loading event definitions" , e );
|
||||
return;
|
||||
}
|
||||
|
||||
AbstractApplicationContext ctx = this.createContext( );
|
||||
this.createTemplates( ctx );
|
||||
this.executeImportTransaction( data );
|
||||
ToolBase.destroyContext( ctx );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the Spring context
|
||||
*
|
||||
* <p>
|
||||
* Load the definition of the data source as a Spring context, then adds the transaction
|
||||
* management component.
|
||||
*
|
||||
* @return the Spring application context
|
||||
*/
|
||||
private ClassPathXmlApplicationContext createContext( )
|
||||
{
|
||||
FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext( new String[] {
|
||||
this.getDataSource( )
|
||||
} );
|
||||
ctx.refresh( );
|
||||
|
||||
return new ClassPathXmlApplicationContext( new String[] {
|
||||
"configuration/transactions.xml"
|
||||
} , true , ctx );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create database access templates
|
||||
*
|
||||
* <p>
|
||||
* Initialise the transaction template and the four stored procedure definitions.
|
||||
*
|
||||
* @param ctx
|
||||
* the Spring application context
|
||||
*/
|
||||
private void createTemplates( ApplicationContext ctx )
|
||||
{
|
||||
DataSource dSource = ctx.getBean( DataSource.class );
|
||||
PlatformTransactionManager tManager = ctx.getBean( PlatformTransactionManager.class );
|
||||
|
||||
this.fEvdefStart = new StoredProc( dSource , "events" , "evdef_start" )
|
||||
.addParameter( "_id" , java.sql.Types.VARCHAR ).addParameter( "_prio" , java.sql.Types.INTEGER )
|
||||
.addParameter( "_adj" , java.sql.Types.BOOLEAN ).addParameter( "_i18n" , java.sql.Types.VARCHAR )
|
||||
.addOutput( "_error" , java.sql.Types.OTHER );
|
||||
|
||||
this.fEvdefFinalise = new StoredProc( dSource , "events" , "evdef_finalise" ).addOutput( "_error" ,
|
||||
java.sql.Types.OTHER ).addOutput( "_fld" , java.sql.Types.VARCHAR );
|
||||
|
||||
this.fEvdefAddfldBool = new StoredProc( dSource , "events" , "evdef_addfld_bool" )
|
||||
.addParameter( "_id" , java.sql.Types.VARCHAR ).addParameter( "_optional" , java.sql.Types.BOOLEAN )
|
||||
.addOutput( "_error" , java.sql.Types.OTHER );
|
||||
|
||||
this.fEvdefAddfldI18N = new StoredProc( dSource , "events" , "evdef_addfld_i18n" )
|
||||
.addParameter( "_id" , java.sql.Types.VARCHAR ).addParameter( "_optional" , java.sql.Types.BOOLEAN )
|
||||
.addOutput( "_error" , java.sql.Types.OTHER );
|
||||
|
||||
this.fEvdefAddfldEntity = new StoredProc( dSource , "events" , "evdef_addfld_entity" )
|
||||
.addParameter( "_id" , java.sql.Types.VARCHAR ).addParameter( "_optional" , java.sql.Types.BOOLEAN )
|
||||
.addParameter( "_etype" , "events.entity_field_type" ).addOutput( "_error" , java.sql.Types.OTHER );
|
||||
|
||||
this.fEvdefAddfldInt = new StoredProc( dSource , "events" , "evdef_addfld_int" )
|
||||
.addParameter( "_id" , java.sql.Types.VARCHAR ).addParameter( "_optional" , java.sql.Types.BOOLEAN )
|
||||
.addOutput( "_error" , java.sql.Types.OTHER );
|
||||
this.fEvdefAddfldIntMin = new StoredProc( dSource , "events" , "evdef_addfld_int_min" )
|
||||
.addParameter( "_id" , java.sql.Types.VARCHAR ).addParameter( "_optional" , java.sql.Types.BOOLEAN )
|
||||
.addParameter( "_min" , java.sql.Types.INTEGER ).addOutput( "_error" , java.sql.Types.OTHER );
|
||||
this.fEvdefAddfldIntMax = new StoredProc( dSource , "events" , "evdef_addfld_int_max" )
|
||||
.addParameter( "_id" , java.sql.Types.VARCHAR ).addParameter( "_optional" , java.sql.Types.BOOLEAN )
|
||||
.addParameter( "_max" , java.sql.Types.INTEGER ).addOutput( "_error" , java.sql.Types.OTHER );
|
||||
this.fEvdefAddfldIntRange = new StoredProc( dSource , "events" , "evdef_addfld_int_range" )
|
||||
.addParameter( "_id" , java.sql.Types.VARCHAR ).addParameter( "_optional" , java.sql.Types.BOOLEAN )
|
||||
.addParameter( "_min" , java.sql.Types.INTEGER ).addParameter( "_max" , java.sql.Types.INTEGER )
|
||||
.addOutput( "_error" , java.sql.Types.OTHER );
|
||||
|
||||
this.fEvdefAddfldReal = new StoredProc( dSource , "events" , "evdef_addfld_real" )
|
||||
.addParameter( "_id" , java.sql.Types.VARCHAR ).addParameter( "_optional" , java.sql.Types.BOOLEAN )
|
||||
.addOutput( "_error" , java.sql.Types.OTHER );
|
||||
this.fEvdefAddfldRealMin = new StoredProc( dSource , "events" , "evdef_addfld_real_min" )
|
||||
.addParameter( "_id" , java.sql.Types.VARCHAR ).addParameter( "_optional" , java.sql.Types.BOOLEAN )
|
||||
.addParameter( "_min" , java.sql.Types.DOUBLE ).addOutput( "_error" , java.sql.Types.OTHER );
|
||||
this.fEvdefAddfldRealMax = new StoredProc( dSource , "events" , "evdef_addfld_real_max" )
|
||||
.addParameter( "_id" , java.sql.Types.VARCHAR ).addParameter( "_optional" , java.sql.Types.BOOLEAN )
|
||||
.addParameter( "_max" , java.sql.Types.DOUBLE ).addOutput( "_error" , java.sql.Types.OTHER );
|
||||
this.fEvdefAddfldRealRange = new StoredProc( dSource , "events" , "evdef_addfld_real_range" )
|
||||
.addParameter( "_id" , java.sql.Types.VARCHAR ).addParameter( "_optional" , java.sql.Types.BOOLEAN )
|
||||
.addParameter( "_min" , java.sql.Types.DOUBLE ).addParameter( "_max" , java.sql.Types.DOUBLE )
|
||||
.addOutput( "_error" , java.sql.Types.OTHER );
|
||||
|
||||
this.fEvdefAddfldText = new StoredProc( dSource , "events" , "evdef_addfld_text" )
|
||||
.addParameter( "_id" , java.sql.Types.VARCHAR ).addParameter( "_optional" , java.sql.Types.BOOLEAN )
|
||||
.addOutput( "_error" , java.sql.Types.OTHER );
|
||||
this.fEvdefAddfldTextMin = new StoredProc( dSource , "events" , "evdef_addfld_text_min" )
|
||||
.addParameter( "_id" , java.sql.Types.VARCHAR ).addParameter( "_optional" , java.sql.Types.BOOLEAN )
|
||||
.addParameter( "_min" , java.sql.Types.INTEGER ).addOutput( "_error" , java.sql.Types.OTHER );
|
||||
this.fEvdefAddfldTextMax = new StoredProc( dSource , "events" , "evdef_addfld_text_max" )
|
||||
.addParameter( "_id" , java.sql.Types.VARCHAR ).addParameter( "_optional" , java.sql.Types.BOOLEAN )
|
||||
.addParameter( "_max" , java.sql.Types.INTEGER ).addOutput( "_error" , java.sql.Types.OTHER );
|
||||
this.fEvdefAddfldTextRange = new StoredProc( dSource , "events" , "evdef_addfld_text_range" )
|
||||
.addParameter( "_id" , java.sql.Types.VARCHAR ).addParameter( "_optional" , java.sql.Types.BOOLEAN )
|
||||
.addParameter( "_min" , java.sql.Types.INTEGER ).addParameter( "_max" , java.sql.Types.INTEGER )
|
||||
.addOutput( "_error" , java.sql.Types.OTHER );
|
||||
|
||||
this.tTemplate = new TransactionTemplate( tManager );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute the event definitions importation transaction
|
||||
*
|
||||
* <p>
|
||||
* Run a transaction and execute the importation code inside it. Roll back if anything goes
|
||||
* wrong.
|
||||
*
|
||||
* @param data
|
||||
* the event definitions top-level instance
|
||||
*/
|
||||
private void executeImportTransaction( final EventDefinitions data )
|
||||
{
|
||||
boolean rv = this.tTemplate.execute( new TransactionCallback< Boolean >( ) {
|
||||
@Override
|
||||
public Boolean doInTransaction( TransactionStatus status )
|
||||
{
|
||||
boolean rv = ImportEvents.this.doTransaction( data );
|
||||
if ( !rv ) {
|
||||
status.setRollbackOnly( );
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
} );
|
||||
|
||||
if ( rv ) {
|
||||
this.logger.info( "Import complete; " + this.successful + " new type(s), " + this.skipped + " skipped" );
|
||||
} else {
|
||||
this.logger.error( this.errors + " error(s) occurred, no changes were made" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Import transaction body
|
||||
*
|
||||
* <p>
|
||||
* Import all definitions and handle exceptions.
|
||||
*
|
||||
* @param data
|
||||
* the event definitions top-level instance
|
||||
* @return <code>true</code> on success, <code>false</code> otherwise
|
||||
*/
|
||||
private boolean doTransaction( EventDefinitions data )
|
||||
{
|
||||
try {
|
||||
this.importDefinitions( data );
|
||||
return this.errors == 0;
|
||||
} catch ( RuntimeException e ) {
|
||||
this.logger.error( "Caught runtime exception" , e );
|
||||
this.errors ++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extract the error code from a stored procedure's return value
|
||||
*
|
||||
* <p>
|
||||
* This method is used to extract the error code from the maps returned by a definition stored
|
||||
* procedure's execution.
|
||||
*
|
||||
* @param result
|
||||
* the map returned by the stored procedure's execution
|
||||
*
|
||||
* @return the error code
|
||||
*/
|
||||
private SPErrorCode getSPResult( Map< String , Object > result )
|
||||
{
|
||||
return SPErrorCode.valueOf( ( (PGobject) result.get( "_error" ) ).getValue( ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Import all event definitions from the top-level importable instance
|
||||
*
|
||||
* <p>
|
||||
* This method iterates through all of the definitions, trying to import each of them.
|
||||
*
|
||||
* @param data
|
||||
* the top-level importable instance
|
||||
*/
|
||||
private void importDefinitions( EventDefinitions data )
|
||||
{
|
||||
for ( EventDefinition evdef : data ) {
|
||||
this.importDefinition( evdef );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Try to import an event definition
|
||||
*
|
||||
* <p>
|
||||
* This method will attempt to import an event definition. It will increase the state counters (
|
||||
* {@link #errors}, {@link #skipped} and {@link #successful}) depending on the results.
|
||||
*
|
||||
* @param evdef
|
||||
* the event definition to import
|
||||
*/
|
||||
private void importDefinition( EventDefinition evdef )
|
||||
{
|
||||
boolean ok;
|
||||
|
||||
// Start the import
|
||||
try {
|
||||
this.startImport( evdef );
|
||||
ok = true;
|
||||
} catch ( DataImportException e ) {
|
||||
this.logger.error( e.getMessage( ) );
|
||||
ok = false;
|
||||
}
|
||||
|
||||
// Import all fields
|
||||
if ( ok ) {
|
||||
for ( EventFieldBase field : evdef ) {
|
||||
ok = ok && this.importField( evdef , field );
|
||||
if ( !ok ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finalise the operation
|
||||
boolean wasNew = false;
|
||||
try {
|
||||
wasNew = this.endImport( evdef );
|
||||
} catch ( DataImportException e ) {
|
||||
if ( ok ) {
|
||||
this.logger.error( e.getMessage( ) );
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Update counters and print to log
|
||||
if ( ok ) {
|
||||
if ( wasNew ) {
|
||||
this.logger.info( evdef.getIdentifier( ) + ": new event definition imported" );
|
||||
this.successful++;
|
||||
} else {
|
||||
this.logger.warn( evdef.getIdentifier( ) + ": event definition exists (skipped)" );
|
||||
this.skipped++;
|
||||
}
|
||||
} else {
|
||||
this.errors++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Start importing an event definition
|
||||
*
|
||||
* <p>
|
||||
* This method calls the <code>events.evdef_start()</code> stored procedure to initialise the
|
||||
* event definition registration, and handles its return value.
|
||||
*
|
||||
* @param evdef
|
||||
* the event definition instance from the XML definition
|
||||
*
|
||||
* @throws DataImportException
|
||||
* if the definition's identifier is invalid or if one of the internationalised
|
||||
* strings is missing
|
||||
*/
|
||||
private void startImport( EventDefinition evdef )
|
||||
throws DataImportException
|
||||
{
|
||||
SPErrorCode ec;
|
||||
ec = this.getSPResult( this.fEvdefStart.execute( evdef.getIdentifier( ) , evdef.getPriority( ) ,
|
||||
evdef.isAdjustable( ) , evdef.getI18NStrings( ) ) );
|
||||
|
||||
switch ( ec ) {
|
||||
case OK:
|
||||
break;
|
||||
|
||||
case BAD_ID:
|
||||
throw new DataImportException( evdef.getIdentifier( ) + ": bad event type identifier" );
|
||||
|
||||
case BAD_STRINGS:
|
||||
throw new DataImportException( evdef.getIdentifier( ) + ": I18N strings not found" );
|
||||
|
||||
default:
|
||||
throw new RuntimeException( "Unsupported return value for events.evdef_start(): " + ec.toString( ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Import a field definition
|
||||
*
|
||||
* <p>
|
||||
* Call the appropriate field definition importation method depending on the field's type.
|
||||
*
|
||||
* @param evdef
|
||||
* the event definition
|
||||
* @param field
|
||||
* the field definition
|
||||
*
|
||||
* @return <code>true</code> on success, <code>false</code> if something went wrong
|
||||
*/
|
||||
private boolean importField( EventDefinition evdef , EventFieldBase field )
|
||||
{
|
||||
SPErrorCode ec;
|
||||
switch ( field.getType( ) ) {
|
||||
case BOOLEAN:
|
||||
ec = this.importBooleanField( field );
|
||||
break;
|
||||
|
||||
case I18N:
|
||||
ec = this.importI18NField( field );
|
||||
break;
|
||||
|
||||
case ENTITY:
|
||||
ec = this.importEntityField( (EntityEventField) field );
|
||||
break;
|
||||
|
||||
case INTEGER:
|
||||
ec = this.importIntegerField( (IntegerEventField) field );
|
||||
break;
|
||||
|
||||
case REAL:
|
||||
ec = this.importRealField( (RealEventField) field );
|
||||
break;
|
||||
|
||||
case TEXT:
|
||||
ec = this.importTextField( (TextEventField) field );
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new RuntimeException( "Unsupported field type " + field.getType( ).toString( ) );
|
||||
}
|
||||
|
||||
switch ( ec ) {
|
||||
case OK:
|
||||
return true;
|
||||
|
||||
case BAD_ID:
|
||||
this.logger.error( evdef.getIdentifier( ) + ": bad field identifier '" + field.getIdentifier( ) + "'" );
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new RuntimeException( "Unsupported return value for field definition procedure: " + ec.toString( ) );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Import a boolean field
|
||||
*
|
||||
* <p>
|
||||
* This method calls <code>events.evdef_addfld_bool</code> to register a new boolean field.
|
||||
*
|
||||
* @param field
|
||||
* the field's definition
|
||||
*
|
||||
* @return the stored procedure's error code
|
||||
*/
|
||||
private SPErrorCode importBooleanField( EventFieldBase field )
|
||||
{
|
||||
return this.getSPResult( this.fEvdefAddfldBool.execute( field.getIdentifier( ) , !field.isRequired( ) ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Import an I18N reference field
|
||||
*
|
||||
* <p>
|
||||
* This method calls <code>events.evdef_addfld_i18n</code> to register a new I18N reference
|
||||
* field.
|
||||
*
|
||||
* @param field
|
||||
* the field's definition
|
||||
*
|
||||
* @return the stored procedure's error code
|
||||
*/
|
||||
private SPErrorCode importI18NField( EventFieldBase field )
|
||||
{
|
||||
return this.getSPResult( this.fEvdefAddfldI18N.execute( field.getIdentifier( ) , !field.isRequired( ) ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Import an entity reference field
|
||||
*
|
||||
* <p>
|
||||
* This method calls <code>events.evdef_addfld_entity</code> to register a new entity reference
|
||||
* field.
|
||||
*
|
||||
* @param field
|
||||
* the field's definition
|
||||
*
|
||||
* @return the stored procedure's error code
|
||||
*/
|
||||
private SPErrorCode importEntityField( EntityEventField field )
|
||||
{
|
||||
return this.getSPResult( this.fEvdefAddfldEntity.execute( field.getIdentifier( ) , !field.isRequired( ) ,
|
||||
field.getEntityType( ) ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Import an integer field definition
|
||||
*
|
||||
* <p>
|
||||
* This method calls one of the integer field definitions stored procedures, depending on the
|
||||
* definition's parameters.
|
||||
*
|
||||
* @param field
|
||||
* the field's definition
|
||||
*
|
||||
* @return the stored procedure's error code
|
||||
*/
|
||||
private SPErrorCode importIntegerField( IntegerEventField field )
|
||||
{
|
||||
String id = field.getIdentifier( );
|
||||
boolean opt = !field.isRequired( );
|
||||
Integer min = field.getMin( );
|
||||
Integer max = field.getMax( );
|
||||
|
||||
Map< String , Object > result;
|
||||
if ( min == null && max == null ) {
|
||||
result = this.fEvdefAddfldInt.execute( id , opt );
|
||||
} else if ( min == null ) {
|
||||
result = this.fEvdefAddfldIntMax.execute( id , opt , max );
|
||||
} else if ( max == null ) {
|
||||
result = this.fEvdefAddfldIntMin.execute( id , opt , min );
|
||||
} else {
|
||||
result = this.fEvdefAddfldIntRange.execute( id , opt , min , max );
|
||||
}
|
||||
|
||||
return this.getSPResult( result );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Import a double precision field definition
|
||||
*
|
||||
* <p>
|
||||
* This method calls one of the double precision field definitions stored procedures, depending
|
||||
* on the definition's parameters.
|
||||
*
|
||||
* @param field
|
||||
* the field's definition
|
||||
*
|
||||
* @return the stored procedure's error code
|
||||
*/
|
||||
private SPErrorCode importRealField( RealEventField field )
|
||||
{
|
||||
String id = field.getIdentifier( );
|
||||
boolean opt = !field.isRequired( );
|
||||
Double min = field.getMin( );
|
||||
Double max = field.getMax( );
|
||||
|
||||
Map< String , Object > result;
|
||||
if ( min == null && max == null ) {
|
||||
result = this.fEvdefAddfldReal.execute( id , opt );
|
||||
} else if ( min == null ) {
|
||||
result = this.fEvdefAddfldRealMax.execute( id , opt , max );
|
||||
} else if ( max == null ) {
|
||||
result = this.fEvdefAddfldRealMin.execute( id , opt , min );
|
||||
} else {
|
||||
result = this.fEvdefAddfldRealRange.execute( id , opt , min , max );
|
||||
}
|
||||
|
||||
return this.getSPResult( result );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Import a text field definition
|
||||
*
|
||||
* <p>
|
||||
* This method calls one of the text field definitions stored procedures, depending on the
|
||||
* definition's parameters.
|
||||
*
|
||||
* @param field
|
||||
* the field's definition
|
||||
*
|
||||
* @return the stored procedure's error code
|
||||
*/
|
||||
private SPErrorCode importTextField( TextEventField field )
|
||||
{
|
||||
String id = field.getIdentifier( );
|
||||
boolean opt = !field.isRequired( );
|
||||
Integer min = field.getMinLength( );
|
||||
Integer max = field.getMaxLength( );
|
||||
|
||||
Map< String , Object > result;
|
||||
if ( min == null && max == null ) {
|
||||
result = this.fEvdefAddfldText.execute( id , opt );
|
||||
} else if ( min == null ) {
|
||||
result = this.fEvdefAddfldTextMax.execute( id , opt , max );
|
||||
} else if ( max == null ) {
|
||||
result = this.fEvdefAddfldTextMin.execute( id , opt , min );
|
||||
} else {
|
||||
result = this.fEvdefAddfldTextRange.execute( id , opt , min , max );
|
||||
}
|
||||
|
||||
return this.getSPResult( result );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finalise the current event definition
|
||||
*
|
||||
* <p>
|
||||
* This method calls the <code>events.evdef_finalise()</code> stored procedure, and handles its
|
||||
* return values.
|
||||
*
|
||||
* @param evdef
|
||||
* the event definition from the XML file
|
||||
*
|
||||
* @return <code>true</code> if the definition was finalised or if it had no effect (except for
|
||||
* cleanup) due to a previous error, <code>false</code> if the definition already
|
||||
* existed and was skipped.
|
||||
*
|
||||
* @throws DataImportException
|
||||
* if the event's specification is invalid, if a field name is duplicated, or if a
|
||||
* field's specification is invalid.
|
||||
*/
|
||||
private boolean endImport( EventDefinition evdef )
|
||||
throws DataImportException
|
||||
{
|
||||
Map< String , Object > result = this.fEvdefFinalise.execute( );
|
||||
SPErrorCode ec = this.getSPResult( result );
|
||||
String field = (String) result.get( "_fld" );
|
||||
|
||||
switch ( ec ) {
|
||||
case OK:
|
||||
case NO_DATA:
|
||||
return true;
|
||||
|
||||
case BAD_SPEC:
|
||||
if ( field == null ) {
|
||||
throw new DataImportException( evdef.getIdentifier( ) + ": bad event type specification" );
|
||||
}
|
||||
throw new DataImportException( evdef.getIdentifier( ) + ": bad field specification (" + field + ")" );
|
||||
|
||||
case DUPLICATE:
|
||||
if ( field == null ) {
|
||||
return false;
|
||||
}
|
||||
throw new DataImportException( evdef.getIdentifier( ) + ": duplicate field name " + field );
|
||||
|
||||
default:
|
||||
throw new RuntimeException( "Unsupported return value for events.evdef_finalise(): " + ec.toString( ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
package com.deepclone.lw.cli.xmlimport;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.deepclone.lw.cli.xmlimport.data.DataImportException;
|
||||
import com.deepclone.lw.cli.xmlimport.data.evdef.*;
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import com.thoughtworks.xstream.XStreamException;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Event definitions loader
|
||||
*
|
||||
* <p>
|
||||
* This class implements loading event definitions from XML files. The definitions will be extracted
|
||||
* and verified.
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*/
|
||||
public class EventDefinitionLoader
|
||||
{
|
||||
/** The file to read the XML from */
|
||||
private final File file;
|
||||
|
||||
|
||||
/**
|
||||
* Initialise the loader
|
||||
*
|
||||
* @param file
|
||||
* the XML file that contains the definitions
|
||||
*/
|
||||
public EventDefinitionLoader( File file )
|
||||
{
|
||||
this.file = file.getAbsoluteFile( );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialise the necessary XStream instance
|
||||
*
|
||||
* <p>
|
||||
* Initialise the XStream instance by processing annotations in all event definition importable
|
||||
* data classes.
|
||||
*
|
||||
* @return the XStream instance to use when loading the data
|
||||
*/
|
||||
private XStream initXStream( )
|
||||
{
|
||||
XStream xstream = new XStream( );
|
||||
xstream.processAnnotations( EventDefinitions.class );
|
||||
xstream.processAnnotations( BooleanEventField.class );
|
||||
xstream.processAnnotations( IntegerEventField.class );
|
||||
xstream.processAnnotations( RealEventField.class );
|
||||
xstream.processAnnotations( TextEventField.class );
|
||||
xstream.processAnnotations( I18NEventField.class );
|
||||
xstream.processAnnotations( EntityEventField.class );
|
||||
return xstream;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load the event definitions
|
||||
*
|
||||
* <p>
|
||||
* Load the XML file and process the definitions file using XStream.
|
||||
*
|
||||
* @return the top-level importable data instance
|
||||
*
|
||||
* @throws DataImportException
|
||||
* if reading from the file or parsing its contents fail
|
||||
*/
|
||||
private EventDefinitions loadXMLFile( )
|
||||
throws DataImportException
|
||||
{
|
||||
FileInputStream fis;
|
||||
try {
|
||||
fis = new FileInputStream( this.file );
|
||||
} catch ( FileNotFoundException e ) {
|
||||
throw new DataImportException( "Unable to load event definitions" , e );
|
||||
}
|
||||
|
||||
try {
|
||||
try {
|
||||
XStream xstream = this.initXStream( );
|
||||
return (EventDefinitions) xstream.fromXML( fis );
|
||||
} finally {
|
||||
fis.close( );
|
||||
}
|
||||
} catch ( IOException e ) {
|
||||
throw new DataImportException( "Input error while loading event definitions" , e );
|
||||
} catch ( XStreamException e ) {
|
||||
throw new DataImportException( "XML error while loading event definitions" , e );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load and process I18N definition
|
||||
*
|
||||
* <p>
|
||||
* Attempt to load all I18N definitions, make sure they are valid, then set the original file's
|
||||
* path.
|
||||
*
|
||||
* @return the top-level importable data instance
|
||||
*
|
||||
* @throws DataImportException
|
||||
* if loading or verifying the data fails
|
||||
*/
|
||||
public EventDefinitions load( )
|
||||
throws DataImportException
|
||||
{
|
||||
EventDefinitions events = this.loadXMLFile( );
|
||||
events.verifyData( );
|
||||
events.setReadFrom( this.file );
|
||||
return events;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.deepclone.lw.cli.xmlimport.data.evdef;
|
||||
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A boolean field definition
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*/
|
||||
@XStreamAlias( "boolean" )
|
||||
@SuppressWarnings( "serial" )
|
||||
public class BooleanEventField
|
||||
extends EventFieldBase
|
||||
{
|
||||
|
||||
/** @return {@link EventFieldType#BOOLEAN} */
|
||||
@Override
|
||||
public EventFieldType getType( )
|
||||
{
|
||||
return EventFieldType.BOOLEAN;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.deepclone.lw.cli.xmlimport.data.evdef;
|
||||
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* An entity reference field definition
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*/
|
||||
@XStreamAlias( "entity" )
|
||||
@SuppressWarnings( "serial" )
|
||||
public class EntityEventField
|
||||
extends EventFieldBase
|
||||
{
|
||||
|
||||
/** The type of entities this field references */
|
||||
@XStreamAsAttribute
|
||||
@XStreamAlias( "entity-type" )
|
||||
private EventFieldEntityType entityType;
|
||||
|
||||
|
||||
public EventFieldEntityType getEntityType( )
|
||||
{
|
||||
return this.entityType;
|
||||
}
|
||||
|
||||
|
||||
/** @return {@link EntityFieldType#ENTITY} */
|
||||
@Override
|
||||
public EventFieldType getType( )
|
||||
{
|
||||
return EventFieldType.ENTITY;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
package com.deepclone.lw.cli.xmlimport.data.evdef;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import com.deepclone.lw.cli.xmlimport.data.DataImportException;
|
||||
import com.deepclone.lw.cli.xmlimport.data.ImportableData;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
|
||||
import com.thoughtworks.xstream.annotations.XStreamImplicit;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Event definition
|
||||
*
|
||||
* <p>
|
||||
* This class represents an event definition entry from the data file. An event definition consists
|
||||
* in a few properties, and a potentially empty list of event field definitions.
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings( "serial" )
|
||||
public class EventDefinition
|
||||
extends ImportableData
|
||||
implements Iterable< EventFieldBase >
|
||||
{
|
||||
|
||||
/** The event type's identifier */
|
||||
@XStreamAsAttribute
|
||||
@XStreamAlias( "id" )
|
||||
private String identifier;
|
||||
|
||||
/** The default priority */
|
||||
@XStreamAsAttribute
|
||||
private Integer priority;
|
||||
|
||||
/** Whether users can override the events' priority */
|
||||
@XStreamAsAttribute
|
||||
private Boolean adjustable;
|
||||
|
||||
/** Prefix of the name and template strings */
|
||||
@XStreamAsAttribute
|
||||
@XStreamAlias( "i18n-strings" )
|
||||
private String i18nStrings;
|
||||
|
||||
/** The list of fields */
|
||||
@XStreamImplicit
|
||||
private List< EventFieldBase > fields = new ArrayList< EventFieldBase >( );
|
||||
|
||||
|
||||
public String getIdentifier( )
|
||||
{
|
||||
return this.identifier;
|
||||
}
|
||||
|
||||
|
||||
public int getPriority( )
|
||||
{
|
||||
return ( this.priority == null ) ? 2 : this.priority;
|
||||
}
|
||||
|
||||
|
||||
public boolean isAdjustable( )
|
||||
{
|
||||
return ( this.adjustable == null ) ? true : this.adjustable;
|
||||
}
|
||||
|
||||
|
||||
public String getI18NStrings( )
|
||||
{
|
||||
return this.i18nStrings;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Iterator< EventFieldBase > iterator( )
|
||||
{
|
||||
return Collections.unmodifiableList( this.fields ).iterator( );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void verifyData( )
|
||||
throws DataImportException
|
||||
{
|
||||
super.verifyData( );
|
||||
if ( this.fields == null ) {
|
||||
this.fields = new ArrayList< EventFieldBase >( );
|
||||
} else {
|
||||
for ( EventFieldBase f : this.fields ) {
|
||||
f.verifyData( );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package com.deepclone.lw.cli.xmlimport.data.evdef;
|
||||
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import com.deepclone.lw.cli.xmlimport.data.DataImportException;
|
||||
import com.deepclone.lw.cli.xmlimport.data.ImportableData;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import com.thoughtworks.xstream.annotations.XStreamImplicit;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Event type definitions
|
||||
*
|
||||
* <p>
|
||||
* This class represents the list of event type definitions as it is found in the appropriate data
|
||||
* file.
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*/
|
||||
@SuppressWarnings( "serial" )
|
||||
@XStreamAlias( "lw-event-definitions" )
|
||||
public class EventDefinitions
|
||||
extends ImportableData
|
||||
implements Iterable< EventDefinition >
|
||||
{
|
||||
|
||||
/** The list of event definitions */
|
||||
@XStreamImplicit( itemFieldName = "evdef" )
|
||||
private List< EventDefinition > definitions = new LinkedList< EventDefinition >( );
|
||||
|
||||
|
||||
/** Iterate over event definitions */
|
||||
@Override
|
||||
public Iterator< EventDefinition > iterator( )
|
||||
{
|
||||
return Collections.unmodifiableList( this.definitions ).iterator( );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void verifyData( )
|
||||
throws DataImportException
|
||||
{
|
||||
super.verifyData( );
|
||||
if ( this.definitions == null ) {
|
||||
throw new DataImportException( "No definitions in this file" );
|
||||
}
|
||||
for ( EventDefinition def : this.definitions ) {
|
||||
def.verifyData( );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package com.deepclone.lw.cli.xmlimport.data.evdef;
|
||||
|
||||
|
||||
import com.deepclone.lw.cli.xmlimport.data.ImportableData;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Common event field definition
|
||||
*
|
||||
* <p>
|
||||
* This abstract class is used as the base for event field definitions.
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*/
|
||||
@SuppressWarnings( "serial" )
|
||||
public abstract class EventFieldBase
|
||||
extends ImportableData
|
||||
{
|
||||
|
||||
/** The field's identifier */
|
||||
@XStreamAsAttribute
|
||||
@XStreamAlias( "id" )
|
||||
private String identifier;
|
||||
|
||||
/** Whether the field is required or optional */
|
||||
@XStreamAsAttribute
|
||||
private Boolean required;
|
||||
|
||||
|
||||
/**
|
||||
* Obtain the type of the field
|
||||
*
|
||||
* @return the field's type.
|
||||
*/
|
||||
public abstract EventFieldType getType( );
|
||||
|
||||
|
||||
public String getIdentifier( )
|
||||
{
|
||||
return this.identifier;
|
||||
}
|
||||
|
||||
|
||||
public boolean isRequired( )
|
||||
{
|
||||
return this.required == null ? true : this.required;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.deepclone.lw.cli.xmlimport.data.evdef;
|
||||
|
||||
|
||||
/** Types of entities which can be referenced through entity fields */
|
||||
public enum EventFieldEntityType {
|
||||
|
||||
/** Empires */
|
||||
EMP ,
|
||||
/** Planets */
|
||||
PLN ,
|
||||
/** Fleets */
|
||||
FLT ,
|
||||
/** Alliances */
|
||||
ALL ,
|
||||
/** Battles */
|
||||
BAT ,
|
||||
/** Administrators */
|
||||
ADM ,
|
||||
/** Bug reports */
|
||||
BUG
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.deepclone.lw.cli.xmlimport.data.evdef;
|
||||
|
||||
|
||||
/** Types of event fields as they are stored in the definition file */
|
||||
public enum EventFieldType {
|
||||
|
||||
/** An integer field */
|
||||
INTEGER ,
|
||||
|
||||
/** An double precision real number field */
|
||||
REAL ,
|
||||
|
||||
/** A string field */
|
||||
TEXT ,
|
||||
|
||||
/** A boolean field */
|
||||
BOOLEAN ,
|
||||
|
||||
/** A field that references an internationalised string */
|
||||
I18N ,
|
||||
|
||||
/** A field that references some game entity */
|
||||
ENTITY
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.deepclone.lw.cli.xmlimport.data.evdef;
|
||||
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Definition of a field containing an I18N reference
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*/
|
||||
@XStreamAlias( "i18n" )
|
||||
@SuppressWarnings( "serial" )
|
||||
public class I18NEventField
|
||||
extends EventFieldBase
|
||||
{
|
||||
|
||||
/** @return {@link EventFieldType#I18N} */
|
||||
@Override
|
||||
public EventFieldType getType( )
|
||||
{
|
||||
return EventFieldType.I18N;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package com.deepclone.lw.cli.xmlimport.data.evdef;
|
||||
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* An integer event field definition
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*/
|
||||
@XStreamAlias( "integer" )
|
||||
@SuppressWarnings( "serial" )
|
||||
public class IntegerEventField
|
||||
extends EventFieldBase
|
||||
{
|
||||
/** Minimal value allowed for the field */
|
||||
@XStreamAsAttribute
|
||||
private Integer min;
|
||||
|
||||
/** Maximal value allowed for the field */
|
||||
@XStreamAsAttribute
|
||||
private Integer max;
|
||||
|
||||
|
||||
public Integer getMin( )
|
||||
{
|
||||
return this.min;
|
||||
}
|
||||
|
||||
|
||||
public Integer getMax( )
|
||||
{
|
||||
return this.max;
|
||||
}
|
||||
|
||||
|
||||
/** @return {@link EventFieldType#INTEGER} */
|
||||
@Override
|
||||
public EventFieldType getType( )
|
||||
{
|
||||
return EventFieldType.INTEGER;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.deepclone.lw.cli.xmlimport.data.evdef;
|
||||
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A real field definition
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*/
|
||||
@XStreamAlias( "real" )
|
||||
@SuppressWarnings( "serial" )
|
||||
public class RealEventField
|
||||
extends EventFieldBase
|
||||
{
|
||||
|
||||
/** Minimal value for the field */
|
||||
@XStreamAsAttribute
|
||||
private Double min;
|
||||
|
||||
/** Maximal value for the field */
|
||||
@XStreamAsAttribute
|
||||
private Double max;
|
||||
|
||||
|
||||
public Double getMin( )
|
||||
{
|
||||
return this.min;
|
||||
}
|
||||
|
||||
|
||||
public Double getMax( )
|
||||
{
|
||||
return this.max;
|
||||
}
|
||||
|
||||
|
||||
/** @return {@link EventFieldType#REAL} */
|
||||
@Override
|
||||
public EventFieldType getType( )
|
||||
{
|
||||
return EventFieldType.REAL;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.deepclone.lw.cli.xmlimport.data.evdef;
|
||||
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A text event field definition
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*/
|
||||
@XStreamAlias( "text" )
|
||||
@SuppressWarnings( "serial" )
|
||||
public class TextEventField
|
||||
extends EventFieldBase
|
||||
{
|
||||
|
||||
/** The field's minimum length */
|
||||
@XStreamAsAttribute
|
||||
@XStreamAlias( "min-length" )
|
||||
private Integer minLength;
|
||||
|
||||
/** The field's maximum length */
|
||||
@XStreamAsAttribute
|
||||
@XStreamAlias( "max-length" )
|
||||
private Integer maxLength;
|
||||
|
||||
|
||||
public Integer getMinLength( )
|
||||
{
|
||||
return this.minLength;
|
||||
}
|
||||
|
||||
|
||||
public Integer getMaxLength( )
|
||||
{
|
||||
return this.maxLength;
|
||||
}
|
||||
|
||||
|
||||
/** @return {@link EventFieldType#TEXT} */
|
||||
@Override
|
||||
public EventFieldType getType( )
|
||||
{
|
||||
return EventFieldType.TEXT;
|
||||
}
|
||||
|
||||
}
|
|
@ -39,6 +39,8 @@ from the root of the server's distribution:
|
|||
|
||||
java -jar legacyworlds-server-main-1.0.0-0.jar \
|
||||
--run-tool ImportText data/i18n-text.xml
|
||||
java -jar legacyworlds-server-main-1.0.0-0.jar \
|
||||
--run-tool ImportEvents data/event-definitions.xml
|
||||
java -jar legacyworlds-server-main-1.0.0-0.jar \
|
||||
--run-tool ImportTechGraph data/tech-graph.xml
|
||||
java -jar legacyworlds-server-main-1.0.0-0.jar \
|
||||
|
|
Reference in a new issue