diff options
| author | Benjamin Culkin <scorpress@gmail.com> | 2024-05-20 17:58:16 -0400 |
|---|---|---|
| committer | Benjamin Culkin <scorpress@gmail.com> | 2024-05-20 17:58:16 -0400 |
| commit | 40a9d99496e098562f090fb7ffce9e749011b131 (patch) | |
| tree | 437df24d65470582e943e494a52db8ed65a881ae /projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WOComponent.java | |
| parent | ff072dfe782f6f22123cd4ba050828d35c0d0fbd (diff) | |
Formatting pass
Diffstat (limited to 'projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WOComponent.java')
| -rw-r--r-- | projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WOComponent.java | 2118 |
1 files changed, 942 insertions, 1176 deletions
diff --git a/projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WOComponent.java b/projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WOComponent.java index 20d8b0a..c99768c 100644 --- a/projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WOComponent.java +++ b/projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WOComponent.java @@ -42,1271 +42,1037 @@ import net.wotonomy.foundation.NSMutableDictionary; import net.wotonomy.foundation.NSSelector; /** -* Pure java implementation of WOComponent. -* -* @author michael@mpowers.net -* @author $Author: cgruber $ -* @version $Revision: 905 $ -*/ -public class WOComponent - extends WOElement - implements WOActionResults, - net.wotonomy.control.EOKeyValueCodingAdditions, - net.wotonomy.control.EOKeyValueCoding -{ + * Pure java implementation of WOComponent. + * + * @author michael@mpowers.net + * @author $Author: cgruber $ + * @version $Revision: 905 $ + */ +public class WOComponent extends WOElement implements WOActionResults, net.wotonomy.control.EOKeyValueCodingAdditions, + net.wotonomy.control.EOKeyValueCoding { WOElement rootElement; - - private static final String DIRECTORY_SUFFIX = ".wo"; - private static final String TEMPLATE_SUFFIX = ".html"; - private static final String DECLARATION_SUFFIX = ".wod"; - - private static final String OPEN_TAG = "webobject"; - private static final String CLOSE_TAG = "/webobject"; - private static final String NAME_KEY = "name"; - - protected transient WOContext context; // don't persist - protected boolean cachingEnabled; - protected WOElement template; - protected WOComponent parent; + + private static final String DIRECTORY_SUFFIX = ".wo"; + private static final String TEMPLATE_SUFFIX = ".html"; + private static final String DECLARATION_SUFFIX = ".wod"; + + private static final String OPEN_TAG = "webobject"; + private static final String CLOSE_TAG = "/webobject"; + private static final String NAME_KEY = "name"; + + protected transient WOContext context; // don't persist + protected boolean cachingEnabled; + protected WOElement template; + protected WOComponent parent; + + /** + * Default constructor. Deprecated in latest spec. + */ + public WOComponent() { + parent = null; + cachingEnabled = true; + template = null; + } + + /** + * Constructor specifying a context. + */ + public WOComponent(WOContext aContext) { + this(); + context = aContext; + } + + /** + * Returns the name of the component, which is usually just the class name. + */ + public String name() { + return justTheClassName(); + } /** - * Default constructor. Deprecated in latest spec. - */ - public WOComponent () - { - parent = null; - cachingEnabled = true; - template = null; - } - - /** - * Constructor specifying a context. - */ - public WOComponent( WOContext aContext ) - { - this(); - context = aContext; - } - + * Returns the system-dependent file path to the current component directory, + * including the ".wo" extension. + */ + public String path() { + throw new RuntimeException("Not implemented yet."); + } + /** - * Returns the name of the component, which is usually just the class name. - */ - public String name () - { - return justTheClassName(); - } - - /** - * Returns the system-dependent file path to the current component - * directory, including the ".wo" extension. - */ - public String path () - { - throw new RuntimeException( "Not implemented yet." ); - } + * Returns the URL for this component, relative to the server's document root on + * the server's file system. This is not an http url. + */ + public String baseURL() { + throw new RuntimeException("Not implemented yet."); + } /** - * Returns the URL for this component, relative to the server's - * document root on the server's file system. - * This is not an http url. - */ - public String baseURL () - { - throw new RuntimeException( "Not implemented yet." ); - } + * Returns the name of the framework that contains this component, or null if + * the component does not belong to a framework. This currently returns the + * package path of the class, or null if it does not belong to a package. + */ + public String frameworkName() { + return justTheResourcePath(); + } /** - * Returns the name of the framework that contains this component, - * or null if the component does not belong to a framework. - * This currently returns the package path of the class, or - * null if it does not belong to a package. - */ - public String frameworkName () - { - return justTheResourcePath(); - } - - /** - * Sets whether templates are cached. If true, templates will - * only be read once per application lifetime. Otherwise, templates - * will be read each time this class is instantiated. Defaults to false. - */ - public void setCachingEnabled (boolean enabled) - { + * Sets whether templates are cached. If true, templates will only be read once + * per application lifetime. Otherwise, templates will be read each time this + * class is instantiated. Defaults to false. + */ + public void setCachingEnabled(boolean enabled) { cachingEnabled = enabled; } - /** - * Returns whether templates are cached. If true, templates are - * read once per application lifetime. Otherwise, templates are - * read each time this class is instantiated. - */ - public boolean isCachingEnabled () - { - return cachingEnabled && WOApplication.application().isCachingEnabled(); - } - - /** - * Returns the root of the tree of elements produced by parsing - * the templates in the component directory for this component. - */ - public WOElement template() - { - return template; - } - - /** - * Returns the root of the tree of elements produced by parsing - * the templates in the component directory for the named component. - * @deprecated Use template() instead. - */ - public WOElement templateWithName(String aComponentName) - { - return templateWithName( aComponentName, null ); - } - - /** - * Returns the root of the tree of elements produced by parsing - * the templates in the component directory for the named component. - */ - WOElement templateWithName(String aComponentName, String aFramework) - { - NSArray languages = null; - WOContext context = context(); - if ( context != null ) - { - languages = context.request().browserLanguages(); - } - WOElement result = templateWithHTMLString( - readTemplateResource( aComponentName, aFramework, TEMPLATE_SUFFIX, languages ), - readTemplateResource( aComponentName, aFramework, DECLARATION_SUFFIX, languages ), - languages ); - if ( result == null ) - { - System.out.println( "WOComponent.templateWithName: failed for " + aComponentName ); - } - return result; - } - - /** - * Returns the root of the tree of elements produced by parsing - * the specfified HTML string and bindings declaration string. - * Note: language list is currently ignored. - */ - public static WOElement templateWithHTMLString ( - String anHTMLString, String aDeclaration, List aLanguageList) - { - if ( anHTMLString == null ) return null; - WOElement result = null; - try - { - NSDictionary bindings = processDeclaration( aDeclaration ); - List elements = new LinkedList(); - int index = processTemplate( elements, anHTMLString, 0, bindings, aLanguageList ); - if ( index == -1 ) - { - if ( elements.size() == 1 ) - { - result = (WOElement) elements.get(0); - } - else - { - result = new WOParentElement( elements ); - } - } - else // entire template did not process - { - throw new RuntimeException( "No closing tag: " + anHTMLString.substring( index ) ); - } - } - catch ( Exception exc ) - { - exc.printStackTrace(); - } + /** + * Returns whether templates are cached. If true, templates are read once per + * application lifetime. Otherwise, templates are read each time this class is + * instantiated. + */ + public boolean isCachingEnabled() { + return cachingEnabled && WOApplication.application().isCachingEnabled(); + } + + /** + * Returns the root of the tree of elements produced by parsing the templates in + * the component directory for this component. + */ + public WOElement template() { + return template; + } + + /** + * Returns the root of the tree of elements produced by parsing the templates in + * the component directory for the named component. + * + * @deprecated Use template() instead. + */ + public WOElement templateWithName(String aComponentName) { + return templateWithName(aComponentName, null); + } + + /** + * Returns the root of the tree of elements produced by parsing the templates in + * the component directory for the named component. + */ + WOElement templateWithName(String aComponentName, String aFramework) { + NSArray languages = null; + WOContext context = context(); + if (context != null) { + languages = context.request().browserLanguages(); + } + WOElement result = templateWithHTMLString( + readTemplateResource(aComponentName, aFramework, TEMPLATE_SUFFIX, languages), + readTemplateResource(aComponentName, aFramework, DECLARATION_SUFFIX, languages), languages); + if (result == null) { + System.out.println("WOComponent.templateWithName: failed for " + aComponentName); + } return result; - } - - /** - * Called at the beginning of a request-response cycle. - * Override to perform any necessary initialization. - * This implementation does nothing. - */ - public void awake () - { - } - - /** - * Package access only. Called to initialize the component with - * the proper context before the start of the request-response cycle. - * If the context has a current component, that component becomes - * this component's parent. - */ - void ensureAwakeInContext (WOContext aContext) - { + } + + /** + * Returns the root of the tree of elements produced by parsing the specfified + * HTML string and bindings declaration string. Note: language list is currently + * ignored. + */ + public static WOElement templateWithHTMLString(String anHTMLString, String aDeclaration, List aLanguageList) { + if (anHTMLString == null) + return null; + WOElement result = null; + try { + NSDictionary bindings = processDeclaration(aDeclaration); + List elements = new LinkedList(); + int index = processTemplate(elements, anHTMLString, 0, bindings, aLanguageList); + if (index == -1) { + if (elements.size() == 1) { + result = (WOElement) elements.get(0); + } else { + result = new WOParentElement(elements); + } + } else // entire template did not process + { + throw new RuntimeException("No closing tag: " + anHTMLString.substring(index)); + } + } catch (Exception exc) { + exc.printStackTrace(); + } + return result; + } + + /** + * Called at the beginning of a request-response cycle. Override to perform any + * necessary initialization. This implementation does nothing. + */ + public void awake() { + } + + /** + * Package access only. Called to initialize the component with the proper + * context before the start of the request-response cycle. If the context has a + * current component, that component becomes this component's parent. + */ + void ensureAwakeInContext(WOContext aContext) { context = aContext; parent = aContext.parent(); - if ( template == null ) - { - template = templateWithName( name(), frameworkName() ); - } - if ( template != null ) - { - template.ensureAwakeInContext( aContext ); - } - awake(); - } - - public void takeValuesFromRequest (WORequest aRequest, WOContext aContext) - { - if ( synchronizesVariablesWithBindings() ) - { - pullValuesFromParent(); - if ( template != null ) - { - template.takeValuesFromRequest( aRequest, aContext ); - } - pushValuesToParent(); - } - else - if ( template != null ) - { - template.takeValuesFromRequest( aRequest, aContext ); - } - } - - public WOActionResults invokeAction (WORequest aRequest, WOContext aContext) - { - WOActionResults result = null; - if ( synchronizesVariablesWithBindings() ) - { - pullValuesFromParent(); - if ( template != null ) - { - result = template.invokeAction( aRequest, aContext ); - } - pushValuesToParent(); - } - else - if ( template != null ) - { - result = template.invokeAction( aRequest, aContext ); - } + if (template == null) { + template = templateWithName(name(), frameworkName()); + } + if (template != null) { + template.ensureAwakeInContext(aContext); + } + awake(); + } + + public void takeValuesFromRequest(WORequest aRequest, WOContext aContext) { + if (synchronizesVariablesWithBindings()) { + pullValuesFromParent(); + if (template != null) { + template.takeValuesFromRequest(aRequest, aContext); + } + pushValuesToParent(); + } else if (template != null) { + template.takeValuesFromRequest(aRequest, aContext); + } + } + + public WOActionResults invokeAction(WORequest aRequest, WOContext aContext) { + WOActionResults result = null; + if (synchronizesVariablesWithBindings()) { + pullValuesFromParent(); + if (template != null) { + result = template.invokeAction(aRequest, aContext); + } + pushValuesToParent(); + } else if (template != null) { + result = template.invokeAction(aRequest, aContext); + } return result; - } - - public void appendToResponse (WOResponse aResponse, WOContext aContext) - { - if ( synchronizesVariablesWithBindings() ) - { - pullValuesFromParent(); - if ( template != null ) - { - template.appendToResponse( aResponse, aContext ); - } - pushValuesToParent(); - } - else - if ( template != null ) - { - template.appendToResponse( aResponse, aContext ); - } - context = null; - } - - /** - * Called at the end of a request-response cycle. - * Override to perform any necessary clean-up. - * This implementation does nothing. - */ - public void sleep () - { - } - - /** - * Generates a WOResponse and calls appendToResponse() on it. - */ - public WOResponse generateResponse () - { - WOResponse response = new WOResponse(); - WOContext context = context(); - appendToResponse( response, context ); // nulls out context - context.session().savePage( this ); //?is this the right place for this? - return response; - } + } + + public void appendToResponse(WOResponse aResponse, WOContext aContext) { + if (synchronizesVariablesWithBindings()) { + pullValuesFromParent(); + if (template != null) { + template.appendToResponse(aResponse, aContext); + } + pushValuesToParent(); + } else if (template != null) { + template.appendToResponse(aResponse, aContext); + } + context = null; + } + + /** + * Called at the end of a request-response cycle. Override to perform any + * necessary clean-up. This implementation does nothing. + */ + public void sleep() { + } /** - * Returns this component's parent component, or null if none. - */ - public WOComponent parent() - { - return parent; - } - - /** - * Invokes the specified action on this component's parent. - * Variables will be synchronized when this method returns. - */ - public WOActionResults performParentAction(String anAction) - { - WOActionResults result = parent().performAction( anAction ); - if ( synchronizesVariablesWithBindings() ) - { - pullValuesFromParent(); - } - return result; - } - - /** - * Invokes the specified action on this component. - */ - WOActionResults performAction( String anAction ) - { - try - { - return (WOActionResults) NSSelector.invoke( anAction, this ); + * Generates a WOResponse and calls appendToResponse() on it. + */ + public WOResponse generateResponse() { + WOResponse response = new WOResponse(); + WOContext context = context(); + appendToResponse(response, context); // nulls out context + context.session().savePage(this); // ?is this the right place for this? + return response; + } + + /** + * Returns this component's parent component, or null if none. + */ + public WOComponent parent() { + return parent; + } + + /** + * Invokes the specified action on this component's parent. Variables will be + * synchronized when this method returns. + */ + public WOActionResults performParentAction(String anAction) { + WOActionResults result = parent().performAction(anAction); + if (synchronizesVariablesWithBindings()) { + pullValuesFromParent(); } - catch ( NoSuchMethodException exc ) - { + return result; + } + + /** + * Invokes the specified action on this component. + */ + WOActionResults performAction(String anAction) { + try { + return (WOActionResults) NSSelector.invoke(anAction, this); + } catch (NoSuchMethodException exc) { // returns below - } - catch ( InvocationTargetException exc ) - { + } catch (InvocationTargetException exc) { Throwable t = exc.getTargetException(); - exc.printStackTrace(); - throw new RuntimeException( t.toString() ); + exc.printStackTrace(); + throw new RuntimeException(t.toString()); + } catch (Exception exc) { + exc.printStackTrace(); + throw new RuntimeException(exc.toString()); } - catch ( Exception exc ) - { - exc.printStackTrace(); - throw new RuntimeException( exc.toString() ); + return null; + } + + /** + * Called before each phase of the request-response cycle, if + * synchronizesVariablesWithBindings is true and the component is not stateless. + */ + public void pullValuesFromParent() { + if (associations == null) + return; + String key; + Enumeration e = associations.keyEnumerator(); + while (e.hasMoreElements()) { + key = e.nextElement().toString(); + takeValueForKey(valueForBinding(key), key); + } + } + + /** + * Called after each phase of the request-response cycle, if + * synchronizesVariablesWithBindings is true and the component is not stateless. + */ + public void pushValuesToParent() { + if (associations == null) + return; + String key; + Enumeration e = associations.keyEnumerator(); + while (e.hasMoreElements()) { + key = e.nextElement().toString(); + setValueForBinding(valueForKey(key), key); } - return null; - } - - /** - * Called before each phase of the request-response cycle, - * if synchronizesVariablesWithBindings is true and the - * component is not stateless. - */ - public void pullValuesFromParent() - { - if ( associations == null ) return; - String key; - Enumeration e = associations.keyEnumerator(); - while ( e.hasMoreElements() ) - { - key = e.nextElement().toString(); - takeValueForKey( valueForBinding( key ), key ); - } - } - - /** - * Called after each phase of the request-response cycle, - * if synchronizesVariablesWithBindings is true and the - * component is not stateless. - */ - public void pushValuesToParent() - { - if ( associations == null ) return; - String key; - Enumeration e = associations.keyEnumerator(); - while ( e.hasMoreElements() ) - { - key = e.nextElement().toString(); - setValueForBinding( valueForKey( key ), key ); - } - } - - /** - * Returns whether this component should be considered stateless. - * Stateless components are shared between sessions to conserve memory. - * This implementation returns false; override to return true. - */ - public boolean isStateless() - { - return false; - } - - /** - * Called only on stateless components to tell themselves to reset - * themselves for another invocation using a different context. - * This implementation does nothing. - */ - public void reset() - { - // does nothing - } - - /** - * Returns the application containing this instance of the class. - */ - public WOApplication application () - { - return context.application(); - } - - /** - * Returns whether a session has been created for this user. - */ - public boolean hasSession () - { - return context.hasSession(); - } - - /** - * Returns the current session object, creating it if it doesn't exist. - */ - public WOSession session () - { - return context.session(); - } + } + + /** + * Returns whether this component should be considered stateless. Stateless + * components are shared between sessions to conserve memory. This + * implementation returns false; override to return true. + */ + public boolean isStateless() { + return false; + } + + /** + * Called only on stateless components to tell themselves to reset themselves + * for another invocation using a different context. This implementation does + * nothing. + */ + public void reset() { + // does nothing + } /** - * Returns the current context for this component. - */ - public WOContext context () - { - return context; - } + * Returns the application containing this instance of the class. + */ + public WOApplication application() { + return context.application(); + } /** - * Returns a new WOComponent with the specified name. - * If null, returns the component named "Main". - * If the named component doesn't exist, returns null. - */ - public WOComponent pageWithName (String aName) - { - return application().pageWithName( aName, context() ); - } + * Returns whether a session has been created for this user. + */ + public boolean hasSession() { + return context.hasSession(); + } /** - * Called when exceptions are raised by assigning values - * to this object. This implementation does nothing, but - * subclasses may override to do something useful. - */ - public void validationFailedWithException ( - Throwable anException, Object aValue, String aPath) - { - // does nothing - } + * Returns the current session object, creating it if it doesn't exist. + */ + public WOSession session() { + return context.session(); + } /** - * Called on the component that represents the requested page. - * Override to return logging information specific to your - * component. This implementation returns the component's name. - */ - public String descriptionForResponse ( - WOResponse aResponse, WOContext aContext) - { - return name(); - } + * Returns the current context for this component. + */ + public WOContext context() { + return context; + } /** - * Returns true if this component should get and set values - * in its parent. This implementation returns true. - * Override to create a component that does not automatically - * synchronize bindings with its parent, useful if you wish - * to handle synchronization manually. - */ - public boolean synchronizesVariablesWithBindings () - { - return true; - } - - /** - * Returns whether this component has a readable value that maps - * to the specified binding. This implementation calls - * hasBinding(aBinding). - */ - public boolean canGetValueForBinding(String aBinding) - { - return hasBinding( aBinding ); - } - - /** - * Returns whether this component has a writable value that maps - * to the specified binding. - */ - public boolean canSetValueForBinding(String aBinding) - { - WOAssociation assoc = - (WOAssociation)associations.objectForKey(aBinding); - if (assoc != null) - { - if ( assoc.isValueSettable() ) return true; - } - return false; - } - - /** - * Returns whether this component has the specified binding. - */ - public boolean hasBinding (String aBinding) - { - if ( associations == null ) return false; - return associations.containsKey( aBinding ); - } + * Returns a new WOComponent with the specified name. If null, returns the + * component named "Main". If the named component doesn't exist, returns null. + */ + public WOComponent pageWithName(String aName) { + return application().pageWithName(aName, context()); + } + + /** + * Called when exceptions are raised by assigning values to this object. This + * implementation does nothing, but subclasses may override to do something + * useful. + */ + public void validationFailedWithException(Throwable anException, Object aValue, String aPath) { + // does nothing + } + + /** + * Called on the component that represents the requested page. Override to + * return logging information specific to your component. This implementation + * returns the component's name. + */ + public String descriptionForResponse(WOResponse aResponse, WOContext aContext) { + return name(); + } /** - * Returns the value for the specified binding for this component. - * The parent component is expected to have set the binding for - * this component. If no such binding exists, the binding is - * treated as a property is and obtained using valueForKey. - * If the property is not found, this method returns null. - */ - public Object valueForBinding (String aBinding) - { - WOComponent parent = parent(); - if ( associations != null ) - { - WOAssociation assoc = - (WOAssociation)associations.objectForKey(aBinding); - if (assoc != null && parent != null) - { - return assoc.valueInComponent( parent ); - } - } - if ( parent != null ) - { - return parent.valueForKey( aBinding ); - } - return null; - } + * Returns true if this component should get and set values in its parent. This + * implementation returns true. Override to create a component that does not + * automatically synchronize bindings with its parent, useful if you wish to + * handle synchronization manually. + */ + public boolean synchronizesVariablesWithBindings() { + return true; + } + + /** + * Returns whether this component has a readable value that maps to the + * specified binding. This implementation calls hasBinding(aBinding). + */ + public boolean canGetValueForBinding(String aBinding) { + return hasBinding(aBinding); + } + + /** + * Returns whether this component has a writable value that maps to the + * specified binding. + */ + public boolean canSetValueForBinding(String aBinding) { + WOAssociation assoc = (WOAssociation) associations.objectForKey(aBinding); + if (assoc != null) { + if (assoc.isValueSettable()) + return true; + } + return false; + } + + /** + * Returns whether this component has the specified binding. + */ + public boolean hasBinding(String aBinding) { + if (associations == null) + return false; + return associations.containsKey(aBinding); + } + + /** + * Returns the value for the specified binding for this component. The parent + * component is expected to have set the binding for this component. If no such + * binding exists, the binding is treated as a property is and obtained using + * valueForKey. If the property is not found, this method returns null. + */ + public Object valueForBinding(String aBinding) { + WOComponent parent = parent(); + if (associations != null) { + WOAssociation assoc = (WOAssociation) associations.objectForKey(aBinding); + if (assoc != null && parent != null) { + return assoc.valueInComponent(parent); + } + } + if (parent != null) { + return parent.valueForKey(aBinding); + } + return null; + } /** - * Sets the value for the specified binding for this component. - * The parent component is expected to have set the binding - * for this component. If no such binding exists, the binding - * is treated as a property and is set using takeValueForKey. - * If the property is not found, this method fails silently. - */ - public void setValueForBinding (Object aValue, String aBinding) - { - if ( associations == null ) return; - - WOComponent parent = parent(); - - if ( associations != null ) - { - WOAssociation assoc = - (WOAssociation)associations.objectForKey(aBinding); - if (assoc != null && parent != null) - { - if ( assoc.isValueSettable() ) - { - assoc.setValue( aValue, parent ); - return; - } - } - } - if ( parent != null ) - { - parent.takeValueForKey( aValue, aBinding ); - } - } - - public static void logString (String aString) - { - System.out.println( aString ); - } - - public static void debugString (String aString) - { - System.err.println( aString ); - } - - public Object valueForKeyPath (String aPath) - { - // currently key value coding support also handles keypaths - return valueForKey( aPath ); - } - - public void takeValueForKeyPath (Object aValue, String aPath) - { - // currently key value coding support also handles keypaths - takeValueForKey( aValue, aPath ); - } - - public NSDictionary valuesForKeys (List aKeyList) - { - throw new RuntimeException( "Not implemented yet." ); - } - - public void takeValuesFromDictionary (Map aValueMap) - { - throw new RuntimeException( "Not implemented yet." ); - } - - public Object valueForKey (String aKey) - { // System.out.println( "valueForKey: " + aKey + "->" + this ); - // handle "^" property keys - if ( aKey.startsWith( "^" ) ) - { - return valueForBinding( aKey.substring(1) ); - } - return EOKeyValueCodingSupport.valueForKey( this, aKey ); - } - - public void takeValueForKey (Object aValue, String aKey) - { // System.out.println( "takeValueForKey: " + aKey + " : " + aValue + "->" + this ); - // handle "^" property keys - if ( aKey.startsWith( "^" ) ) - { - setValueForBinding( aValue, aKey.substring(1) ); - return; - } - EOKeyValueCodingSupport.takeValueForKey( this, aValue, aKey ); - } - - public Object storedValueForKey (String aKey) - { - return EOKeyValueCodingSupport.storedValueForKey( this, aKey ); - } - - public void takeStoredValueForKey (Object aValue, String aKey) - { - EOKeyValueCodingSupport.takeStoredValueForKey( this, aValue, aKey ); - } - - public Object handleQueryWithUnboundKey (String aKey) - { - return EOKeyValueCodingSupport.handleQueryWithUnboundKey( this, aKey ); - } - - public void handleTakeValueForUnboundKey (Object aValue, String aKey) - { - EOKeyValueCodingSupport.handleTakeValueForUnboundKey( this, aValue, aKey ); - } - - public void unableToSetNullForKey (String aKey) - { - EOKeyValueCodingSupport.unableToSetNullForKey( this, aKey ); - } - - public Object validateTakeValueForKeyPath (Object aValue, String aKey) - { - throw new RuntimeException( "Not implemented yet." ); - } + * Sets the value for the specified binding for this component. The parent + * component is expected to have set the binding for this component. If no such + * binding exists, the binding is treated as a property and is set using + * takeValueForKey. If the property is not found, this method fails silently. + */ + public void setValueForBinding(Object aValue, String aBinding) { + if (associations == null) + return; + + WOComponent parent = parent(); + + if (associations != null) { + WOAssociation assoc = (WOAssociation) associations.objectForKey(aBinding); + if (assoc != null && parent != null) { + if (assoc.isValueSettable()) { + assoc.setValue(aValue, parent); + return; + } + } + } + if (parent != null) { + parent.takeValueForKey(aValue, aBinding); + } + } + + public static void logString(String aString) { + System.out.println(aString); + } + + public static void debugString(String aString) { + System.err.println(aString); + } + + public Object valueForKeyPath(String aPath) { + // currently key value coding support also handles keypaths + return valueForKey(aPath); + } + + public void takeValueForKeyPath(Object aValue, String aPath) { + // currently key value coding support also handles keypaths + takeValueForKey(aValue, aPath); + } + + public NSDictionary valuesForKeys(List aKeyList) { + throw new RuntimeException("Not implemented yet."); + } + + public void takeValuesFromDictionary(Map aValueMap) { + throw new RuntimeException("Not implemented yet."); + } + public Object valueForKey(String aKey) { // System.out.println( "valueForKey: " + aKey + "->" + this ); + // handle "^" property keys + if (aKey.startsWith("^")) { + return valueForBinding(aKey.substring(1)); + } + return EOKeyValueCodingSupport.valueForKey(this, aKey); + } + + public void takeValueForKey(Object aValue, String aKey) { // System.out.println( "takeValueForKey: " + aKey + " : " + // + aValue + "->" + this ); + // handle "^" property keys + if (aKey.startsWith("^")) { + setValueForBinding(aValue, aKey.substring(1)); + return; + } + EOKeyValueCodingSupport.takeValueForKey(this, aValue, aKey); + } + + public Object storedValueForKey(String aKey) { + return EOKeyValueCodingSupport.storedValueForKey(this, aKey); + } + + public void takeStoredValueForKey(Object aValue, String aKey) { + EOKeyValueCodingSupport.takeStoredValueForKey(this, aValue, aKey); + } + + public Object handleQueryWithUnboundKey(String aKey) { + return EOKeyValueCodingSupport.handleQueryWithUnboundKey(this, aKey); + } + + public void handleTakeValueForUnboundKey(Object aValue, String aKey) { + EOKeyValueCodingSupport.handleTakeValueForUnboundKey(this, aValue, aKey); + } + + public void unableToSetNullForKey(String aKey) { + EOKeyValueCodingSupport.unableToSetNullForKey(this, aKey); + } + + public Object validateTakeValueForKeyPath(Object aValue, String aKey) { + throw new RuntimeException("Not implemented yet."); + } // Template Processing - /** - * Takes a template string and a location to begin parsing, - * looking only for interesting tags, and calling itself recursively - * as necessary. Returns the index to resume parsing, or -1 if done. - */ - static private int processTemplate( - List elements, String template, int index, - Map bindings, List aLanguageList ) - throws java.io.IOException - { //System.out.println( "processTemplate: " + index ); - if ( template == null ) return -1; - - int start = index; - - while ( true ) - { - // search for start of next tag - start = template.indexOf( '<', start ); - - if ( start == -1 ) - { - // if no tags, send output and return - elements.add( new WOStaticElement( template.substring( index ) ) ); - return -1; - } - - // search for end of opening tag - int end = template.indexOf( ">", start + 1 ); - if ( end == -1 ) - { - // if no end to tag - throw new RuntimeException( "No end to tag: " - + template.substring( start ) ); - } - - boolean hasBody = true; - if ( template.charAt( end - 1 ) == '/' ) - { - // tag is standalone - no body - end = end - 1; - hasBody = false; - } - - // search for name of tag - int endName = start + 1; - while ( endName < end ) - { - if ( Character.isWhitespace( - template.charAt(endName) ) ) break; - endName++; - } - - String name = template.substring( start + 1, endName ); - - if ( name.toLowerCase().startsWith( OPEN_TAG ) ) - { - // add the contents before the tag - //System.out.println( index + " : " + start + " : " + hasBody ); - elements.add( new WOStaticElement( template.substring( index, start ) ) ); - - // interesting tag; parse parameters - Map params = new HashMap( 5 ); // arbitrary init length - if ( endName < end ) - { - // delimit by whitespace - StringTokenizer tokens = new StringTokenizer( - template.substring( endName+1, end ) ); - int equals; - String token; - String value; - while ( tokens.hasMoreTokens() ) - { - token = tokens.nextToken(); - equals = token.indexOf( '=' ); - if ( equals != -1 ) - { - value = token.substring( equals+1 ); - - if ( value.startsWith( "\"" ) ) - { - // handle spaces within parameter names - while ( ! value.endsWith( "\"" ) ) - { - value = value + " " + tokens.nextToken(); - } - - // strip quotation marks - if ( value.endsWith( "\"" ) ) - { - value = value.substring( 1, value.length()-1 ); - } - } - - // register key with specified value - params.put( - token.substring( 0, equals ).toLowerCase(), value ); - - } - else - { - // no value found, register the key name - params.put( token.toLowerCase(), "" ); - } - } - } - - index = end + (hasBody?1:2); - - WOElement body = null; - if ( hasBody ) - { - List childElements = new LinkedList(); - - index = processTemplate( - childElements, template, index, - bindings, aLanguageList ); - start = index; - - if ( index == -1 ) - { - throw new RuntimeException( - "No closing tag found: " + template.substring( end ) ); - } - - if ( childElements.size() == 1 ) - { - body = (WOElement) childElements.get(0); - } - else - { - body = new WOParentElement( childElements ); - } - } - - WOElement element = null; - String nameProperty = (String) params.get( NAME_KEY ); - NSDictionary original = (NSDictionary) bindings.get( nameProperty ); - //System.out.println( nameProperty + " : " + associations ); - if ( original == null ) - { - original = NSDictionary.EmptyDictionary; - System.err.println( "No associations for: " + nameProperty ); - System.err.println( bindings ); - } - - NSDictionary associations = new NSMutableDictionary( original ); - String elementClass = (String) associations.remove( WOApplication.ELEMENT_CLASS ); - - WOApplication application = WOApplication.application(); - element = application.dynamicElementWithName( - elementClass, associations, body, aLanguageList ); - if ( element == null ) - { - // unable to create element: show assocs in static element - element = new WOStaticElement( associations.toString() ); - } - - //System.out.println( element ); - elements.add( element ); - - if ( !hasBody ) - { - start = end + 2; - } - } - else - if ( name.toLowerCase().startsWith( CLOSE_TAG ) ) - { - // add any contents before the tag - elements.add( new WOStaticElement( template.substring( index, start ) ) ); - + /** + * Takes a template string and a location to begin parsing, looking only for + * interesting tags, and calling itself recursively as necessary. Returns the + * index to resume parsing, or -1 if done. + */ + static private int processTemplate(List elements, String template, int index, Map bindings, List aLanguageList) + throws java.io.IOException { // System.out.println( "processTemplate: " + index ); + if (template == null) + return -1; + + int start = index; + + while (true) { + // search for start of next tag + start = template.indexOf('<', start); + + if (start == -1) { + // if no tags, send output and return + elements.add(new WOStaticElement(template.substring(index))); + return -1; + } + + // search for end of opening tag + int end = template.indexOf(">", start + 1); + if (end == -1) { + // if no end to tag + throw new RuntimeException("No end to tag: " + template.substring(start)); + } + + boolean hasBody = true; + if (template.charAt(end - 1) == '/') { + // tag is standalone - no body + end = end - 1; + hasBody = false; + } + + // search for name of tag + int endName = start + 1; + while (endName < end) { + if (Character.isWhitespace(template.charAt(endName))) + break; + endName++; + } + + String name = template.substring(start + 1, endName); + + if (name.toLowerCase().startsWith(OPEN_TAG)) { + // add the contents before the tag + // System.out.println( index + " : " + start + " : " + hasBody ); + elements.add(new WOStaticElement(template.substring(index, start))); + + // interesting tag; parse parameters + Map params = new HashMap(5); // arbitrary init length + if (endName < end) { + // delimit by whitespace + StringTokenizer tokens = new StringTokenizer(template.substring(endName + 1, end)); + int equals; + String token; + String value; + while (tokens.hasMoreTokens()) { + token = tokens.nextToken(); + equals = token.indexOf('='); + if (equals != -1) { + value = token.substring(equals + 1); + + if (value.startsWith("\"")) { + // handle spaces within parameter names + while (!value.endsWith("\"")) { + value = value + " " + tokens.nextToken(); + } + + // strip quotation marks + if (value.endsWith("\"")) { + value = value.substring(1, value.length() - 1); + } + } + + // register key with specified value + params.put(token.substring(0, equals).toLowerCase(), value); + + } else { + // no value found, register the key name + params.put(token.toLowerCase(), ""); + } + } + } + + index = end + (hasBody ? 1 : 2); + + WOElement body = null; + if (hasBody) { + List childElements = new LinkedList(); + + index = processTemplate(childElements, template, index, bindings, aLanguageList); + start = index; + + if (index == -1) { + throw new RuntimeException("No closing tag found: " + template.substring(end)); + } + + if (childElements.size() == 1) { + body = (WOElement) childElements.get(0); + } else { + body = new WOParentElement(childElements); + } + } + + WOElement element = null; + String nameProperty = (String) params.get(NAME_KEY); + NSDictionary original = (NSDictionary) bindings.get(nameProperty); + // System.out.println( nameProperty + " : " + associations ); + if (original == null) { + original = NSDictionary.EmptyDictionary; + System.err.println("No associations for: " + nameProperty); + System.err.println(bindings); + } + + NSDictionary associations = new NSMutableDictionary(original); + String elementClass = (String) associations.remove(WOApplication.ELEMENT_CLASS); + + WOApplication application = WOApplication.application(); + element = application.dynamicElementWithName(elementClass, associations, body, aLanguageList); + if (element == null) { + // unable to create element: show assocs in static element + element = new WOStaticElement(associations.toString()); + } + + // System.out.println( element ); + elements.add(element); + + if (!hasBody) { + start = end + 2; + } + } else if (name.toLowerCase().startsWith(CLOSE_TAG)) { + // add any contents before the tag + elements.add(new WOStaticElement(template.substring(index, start))); + // return end + name.length() + 1; // "<" + ">" - 1 = 1 - return end + (hasBody?1:2); // "<" + ">" - 1 = 1 - } - else - { - // tag not interesting: continue - start = end + (hasBody?1:2); - } - } - } - - - // Utility Methods - - static private void rewriteTag( String tagName, - Map properties, String body, StringBuffer context ) - throws java.io.IOException - { - context.append( "<"+tagName ); + return end + (hasBody ? 1 : 2); // "<" + ">" - 1 = 1 + } else { + // tag not interesting: continue + start = end + (hasBody ? 1 : 2); + } + } + } + + // Utility Methods + + static private void rewriteTag(String tagName, Map properties, String body, StringBuffer context) + throws java.io.IOException { + context.append("<" + tagName); Iterator it = properties.keySet().iterator(); String key; - while ( it.hasNext() ) - { + while (it.hasNext()) { key = (String) it.next(); - context.append( " " + key + "=\"" + properties.get( key ) + "\"" ); + context.append(" " + key + "=\"" + properties.get(key) + "\""); } - - if ( body == null ) - { - context.append( "/>" ); + + if (body == null) { + context.append("/>"); return; } - - context.append( ">" + body + "</" + tagName + ">" ); + + context.append(">" + body + "</" + tagName + ">"); + } + + private String justTheClassName() { + String className = getClass().getName(); + int index = className.lastIndexOf("."); + if (index == -1) + return className; + return className.substring(index + 1); + } + + private String justTheResourcePath() { + int last = -1; + char[] src = getClass().getName().toCharArray(); + char[] dst = new char[src.length]; + for (int i = 0; i < src.length; i++) { + if (src[i] == '.') { + dst[i] = '/'; + last = i; + } else { + dst[i] = src[i]; + } + } + if (last == -1) + return null; + return new String(dst, 0, last); } - - private String justTheClassName() - { - String className = getClass().getName(); - int index = className.lastIndexOf( "." ); - if ( index == -1 ) return className; - return className.substring( index+1 ); - } - - private String justTheResourcePath() - { - int last = -1; - char[] src = getClass().getName().toCharArray(); - char[] dst = new char[ src.length ]; - for ( int i = 0; i < src.length; i++ ) - { - if ( src[i] == '.' ) - { - dst[i] = '/'; - last = i; - } - else - { - dst[i] = src[i]; - } - } - if ( last == -1 ) return null; - return new String( dst, 0, last ); - } - - private String readTemplateResource( String name, String framework, String suffix, NSArray languages ) - { - if ( name == null ) return null; - name = name + DIRECTORY_SUFFIX + '/' + name + suffix; - InputStream is = null; - if ( isCachingEnabled() ) - { - byte[] data = WOApplication.application().resourceManager().bytesForResourceNamed( - name, framework, languages ); - if ( data != null ) - { - is = new ByteArrayInputStream( data ); - } - } - else - { - is = WOApplication.application().resourceManager().inputStreamForResourceNamed( - name, framework, languages ); - } - if ( is == null ) - { - System.err.println( "No resources found for: " + name ); - return null; - } - - // try to autodetect encoding - String encoding = "ISO8859_1"; - try - { - byte[] header = new byte[4]; - is = new PushbackInputStream( is, 4 ); - is.read( header ); - if ( header[0] < 33 || header[0] > 126 ) - { - // if any funny characters, presume UTF-16 - encoding = "UTF-16"; - if (!( header[1] < 33 || header[1] > 126 )) - { - // if second character is valid, presume UTF-8 - encoding = "UTF-8"; - } - } - // check byte-order-mark - if (header[0] == 0xef && header[1] == 0xbb && header[2] == 0xbf) // utf-8 - { - encoding = "UTF-8"; - } - else - if (header[0] == 0xfe && header[1] == 0xff) // utf-16 - { - encoding = "UTF-16"; - } - else - if (header[0] == 0 && header[1] == 0 && header[2] == 0xfe && header[3] == 0xff) // ucs-4 - { - encoding = "UCS-4"; //?? - } - else - if (header[0] == 0xff && header[1] == 0xfe) // ucs-2le, ucs-4le, and - { - encoding = "UCS-16le"; //?? - } - // put back the header - ((PushbackInputStream)is).unread( header ); - } - catch ( Throwable t ) - { - t.printStackTrace(); - System.err.println( - "Error while autodetecting encoding: should never happen" ); - } - - try - { - String line; - StringBuffer buf = new StringBuffer(); - BufferedReader r = new BufferedReader( new InputStreamReader( is, encoding ) ); - while ( ( line = r.readLine() ) != null ) - { - buf.append( line ); - buf.append( '\n' ); - } - is.close(); // release the resource - return buf.toString(); - } - catch ( IOException exc ) - { - System.err.println( "Error while reading: " + name ); - exc.printStackTrace(); - return null; - } - } - - // Declaration Parsing - - /** - * Parses the declarations in the specified content and returns a map of element names - * to maps of attribute names to WOAssociations. - */ - private static NSDictionary processDeclaration( String content ) - { - int index; - NSMutableDictionary result = new NSMutableDictionary(); - - // strip out comments - StringBuffer stripped = new StringBuffer(); - try - { - LineNumberReader reader = - new LineNumberReader( new StringReader( content ) ); - String line; - while ( ( line = reader.readLine() ) != null ) - { - index = line.indexOf("//"); - while (index > -1) { - //(chochos) This used to truncate lines with quoted URLs - //in them. We have to check that the "//" is not inside quotes. - boolean quoted = false; - if (index > 0) { - for (int _position = 0; _position < index; _position++) - if (line.charAt(_position) == '"') - quoted = !quoted; - } - if (!quoted) { - line = line.substring( 0, index ); - index = -1; - } else { - //if we didn't truncate the line it's because the // - //were quoted. let's look for more, and check if they're not quoted... - index = line.indexOf("\"", index); - if (index > 0) { - index = line.indexOf("//", index); - } - } - } - stripped.append( line ); - } + + private String readTemplateResource(String name, String framework, String suffix, NSArray languages) { + if (name == null) + return null; + name = name + DIRECTORY_SUFFIX + '/' + name + suffix; + InputStream is = null; + if (isCachingEnabled()) { + byte[] data = WOApplication.application().resourceManager().bytesForResourceNamed(name, framework, + languages); + if (data != null) { + is = new ByteArrayInputStream(data); + } + } else { + is = WOApplication.application().resourceManager().inputStreamForResourceNamed(name, framework, languages); } - catch ( IOException exc ) - { - throw new RuntimeException( - "Error while stripping comments from declaration: " + stripped ); + if (is == null) { + System.err.println("No resources found for: " + name); + return null; } - while ( (index = stripped.toString().indexOf( "/*" )) != -1 ) - { - int j = stripped.toString().indexOf( "*/", index+1 ); - if ( j == -1 ) break; - stripped.delete( index, j+2 ); - } - - String token; - StringTokenizer tokens = new StringTokenizer( stripped.toString(), "{}", true ); - while ( tokens.hasMoreTokens() ) - { - token = tokens.nextToken(); - - // next token is the name and class - String name, cl; - index = token.indexOf( ":" ); - if ( index > -1 ) - { - name = token.substring( 0, index ).trim(); - cl = token.substring( index+1 ).trim(); + + // try to autodetect encoding + String encoding = "ISO8859_1"; + try { + byte[] header = new byte[4]; + is = new PushbackInputStream(is, 4); + is.read(header); + if (header[0] < 33 || header[0] > 126) { + // if any funny characters, presume UTF-16 + encoding = "UTF-16"; + if (!(header[1] < 33 || header[1] > 126)) { + // if second character is valid, presume UTF-8 + encoding = "UTF-8"; + } } - else + // check byte-order-mark + if (header[0] == 0xef && header[1] == 0xbb && header[2] == 0xbf) // utf-8 + { + encoding = "UTF-8"; + } else if (header[0] == 0xfe && header[1] == 0xff) // utf-16 + { + encoding = "UTF-16"; + } else if (header[0] == 0 && header[1] == 0 && header[2] == 0xfe && header[3] == 0xff) // ucs-4 { - System.err.println( "Could not parse declaration:" ); - System.err.println( content ); - throw new RuntimeException( - "Could not parse declaration: " + token ); - } + encoding = "UCS-4"; // ?? + } else if (header[0] == 0xff && header[1] == 0xfe) // ucs-2le, ucs-4le, and + { + encoding = "UCS-16le"; // ?? + } + // put back the header + ((PushbackInputStream) is).unread(header); + } catch (Throwable t) { + t.printStackTrace(); + System.err.println("Error while autodetecting encoding: should never happen"); + } + + try { + String line; + StringBuffer buf = new StringBuffer(); + BufferedReader r = new BufferedReader(new InputStreamReader(is, encoding)); + while ((line = r.readLine()) != null) { + buf.append(line); + buf.append('\n'); + } + is.close(); // release the resource + return buf.toString(); + } catch (IOException exc) { + System.err.println("Error while reading: " + name); + exc.printStackTrace(); + return null; + } + } + + // Declaration Parsing + + /** + * Parses the declarations in the specified content and returns a map of element + * names to maps of attribute names to WOAssociations. + */ + private static NSDictionary processDeclaration(String content) { + int index; + NSMutableDictionary result = new NSMutableDictionary(); + + // strip out comments + StringBuffer stripped = new StringBuffer(); + try { + LineNumberReader reader = new LineNumberReader(new StringReader(content)); + String line; + while ((line = reader.readLine()) != null) { + index = line.indexOf("//"); + while (index > -1) { + // (chochos) This used to truncate lines with quoted URLs + // in them. We have to check that the "//" is not inside quotes. + boolean quoted = false; + if (index > 0) { + for (int _position = 0; _position < index; _position++) + if (line.charAt(_position) == '"') + quoted = !quoted; + } + if (!quoted) { + line = line.substring(0, index); + index = -1; + } else { + // if we didn't truncate the line it's because the // + // were quoted. let's look for more, and check if they're not quoted... + index = line.indexOf("\"", index); + if (index > 0) { + index = line.indexOf("//", index); + } + } + } + stripped.append(line); + } + } catch (IOException exc) { + throw new RuntimeException("Error while stripping comments from declaration: " + stripped); + } + while ((index = stripped.toString().indexOf("/*")) != -1) { + int j = stripped.toString().indexOf("*/", index + 1); + if (j == -1) + break; + stripped.delete(index, j + 2); + } + + String token; + StringTokenizer tokens = new StringTokenizer(stripped.toString(), "{}", true); + while (tokens.hasMoreTokens()) { + token = tokens.nextToken(); + + // next token is the name and class + String name, cl; + index = token.indexOf(":"); + if (index > -1) { + name = token.substring(0, index).trim(); + cl = token.substring(index + 1).trim(); + } else { + System.err.println("Could not parse declaration:"); + System.err.println(content); + throw new RuntimeException("Could not parse declaration: " + token); + } // next token is the declaration for the name and class - if ( ! tokens.hasMoreTokens() ) - { - System.err.println( "Could not find associations for declaration:" ); - System.err.println( content ); - throw new RuntimeException( - "Could not find associations for declaration: " + name ); + if (!tokens.hasMoreTokens()) { + System.err.println("Could not find associations for declaration:"); + System.err.println(content); + throw new RuntimeException("Could not find associations for declaration: " + name); + } + + token = tokens.nextToken(); + if (token.equals("{")) { + if (!tokens.hasMoreTokens()) + throw new RuntimeException("Error parsing declaration: expected { but found: '" + token + "'"); + token = tokens.nextToken(); + } + + NSMutableDictionary associations = new NSMutableDictionary(); + + if (!token.equals("}")) { + String line, key, value; + StringTokenizer lines = new StringTokenizer(token, ";"); + while (lines.hasMoreElements()) { + line = lines.nextToken(); + index = line.indexOf("="); + if (index > -1) { + if (line.length() == index + 1) + line += " "; + key = line.substring(0, index).trim(); + value = line.substring(index + 1).trim(); + } else { + // not a valid key: skip + key = null; + value = null; + } + + if (key != null) { + // if in quotation marks + if ((value.startsWith("\"")) && (value.endsWith("\""))) { + // it's a constant value association + value = value.substring(1, value.length() - 1); + associations.put(key, WOAssociation.associationWithValue(value)); + } else if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) { + // HACK: needed to be compatible with woextensions + // apparently true and false are allowed without quotes + associations.put(key, WOAssociation.associationWithValue(value)); + } else { + // HACK: needed to be compatible with woextensions: + // apparently a standalone integer is allowed without quotes. + try { + Integer.parseInt(value); // does it parse? + associations.put(key, WOAssociation.associationWithValue(value)); + } catch (NumberFormatException nfe) { + // did not parse: + // it's a key path association + associations.put(key, WOAssociation.associationWithKeyPath(value)); + } + } + } + } + if (tokens.hasMoreTokens()) { + token = tokens.nextToken(); + if (!token.equals("}")) + throw new RuntimeException("Error parsing declaration: expected } but found: '" + token + "'"); + } } - - token = tokens.nextToken(); - if ( token.equals( "{" ) ) - { - if ( !tokens.hasMoreTokens() ) throw new RuntimeException( - "Error parsing declaration: expected { but found: '" + token + "'" ); - token = tokens.nextToken(); - } - - NSMutableDictionary associations = new NSMutableDictionary(); - - if ( !token.equals( "}" ) ) - { - String line, key, value; - StringTokenizer lines = - new StringTokenizer( token, ";" ); - while ( lines.hasMoreElements() ) - { - line = lines.nextToken(); - index = line.indexOf( "=" ); - if ( index > -1 ) - { - if ( line.length() == index+ 1 ) line += " "; - key = line.substring( 0, index ).trim(); - value = line.substring( index+1 ).trim(); - } - else - { - // not a valid key: skip - key = null; - value = null; - } - - if ( key != null ) - { - // if in quotation marks - if ( ( value.startsWith( "\"" ) ) && ( value.endsWith( "\"" ) ) ) - { - // it's a constant value association - value = value.substring( 1, value.length()-1 ); - associations.put( key, - WOAssociation.associationWithValue( value ) ); - } - else - if ( value.equalsIgnoreCase( "true" ) || value.equalsIgnoreCase( "false" ) ) - { - //HACK: needed to be compatible with woextensions - // apparently true and false are allowed without quotes - associations.put( key, - WOAssociation.associationWithValue( value ) ); - } - else - { - //HACK: needed to be compatible with woextensions: - // apparently a standalone integer is allowed without quotes. - try - { - Integer.parseInt( value ); // does it parse? - associations.put( key, - WOAssociation.associationWithValue( value ) ); - } - catch ( NumberFormatException nfe ) - { - // did not parse: - // it's a key path association - associations.put( key, - WOAssociation.associationWithKeyPath( value ) ); - } - } - } - } - if ( tokens.hasMoreTokens() ) - { - token = tokens.nextToken(); - if ( !token.equals( "}" ) ) throw new RuntimeException( - "Error parsing declaration: expected } but found: '" + token + "'" ); - } - } - associations.put( WOApplication.ELEMENT_CLASS, cl ); // store classname - result.put( name, associations ); - - } - //System.out.println( "processDeclaration: " + result ); - return result; - } + associations.put(WOApplication.ELEMENT_CLASS, cl); // store classname + result.put(name, associations); + + } + // System.out.println( "processDeclaration: " + result ); + return result; + } } /* - * $Log$ - * Revision 1.2 2006/02/19 01:44:02 cgruber - * Add xmlrpc files - * Remove jclark and replace with dom4j and javax.xml.sax stuff - * Re-work dependencies and imports so it all compiles. + * $Log$ Revision 1.2 2006/02/19 01:44:02 cgruber Add xmlrpc files Remove jclark + * and replace with dom4j and javax.xml.sax stuff Re-work dependencies and + * imports so it all compiles. * - * Revision 1.1 2006/02/16 13:22:22 cgruber - * Check in all sources in eclipse-friendly maven-enabled packages. + * Revision 1.1 2006/02/16 13:22:22 cgruber Check in all sources in + * eclipse-friendly maven-enabled packages. * - * Revision 1.32 2003/08/07 00:15:14 chochos - * general cleanup (mostly removing unused imports) + * Revision 1.32 2003/08/07 00:15:14 chochos general cleanup (mostly removing + * unused imports) * - * Revision 1.31 2003/07/24 00:23:21 chochos - * fixed problem with parsing wod files that have //-type comments. Quotes URL's would be truncated. + * Revision 1.31 2003/07/24 00:23:21 chochos fixed problem with parsing wod + * files that have //-type comments. Quotes URL's would be truncated. * - * Revision 1.30 2003/03/28 15:33:11 mpowers - * Now using a PushBackInputStream for auto detection of content encoding. - * No longer relying on markSupported() since jar input streams don't have it. + * Revision 1.30 2003/03/28 15:33:11 mpowers Now using a PushBackInputStream for + * auto detection of content encoding. No longer relying on markSupported() + * since jar input streams don't have it. * - * Revision 1.29 2003/03/03 16:41:52 mpowers - * Bad characters in cvs log. + * Revision 1.29 2003/03/03 16:41:52 mpowers Bad characters in cvs log. * - * Revision 1.28 2003/03/03 16:37:35 mpowers - * Better handling for string encodings. - * Now trying to autodetect unicode-formatted templates and declarations. - * Now handlings block-style comments in declarations. + * Revision 1.28 2003/03/03 16:37:35 mpowers Better handling for string + * encodings. Now trying to autodetect unicode-formatted templates and + * declarations. Now handlings block-style comments in declarations. * - * Revision 1.27 2003/01/28 19:33:51 mpowers - * Implemented the rest of WOResourceManager. - * Implemented support for java-style i18n. - * Components now use the resource manager to load templates. + * Revision 1.27 2003/01/28 19:33:51 mpowers Implemented the rest of + * WOResourceManager. Implemented support for java-style i18n. Components now + * use the resource manager to load templates. * - * Revision 1.26 2003/01/24 20:13:22 mpowers - * Now accepting immutable NSDictionary in constructor, not Map. + * Revision 1.26 2003/01/24 20:13:22 mpowers Now accepting immutable + * NSDictionary in constructor, not Map. * - * Revision 1.25 2003/01/21 17:53:45 mpowers - * Now correctly reporting error for missing bindings. + * Revision 1.25 2003/01/21 17:53:45 mpowers Now correctly reporting error for + * missing bindings. * - * Revision 1.24 2003/01/20 17:50:11 mpowers - * Caught a loop condition when same declaration was used twice. + * Revision 1.24 2003/01/20 17:50:11 mpowers Caught a loop condition when same + * declaration was used twice. * - * Revision 1.23 2003/01/19 22:33:25 mpowers - * Fixed problems with classpath and dynamic class loading. - * Dynamic elements now pass on ensureAwakeInContext. + * Revision 1.23 2003/01/19 22:33:25 mpowers Fixed problems with classpath and + * dynamic class loading. Dynamic elements now pass on ensureAwakeInContext. * Parser how handles <standalone/> tags. * - * Revision 1.22 2003/01/17 22:55:09 mpowers - * Straighted out the parent binding issue (I think). - * Fixes for woextensions compatibility. + * Revision 1.22 2003/01/17 22:55:09 mpowers Straighted out the parent binding + * issue (I think). Fixes for woextensions compatibility. * - * Revision 1.21 2003/01/17 20:34:57 mpowers - * Better handling for components and parents in the context's element stack. + * Revision 1.21 2003/01/17 20:34:57 mpowers Better handling for components and + * parents in the context's element stack. * - * Revision 1.19 2003/01/17 15:32:22 mpowers - * Changes to better support generic elements and containers. - * Now preserving newlines in templates. + * Revision 1.19 2003/01/17 15:32:22 mpowers Changes to better support generic + * elements and containers. Now preserving newlines in templates. * - * Revision 1.17 2003/01/16 22:47:30 mpowers - * Compatibility changes to support compiling woextensions source. - * (34 out of 56 classes compile!) + * Revision 1.17 2003/01/16 22:47:30 mpowers Compatibility changes to support + * compiling woextensions source. (34 out of 56 classes compile!) * - * Revision 1.15 2003/01/16 15:50:43 mpowers - * More robust declaration parsing. - * Subcomponents are now supported. - * dynamicElementWithName can now return subcomponents. + * Revision 1.15 2003/01/16 15:50:43 mpowers More robust declaration parsing. + * Subcomponents are now supported. dynamicElementWithName can now return + * subcomponents. * - * Revision 1.14 2003/01/15 19:50:49 mpowers - * Fixed issues with WOSession and Serializable. - * Can now persist sessions between classloaders (hot swap of class impls). + * Revision 1.14 2003/01/15 19:50:49 mpowers Fixed issues with WOSession and + * Serializable. Can now persist sessions between classloaders (hot swap of + * class impls). * - * Revision 1.13 2003/01/15 14:33:48 mpowers - * Refactoring: element id handling is now confined to WOParentElement. - * Other elements/components should not have to do element id incrementing. + * Revision 1.13 2003/01/15 14:33:48 mpowers Refactoring: element id handling is + * now confined to WOParentElement. Other elements/components should not have to + * do element id incrementing. * - * Revision 1.12 2003/01/14 16:05:12 mpowers - * Removed extraneous printlns. + * Revision 1.12 2003/01/14 16:05:12 mpowers Removed extraneous printlns. * - * Revision 1.11 2003/01/13 22:24:25 mpowers - * Request-response cycle is working with session and page persistence. + * Revision 1.11 2003/01/13 22:24:25 mpowers Request-response cycle is working + * with session and page persistence. * - * Revision 1.10 2003/01/10 19:33:28 mpowers - * Added contextID for the component url generation. + * Revision 1.10 2003/01/10 19:33:28 mpowers Added contextID for the component + * url generation. * - * Revision 1.9 2003/01/10 19:16:40 mpowers - * Implemented support for page caching. + * Revision 1.9 2003/01/10 19:16:40 mpowers Implemented support for page + * caching. * - * Revision 1.8 2003/01/09 21:16:48 mpowers - * Bringing request-response cycle more into conformance. + * Revision 1.8 2003/01/09 21:16:48 mpowers Bringing request-response cycle more + * into conformance. * - * Revision 1.7 2003/01/09 16:13:55 mpowers - * Implemented WOComponentRequestHandler: - * Bringing the request-response cycle more into conformance. + * Revision 1.7 2003/01/09 16:13:55 mpowers Implemented + * WOComponentRequestHandler: Bringing the request-response cycle more into + * conformance. * - * Revision 1.6 2002/12/20 22:56:33 mpowers - * Reimplemented the template parsing again. - * Nested components are now correctly parsed. - * ElementID numbering is now working. + * Revision 1.6 2002/12/20 22:56:33 mpowers Reimplemented the template parsing + * again. Nested components are now correctly parsed. ElementID numbering is now + * working. * - * Revision 1.3 2002/12/18 14:12:38 mpowers - * Support for differentiated request handlers. - * Support url generation for WOContext and WORequest. + * Revision 1.3 2002/12/18 14:12:38 mpowers Support for differentiated request + * handlers. Support url generation for WOContext and WORequest. * - * Revision 1.2 2002/11/07 18:52:33 mpowers - * New components courtesy of ezamudio@nasoft.com. Many thanks! + * Revision 1.2 2002/11/07 18:52:33 mpowers New components courtesy of + * ezamudio@nasoft.com. Many thanks! * - * Revision 1.1.1.1 2000/12/21 15:53:01 mpowers - * Contributing wotonomy. + * Revision 1.1.1.1 2000/12/21 15:53:01 mpowers Contributing wotonomy. * - * Revision 1.2 2000/12/20 16:25:49 michael - * Added log to all files. + * Revision 1.2 2000/12/20 16:25:49 michael Added log to all files. * * */ - |
