WebObjects 5.4.2

Package com.webobjects.appserver.parser

Provides a set of parser classes to handle the parsing of WOComponent HTML single files or WOComponent Bundles.

See:
          Description

Interface Summary
WOComponentTemplateParser.Factory.ClassDelegate This interface defines a delegate to enable subclassing.
WOHTMLParserDelegate  
 

Class Summary
WOBundleComponentTemplateParser  
WOComponentTemplateParser Used for parsing traditional .wo components.
WOComponentTemplateParser.Factory Factory method for new parser.
WOHTMLParser  
WOHTMLTemplateParser  
WOHTMLWebObjectTag  
 

Exception Summary
WOHTMLFormatException  
WOParserException  
 

Package com.webobjects.appserver.parser Description

Provides a set of parser classes to handle the parsing of WOComponent HTML single files or WOComponent Bundles. See also the "WebObjects File Format Reference" guide in the WebObjects 5.4 Documentation for an explanation of these file formats.

Enables developers to customize their parsers. If you do not need to modify the parsing behavior, it is not necessary to modify these classes.

Introduction

The Parser package contains the following classes:

Usage Notes

Examples of traditional vs. single file bindings

Traditional bindings in a .wod file:

MyLink: WOHyperlink { string = "Link to Home Page"; action = backToHomePage; }

HTML file with bindings:

<wo:WOHyperlink name="MyLink" string="Link to Home Page" action="[backToHomePage]" >

How to override the method valueForKeyPath: in .wod declarations

