/* ** j###t ########## #### #### ** j###t ########## #### #### ** j###T "###L J###" ** ######P' ########## ######### ** ######k, ########## T######T ** ####~###L #### ** #### q###L ########## .##### ** #### \###L ########## #####" ** ** $Id$ ** ** Class History ** ** Date Name Description ** ---------|------------|----------------------------------------------- ** 24Aug98 subtle start of recorded history ** */ package key.commands; import key.*; import key.primitive.*; import java.io.IOException; import java.util.StringTokenizer; public class Set extends Command { private static final long serialVersionUID = -5068724951236294607L; public Set() { setKey( "set" ); usage = "<property> <value>"; } public void run( Player p, StringTokenizer args, String fullLine, CategoryCommand caller, InteractiveConnection ic, Flags flags ) throws IOException { if( !args.hasMoreTokens() ) { usage( ic ); return; } String propertyId = args.nextToken(); if( !args.hasMoreTokens() ) { usage( ic ); return; } String valueString = args.nextToken( "" ).trim(); // search for propertyId, set it to valueString Search search = new Search( propertyId, p.getContext() ); Object o = search.matchedResult; try { if( o instanceof AtomicElement ) { AtomicElement ae = (AtomicElement) o; if( ae.isReadOnly() ) { ic.sendFailure( "That property is read-only." ); return; } else if( ae.isReference() ) { ae.setValue( search.lastAtom, valueString, p.getContext() ); } else if( ae.isAtomic() ) { if( valueString.equalsIgnoreCase( Key.nullString ) ) ae.setValue( search.lastAtom, null, p.getContext() ); else { StringTokenizer st = new StringTokenizer( valueString ); if( st.hasMoreTokens() ) { String className = st.nextToken(); try { Atom r = (Atom) Factory.makeAtom( Class.forName( "key." + className ) ); if( st.hasMoreTokens() ) r.argument( st.nextToken() ); ae.setValue( search.lastAtom, r, p.getContext() ); } catch( ClassNotFoundException e ) { ic.sendFailure( "Type not found: " + e.getMessage() ); return; } catch( IllegalAccessException e ) { ic.sendFailure( "Error accessing type: " + e.getMessage() ); return; } } else { ic.sendFailure( "No value supplied for atomic set." ); return; } } } else { if( valueString.equalsIgnoreCase( Key.nullString ) ) ae.setValue( search.lastAtom, null, p.getContext() ); else { // special case for string assigns so we can // have leading and trailing spaces if( ae.getClassOf() == String.class ) { if( valueString.length() > 1 ) { if( valueString.charAt( 0 ) == '\"' ) { int i = valueString.lastIndexOf( '\"' ); if( i != -1 ) valueString = valueString.substring( 1, i ); } } ae.setValue( search.lastAtom, valueString, p.getContext() ); } else { // we can convert a string to a lot of things, if // we're clever, which we are ;) Class c = ae.getClassOf(); if( c == Boolean.class || c == Boolean.TYPE ) { if( valueString.equalsIgnoreCase( "true" ) ) ae.setValue( search.lastAtom, Boolean.TRUE, p.getContext() ); else if( valueString.equalsIgnoreCase( "false" ) ) ae.setValue( search.lastAtom, Boolean.FALSE, p.getContext() ); else { ic.sendFailure( "'" + valueString + "' can not be recognised as a boolean (use 'true' or 'false')" ); return; } } else if( c == Integer.class || c == Integer.TYPE ) { try { ae.setValue( search.lastAtom, new Integer( Integer.parseInt( valueString ) ), p.getContext() ); } catch( NumberFormatException e ) { ic.sendFailure( "'" + valueString + "' can not be recognised as an integer (use digits)" ); return; } } else if( c == Gender.class ) { // should probably be in gender if( valueString.equalsIgnoreCase( "male" ) ) ae.setValue( search.lastAtom, Gender.MALE_GENDER, p.getContext() ); else if( valueString.equalsIgnoreCase( "female" ) ) ae.setValue( search.lastAtom, Gender.FEMALE_GENDER, p.getContext() ); else if( valueString.equalsIgnoreCase( "neuter" ) ) ae.setValue( search.lastAtom, Gender.NEUTER_GENDER, p.getContext() ); else { ic.sendFailure( "'" + valueString + "' can not be recognised as a gender (use 'male', 'female' or 'neuter')" ); return; } } else if( c == Duration.class ) { try { ae.setValue( search.lastAtom, new Duration( Duration.parse( valueString ) ), p.getContext() ); } catch( NumberFormatException e ) { ic.sendFailure( "'" + valueString + "' can not be recognised as a duration: " + e.getMessage() ); return; } } else { ic.sendFailure( "cannot coerce to type " + Type.typeFor( c ).getName() ); return; } } } } } else if( o != null ) { ic.sendFailure( "That is not a property, it is: " + Type.typeOf( o ).getName() ); return; } else { ic.sendFailure( "'" + propertyId + "' not found." ); return; } } catch( IllegalAccessException e ) { ic.sendError( "Illegal access: " + e.getMessage() ); } sendOkay( ic ); } protected void sendOkay( InteractiveConnection ic ) { ic.sendFeedback( "Okay" ); //Log.log( "level", p.getName() + ", from context '" + p.getContext().getId() + "': set " + propertyId + " " + valueString ); } }