The new declaration parser will handle the .wod declarations in a strict manner either as:

  • A string value enclosed in quotes (")

  • Dynamic bindings are surrounded by bracket characters, [ and ].

  • A Key Value Coding expression, strictly defined (i.e. foo.bar.baz or foo.items.@sum)

  • A Key Value Coding expression evaluated from the parent (i.e. ^ prefix to Key Value Coding)

  • A scheme-based custom association (i.e. prefixed by scheme name and separated by colon, such as localization: <any expression>)


    Overriding the method valueForKeyPath: means that you are essentially redefining how Key Value Coding works for that object.The new mechanism will create custom WOAssociation subclasses when the scheme is encountered. You are free to interpret the expression <any expression> above in any way you see fit.

    The WOAssociationFactory lives in the Application subclass and can be replaced with a custom factory. A proper override would be that in your application subclass you create a custom association factory, register the custom associations with your association factory and delegate the custom association schemes.

    Example of a custom WOAssociation WOOGNLAssociation

    // Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. ("Apple") // in consideration of your agreement to the following terms, and your use, // installation, modification or redistribution of this Apple software // constitutes acceptance of these terms. If you do not agree with these // terms, please do not use, install, modify or redistribute this Apple // software. // // In consideration of your agreement to abide by the following terms, and // subject to these terms, Apple grants you a personal, non - exclusive // license, under Apple's copyrights in this original Apple software ( the // "Apple Software" ), to use, reproduce, modify and redistribute the Apple // Software, with or without modifications, in source and / or binary forms; // provided that if you redistribute the Apple Software in its entirety and // without modifications, you must retain this notice and the following text // and disclaimers in all such redistributions of the Apple Software. Neither // the name, trademarks, service marks or logos of Apple Inc. may be used to // endorse or promote products derived from the Apple Software without specific // prior written permission from Apple. Except as expressly stated in this // notice, no other rights or licenses, express or implied, are granted by // Apple herein, including but not limited to any patent rights that may be // infringed by your derivative works or by other works in which the Apple // Software may be incorporated. // // The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO // WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED // WARRANTIES OF NON - INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION // ALONE OR IN COMBINATION WITH YOUR PRODUCTS. // // IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR // CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION ) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION // AND / OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER // UNDER THEORY OF CONTRACT, TORT ( INCLUDING NEGLIGENCE ), STRICT LIABILITY OR // OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Copyright ( C ) 2007 Apple Inc. All Rights Reserved. //
    MyString: WOString { value = ognl: doSomething(); }

    The wod parser will delegate to the WOAssociationFactory registered with the application to create the association:

    import ognl.Expression; import ognl.ExpressionSyntaxException; import ognl.OgnlContext; import ognl.OgnlException; import com.webobjects.appserver.WOAssociation; import com.webobjects.appserver.WOComponent;
    public class WOOGNLAssociation extends WOAssociation { private Expression expression; /*=================================================================== * Constructors *===================================================================*/ public WOOGNLAssociation(String ognlExpressionString) throws ExpressionSyntaxException { super(); expression = parseOGNLExpression(ognlExpressionString); } /*=================================================================== * Protected methods *===================================================================*/ protected Expression parseOGNLExpression(String expressionString) throws ExpressionSyntaxException { Expression result; result = getContextForComponent(null).parseExpression(expressionString); return result; } protected Object valueInComponent(WOComponent aComponent, Expression expression) { try { Object result; result = expression.getValue(getContextForComponent(aComponent), aComponent); return result; } catch (OgnlException ex) { throw new RuntimeException(ex); } } protected void setValue(Object aValue, WOComponent aComponent, Expression expression) { try { expression.setValue(new OgnlContext(((Application)Application.application()).getRootContext()), aComponent, aValue); } catch (OgnlException ex) { throw new RuntimeException(ex); } } protected boolean isValueSettable(Expression expression) { return true; } protected boolean isValueConstant(Expression expression) { try { return expression.isConstant(getContextForComponent(null)); } catch (OgnlException ex) { throw new RuntimeException(ex); } } public String bindingInComponent(WOComponent aComponent, Expression expression) { return expression.toString(); } /*=================================================================== * Public methods *===================================================================*/ public OgnlContext getContextForComponent(WOComponent aComponent) { return new OgnlContext(((Application)Application.application()).getRootContext()); } /*=================================================================== * Overridden methods *===================================================================*/ public Object valueInComponent(WOComponent aComponent) { return valueInComponent(aComponent, expression); } public void setValue(Object aValue, WOComponent aComponent) { setValue(aValue, aComponent, expression); } public boolean isValueSettable() { return isValueSettable(expression); } public boolean isValueConstant() { return isValueConstant(expression); } /** * @see com.webobjects.appserver.WOAssociation#bindingInComponent(com.webobjects.appserver.WOComponent) * * @param aComponent * @return */ public String bindingInComponent(WOComponent aComponent) { return bindingInComponent(aComponent, expression); } /** * Overridden to return "\". * * @see com.webobjects.appserver.WOAssociation#keyPath() * * @return */ public String keyPath() { return ""; } }


    Sample code to change the default association factory so that you can register your own associations

    /*=================================================================== * Set WOApplication to use own association factory in the constructor of your Application subclass * and register the new association(s) in the association factory *=================================================================== */ setAssociationFactory(new OGNLWOAssociationFactory());

    registerAssociations((OGNLWOAssociationFactory)associationFactory());

    Sample implementation of the registerAssociations() method

    public static void registerAssociations(OGNLWOAssociationFactory iFactory) { iFactory.registerSchemeAssociation(OGNLLocalizeAssociation.SCHEME, OGNLLocalizeAssociation.class); ... }

    Sample code for a custom WOAssociationFactory

    import com.webobjects.appserver.WOAssociation; import com.webobjects.appserver.WOAssociationFactory; import com.webobjects.appserver.WOSchemeNotSupportedException; import com.webobjects.foundation.NSMutableDictionary; public class OGNLWOAssociationFactory implements WOAssociationFactory { //================================================= // Class Variables //================================================= private NSMutableDictionary _schemeAssociations; private static Class[] _parameterTypes; //================================================= // Instance Variables //================================================= //================================================= // Constructors //================================================= public OGNLWOAssociationFactory() { _schemeAssociations = new NSMutableDictionary(); _parameterTypes = new Class[] { String.class }; } //================================================= // Instance Methods //================================================= /** * @see com.webobjects.appserver.WOAssociationFactory#createConstantAssociation(java.lang.Object) * * @param iValue * @return WOAssociation */ public WOAssociation createConstantAssociation(Object iValue) { WOAssociation aResult; aResult = WOAssociation.associationWithValue(iValue); return aResult; } /** * Default implementation calls WOAssociation.associationWithKeyPath(). * * @see com.webobjects.appserver.WOAssociationFactory#createKeyValueAssociation(java.lang.String) * * @param iKeyPath * @return WOAssociation */ public WOAssociation createKeyValueAssociation(String iKeyPath) { return WOAssociation.associationWithKeyPath(iKeyPath); } /** * Instantiate class via reflection * */ public static Object instantiateObject(Class objectClass, Class[] parameterTypes, Object[] parameters, boolean shouldThrow, boolean shouldLog) { try { if ((parameterTypes != null) && (parameters != null)) { Constructor constructor = objectClass.getDeclaredConstructor(parameterTypes); return constructor.newInstance(parameters); } return objectClass.newInstance(); } catch (Throwable throwable) { throwable.toString(); if (shouldThrow) { throw throwable; } else if (shouldLog) { throwable.getMessage(); } } return null; }
    /** * Default implementation throws WOSchemeNotSupportedException. * @see com.webobjects.appserver.WOAssociationFactory#createSchemedAssociation(java.lang.String, java.lang.String) * * @param iScheme * @param iContent * @return WOAssociation * @throws WOSchemeNotSupportedException */ public WOAssociation createSchemedAssociation(String iScheme, String iContent) throws WOSchemeNotSupportedException { Class anAssociationClass = _associationClassForKeyPath(iScheme); Object aParamList[] = new Object[] { iContent }; WOAssociation aNewAssociation = (WOAssociation) instantiateObject(anAssociationClass, _parameterTypes, aParamList, true, true); return aNewAssociation; } /** * Adds the passed in scheme to the scheme associations dictionary. If the scheme is already registered, * it is removed and re-added. * When that scheme is encountered in a component, its class will be called to get its value * for use in the component. * @param iScheme * @param iSchemeClass */ public void registerSchemeAssociation(String iScheme, Class iSchemeClass) { if (iScheme != null && iSchemeClass != null) { unRegisterSchemeAssociation(iScheme); _schemeAssociations.setObjectForKey(iSchemeClass, iScheme); } } /** * Removes the passed in scheme from our scheme associations dictionary. * @param iScheme */ public void unRegisterSchemeAssociation(String iScheme) { if (iScheme != null) { if (_schemeAssociations.containsKey(iScheme)) { _schemeAssociations.removeObjectForKey(iScheme); } } } /* * Returns the class for the passed in scheme */ private Class _associationClassForKeyPath(String iScheme) { Class aReturnVal = null; if (iScheme != null) { aReturnVal = (Class)_schemeAssociations.objectForKey(iScheme); } return aReturnVal; } }

    Since:
    5.4
    See Also:
    WOAssociationFactory, WOAssociation

    Last updated June 2008

    Copyright © 2000-2008 Apple Inc.