SlideShare une entreprise Scribd logo
1  sur  57
Télécharger pour lire hors ligne
Hidden Treasures in
Project Wonder
Spirit of Mike Schrag
Whereabouts Unknown

Channeled By Chuck Hill
Global Village Consulting
What You See

•   Mike’s Step 1: Look at every damn method in
    Wonder.
•   Mike’s Step 1a: Seriously. Every one.
•   Mike’s Step 2: “Cool” = Chosen
What You Get


•   Notification of existence
•   Nothing in-depth
Type-safe pageWithName
•   <T extends WOComponent> T
    pageWithName(Class<T> componentClass)
•   ERXApplication, ERXDirectAction,
    ERXComponent
•   less typing
•   refactoring updates them
•   compiler errors for speeling errors
Type-safe pageWithName
old way
MyPage page = (MyPage)pageWithName(“MyPage”);

new way
MyPage page = (MyPage)pageWithName(MyPage.class.getName());

cool way
MyPage page = pageWithName(MyPage.class);
IVersionManager
•   better control of static resource caching
    •   infinite expiration in Apache
    •   change resource url when resource
        changes
•   pluggable versioning schemes
    •   “default” = WebObjects default
    •   “properties” = specify version numbers in
        properties
    •   your own
PropertiesVersionManager
properties
er.extensions.ERXResourceManager.versionManager=properties
er.extensions.ERXResourceManager.versionManager.default=10
er.extensions.ERXResourceManager.versionManager.bundleName.resourceName=20

produces
/WebObjects/YourApp.woa/WebServerResources/awesomeImage.png?10
/WebObjects/bundleName/WebServerResources/resourceName?20
ERXDirectAction / log4j
url
/wa/ERXDirectAction/log4j?pw=somepw


properties
er.extensions.ERXLog4JPassword=somepw
ERXDirectAction / log4j
ERXDirectAction /
        eoAdaptorDebugging
url
/wa/ERXDirectAction/eoAdaptorDebugging?debug=on&pw=somepw
/wa/ERXDirectAction/eoAdaptorDebugging?debug=off&pw=somepw


properties
er.extensions.ERXEOAdaptorDebuggingPassword=somepw
ERXMainRunner

•   initializes all of Wonder
•   runs “main” method inside of an Application
    context
•   java
       -classpath ...
       er.extensions.appserver.ERXMainRunner
       -mainClass YourClass
ERXApplication._rewriteURL



•   Pretty URLs
•   One generator method to rule them all
ERXApplication._rewriteURL
           (simple method)
properties
er.extensions.ERXApplication.replaceApplicationPath.pattern= ↵
/cgi-bin/WebObjects/YourApp.woa

er.extensions.ERXApplication.replaceApplicationPath.replace= ↵
/yourapp

produces
http://server.com/yourapp/wa/default

apache rewrite rule
RewriteRule ^/yourapp(.*)$ /cgi-bin/WebObjects/YourApp.woa$1 [PT,L]
ERXApplication._rewriteURL
               (complex method)
Application subclass
@Override
public String _rewriteURL(String url) {
    return convertURLWithFancyRegexOrSomething(url);
}

apache rewrite rule
rewrite rule has to be an inverse of your _rewriteURL implementation
ERXRedirect
•   drop-in replacement for WORedirect
•   can redirect to a component instance rather
    than a direct action
•   generates document.location.href=... in Ajax
    request
•   https support
•   api for setting query parameters
ERXRedirect
public WOActionResults doSomething() {
    ERXRedirect redirect = pageWithName(ERXRedirect.class);
    NextPage nextPage = pageWithName(NextPage.class);
    nextPage.setState(someStateFromThisPage);
    redirect.setComponent(nextPage);
    return redirect;
}
ERXSession.useSecureSessionCookies



•   secure cookies are only sent across https
    requests
•   wosid and woinst are not secure cookies by
    default (and thus vulnerable to sniffing off a
    non-https url)
ERXSession.useSecureSessionCookies

@Override
public boolean useSecureSessionCookies() {
    return true;
}

or

er.extensions.ERXSession.useSecureSessionCookies=true
ERXFlickrBatchNavigation
• WOBatchNavigationBar looks like ass
• ERXFlickrBatchNavigation does not
• Drop-in replacement of
  WOBatchNavigationBar
ERXDataHyperlink

•   Like WOHyperlink but with object-based
    attribute passing
•   Automagically calls accessor methods on
    pageName component
•   Safe ... doesn’t leak data to user
•   An example will make more sense
ERXDataHyperlink
PersonList page
<wo:ERXDataHyperlink pageName=”PersonEdit” ↵
                     person=”$currentPerson”>
    edit person
</wo:ERXDataHyperlink>


PersonEdit page
public class PersonEdit extends WOComponent {
    ...
    public void setPerson(Person person) {
        _person = person;
    }
}
ERXInlineTemplate

•   Generate a WOComponent on-the-fly
•   Generate a WOComponent from a database
    (i.e. a CMS)
•   Take over the world?
ERXInlineTemplate
basic
<wo:ERXInlineTemplate html=”$someHtmlString” wod=”$someWodString”/>
(using woognl doesn’t require a wod)

cache generated component
<wo:ERXInlineTemplate html=”$someHtmlString” wod=”$someWodString”
    cacheKey=”MyCacheKey” cacheVersion=”$computedVersionObject”/>
(when cacheVersion changes, regenerate)
ERXWOComponentContent /
          ERXWOTemplate



•   WOComponentContent but with multiple
    content areas
•   example: a DialogComponent has a “title”
    area and a “content” area
ERXWOComponentContent /
                 ERXWOTemplate
DialogComponent
<div>
    <div><wo:ERXWOComponentContent templateName=”title”/></div>
    <div><wo:ERXWOComponentContent templateName=”content”/></div>
</div>

CallingComponent
<wo:DialogComponent>
    <wo:ERXWOTemplate templateName=”title”>
        this is the title and you can put real components in here
    </wo:ERXWOTemplate>
    <wo:ERXWOTemplate templateName=”content”>
        this is the content of the dialog
    </wo:ERXWOTemplate>
</wo:DialogComponent>
ERXLoremIpsumGenerator
•   sometimes you just need fake content (test
    cases, load tests, mockups)
•   “Lorem ipsum dolor sit amet, ...”
•   ERXLoremIpsumGenerator.paragraph(3) = 3
    paragraphs
•   ERXLoremIpsumGenerator.sentence(1) = 1
    sentence
•   ERXLoremIpsumGenerator.words(10) = 10
    words
Captchas and Spam Checks

•   ERXSimpleSpamCheck
    (ERExtensions.framework)
    sets a hidden field with javascript
•   ERReCaptcha (ERCaptcha.framework)
    reCAPTCHA wrapper (http://
    www.google.com/recaptcha)
•   ERAkismet (ERCaptcha.framework)
    Akismet wrapper (http://akismet.com); spam
    checks blog comments
Captchas and Spam Checks



•   calls validationFailedWithException on failure
•   sets “valid” binding accordingly
Captchas and Spam Checks
<wo:form>
    <wo:ERXSimpleSpamCheck />

    <wo:WOTextField value=”$firstName” />
    <wo:WOSubmitButton action=”$doSomething” />
</wo:form>
ERXRssPage
•   quickly produce RSS feeds
•   feedTitle, feedUrl, feedDescription
•   list : list of items to show in the feed
•   item : repetition item
•   itemGuid, itemTitle, itemLink, itemPubDate,
    itemAuthor
•   description from WOComponentContent
ERXRssPage
<wo:ERXRssPage
        feedTitle=”RSS of People”
        feedUrl=”http://yourhost.com”
        feedDescription=”This is my list of people!”
        list=”$people”
        item=”$person”
        itemGuid=”$person.primaryKey”
        itemTitle=”$person.fullName”
        itemLink=”$someURLToThePerson”
        itemPubDate=”$person.creationDate” />
ERXWORepetition
•   WORepetition relies on repetition item
    indexes
•   changing item order = you just clicked
    “delete” on the wrong row ... whoops
•   uses key instead of index
•   small risk of collision, but unlikely in tests (use
    uniqueKey binding to prevent)
ERXWORepetition
properties
# use hash codes of objects instead of index
er.extensions.ERXWORepetition.checkHashCodes=true

# throw an exception if a match isn’t found
er.extensions.ERXWORepetition.raiseOnUnmatchedObject=true



unique keys
# use item PKs instead of hash codes
<wo:ERXWORepetition uniqueKey=”$person.primaryKey”> ...
External Services
•   ERXGoogleSpell.correct(String)
    •   spelling correction like Google’s “did you
        mean”
•   ERXYahooContentAnalysisService.termExtra
    ction(..)
    •   extracts important terms from text
    •   useful for guessing ERTaggable tags
•   Access keys required, read Javadoc for details
ERXEnterpriseObjectCache

•   caches EO’s based on a keypath
•   optionally filter with qualifier (dynamically
    updates!)
    example: two caches -- published=true,
    published=false
•   optional timed expiration
ERXEnterpriseObjectCache
•    use this constructor and
     shouldRetainObjects=true!
    public ERXEnterpriseObjectCache(
         String entityName,
         String keyPath,
         EOQualifier qualifier,
         long timeout,
         boolean shouldRetainObjects,
         boolean shouldFetchInitialValues)
ERXEnterpriseObjectCache
# cache any CMSPage objects by their “name” key
# that are published=true
# expire them after 60 seconds
ERXEnterpriseObjectCache cache = new ERXEnterpriseObjectCache(
        CMSPage.ENTITY_NAME,
        CMSPage.NAME_KEY,
        CMSPage.PUBLISHED.isTrue(),
        60 * 1000);

EOEditingContext editingContext = ERXEC.newEditingContext();
CMSPage homePage = cache.objectForKey(editingContext, “HomePage”);
homePage.setPublished(false);
editingContext.saveChanges();
# published = false, so it is dynamically removed from the cache
ERXEOControlUtilities

•   ERXEOControlUtilities.convertEOtoGID /
    convertGIDtoEO
    recursively convert data structures from EO’s
    to GID’s (NSDictionary of String to NSArray
    of EO’s becomes NSDictionary of String to
    NSArray of GID’s, etc) and the corresponding
    inverse method
ERXEOControlUtilities
•   ERXEOControlUtilities.eoEquals
    compare two EO’s, returning true if their
    GID’s match, regardless of the
    EOEditingContext that contains both of them
•   ERXEOControlUtilities.aggregateFunctionWith
    Qualifier
    perform MIN/MAX/AVG/etc database
    functions on attributes of an entity without
    writing custom SQL
Automatic Batch Faulting
•   Common problem: Fetch array of Person
    objects, show them in a table, for each row,
    show the person.company().name()
•   Common solution: Manually batch fetch
    “company.name” on the Person objects.
•   Bad-ass solution:
    er.extensions.ERXDatabaseContextDelegate.
    autoBatchFetchSize=50
•   Automatically batch fetches faulted
    relationships on all EO’s that were fetched
    from the same query
Automatic Batch Faulting
NSArray<Person> people = ec.objectsWithFetchSpecification(fspec);

# this automatically faults all the companies for
# the person objects in the “people” array (up to
# your 50 max specified in the property)
Company comp = people.objectAtIndex(0).company();
String name = comp.name();

# this automatically faults all the employees for
# all the companies that were just batch fetched
# above -- it’s magic and recursive
NSArray<Person> employees = comp.employees();

# restricts to only the visible objects if attached
# to a display group
ERXUnitAwareDecimalFormat

•   automatically format bytes/meters/grams/
    seconds in metric decimal form
•   scales to appropriate unit based on size
•   1234567890 bytes becomes “1.15GB”
NumberFormat formatter =
     new ERXUnitAwareDecimalFormat
(ERXUnitAwareDecimalFormat.BYTE);
formatter.setMaximumFractionDigits(2);
formatter.format(1234567890.0);
ERXJDBCAdaptor

•   fixes double connection bug from jdbcInfo
•   should just be the default
•   er.extensions.ERXJDBCAdaptor.className =
    er.extensions.jdbc.ERXJDBCAdaptor
ERXMutableURL

•   java.net.URL is garbage. ERXMutableURL is
    not.
•   mutable interface to a URL object
•   add query parameters one-by-one
•   supports weird “urls” like “javascript:” and
    incomplete “/wa/something”
ERXMutableURL
ERXMutableURL url = new ERXMutableURL(
    "http://yourhost.com:80/tutorial/index.html?key1=value1#someref");
url.setRef(null);
url.removeQueryParameter("key1");
url.addQueryParameter("key2", “value2”);
url.addQueryParameters(“key3=value3&key4=value4”);

java.net.URL javaneturl = url.toURL();
String urlString = url.toExternalForm();
ERXThreadStorage
•   a ThreadLocal dictionary that resets for each
    request
•   Object obj = ERXThreadStorage.valueForKey
    (String)
•   ERXThreadStorage.takeValueForKey(Object,
    String)
•   common uses: current user, current session,
    current context
ERXValueUtilities
•    convert objects to various common types
    including “default” form
•   example:
    booleanValue(Object) /
    booleanValueWithDefault(Object, boolean
    def)
•   supports boolean, Boolean, int, Integer, float,
    Float, double, Double, long, Long, array, set,
    dictionary, data, bigDecimal, enum
•   converts from every possible form for you --
    handy for bindings
ERMemoryAdaptor
•   acts like a database, but just talking to
    dictionaries
•   great for test cases
•   no SQL support -- don’t try to get tricky
•   Include JavaMemoryAdaptor.framework
•   dbConnectAdaptorGLOBAL=Memory
    or
    [ModelName].adaptor=Memory
ERPDFWrapper

•   Turn any HTML+CSS page into a PDF
•   Include ERPDFGeneration.framework
•   <wo:ERPDFWrapper>
    <html> ...
    </wo:ERPDFWrapper>
•   Done. That’s just cool.
PFProfiler /
    SESnapshotExplorer

•   These are in another talk.
•   They’re cool, though.
•   Pay attention during that talk.
ERXResponseRewriter.Delegate

•   intercept all resource insertions, optionally
    replacing (or denying) them
•   example:
    you have your own prototype.js and you want
    to replace Ajax.framework’s version with
    yours
•   via properties (for simple cases) or via
    custom delegate
•   responseRewriterWillAddResource
ERXResponseRewriter.Delegate
properties
er.extensions.ERXResponseRewriter.resource.[framework].[filename]=
[newFramework].[newFileName]
er.extensions.ERXResponseRewriter.resource.Ajax.prototype.js=
app.myprototype.js

delegate (example replaces EVERY file with myfile.png -- be smarter)
ERXResponseRewriter.setDelegate(new ERXResponseRewriter.Delegate() {
  public boolean responseRewriterShouldAddResource(
      String framework, String fileName) { return true; }

  public ERXResponseRewriter.Resource responseRewriterWillAddResource(
    String framework, String fileName) {
        return new ERXResponseRewriter.Resource(“app”, “myfile.png”);
});
applyRestrictingQualifierOnInsert

•   er.extensions.ERXEnterpriseObject.applyRest
    rictingQualifierOnInsert=true
•   makes new objects automatically match their
    entity’s restricting qualifier
•   i.e. if Employee is “personType = 5”, a new
    Employee will automatically have personType
    = 5 set on it
•   no more awakeFromInsertion junk
secureDisabled
•   You use DirectConnect
•   You don’t have SSL in dev
•   You want to run your app
•   er.extensions.ERXRequest.secureDisabled=tr
    ue
•   Turns off all https URL generation -- only
    works in dev
ERXAdaptorChannelDelegate


•   conditionally log slow SQL execution (and
    some other cool debugging stuff)
•   took 100ms, log.info the expression
•   took 1000ms, log.warn the expression
•   etc ...
ERXAdaptorChannelDelegate
properties
er.extensions.ERXAdaptorChannelDelegate.enabled=true
er.extensions.ERXAdaptorChannelDelegate.trace.milliSeconds.debug=0
er.extensions.ERXAdaptorChannelDelegate.trace.milliSeconds.info=100
er.extensions.ERXAdaptorChannelDelegate.trace.milliSeconds.warn=1000
er.extensions.ERXAdaptorChannelDelegate.trace.milliSeconds.error=5000
Q&A
Spirit of Mike Schrag
Whereabouts Unknown

Channeled By Chuck Hill
Global Village Consulting

Contenu connexe

Tendances

async/await in Swift
async/await in Swiftasync/await in Swift
async/await in SwiftPeter Friese
 
How to write easy-to-test JavaScript
How to write easy-to-test JavaScriptHow to write easy-to-test JavaScript
How to write easy-to-test JavaScriptYnon Perek
 
Sprout core and performance
Sprout core and performanceSprout core and performance
Sprout core and performanceYehuda Katz
 
Contagion的Ruby/Rails投影片
Contagion的Ruby/Rails投影片Contagion的Ruby/Rails投影片
Contagion的Ruby/Rails投影片cfc
 
HTML5 JavaScript APIs
HTML5 JavaScript APIsHTML5 JavaScript APIs
HTML5 JavaScript APIsRemy Sharp
 
Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Matthew Groves
 
Alloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLonAlloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLonFokke Zandbergen
 
Angular.js Fundamentals
Angular.js FundamentalsAngular.js Fundamentals
Angular.js FundamentalsMark
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the FinishYehuda Katz
 
Simplify AJAX using jQuery
Simplify AJAX using jQuerySimplify AJAX using jQuery
Simplify AJAX using jQuerySiva Arunachalam
 
Remote code-with-expression-language-injection
Remote code-with-expression-language-injectionRemote code-with-expression-language-injection
Remote code-with-expression-language-injectionMickey Jack
 
Better Selenium Tests with Geb - Selenium Conf 2014
Better Selenium Tests with Geb - Selenium Conf 2014Better Selenium Tests with Geb - Selenium Conf 2014
Better Selenium Tests with Geb - Selenium Conf 2014Naresha K
 
Elasticsearch for SQL Users
Elasticsearch for SQL UsersElasticsearch for SQL Users
Elasticsearch for SQL UsersAll Things Open
 
Akka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignLightbend
 
Mastering Oracle ADF Bindings
Mastering Oracle ADF BindingsMastering Oracle ADF Bindings
Mastering Oracle ADF BindingsEuegene Fedorenko
 

Tendances (20)

jQuery in 15 minutes
jQuery in 15 minutesjQuery in 15 minutes
jQuery in 15 minutes
 
async/await in Swift
async/await in Swiftasync/await in Swift
async/await in Swift
 
How to write easy-to-test JavaScript
How to write easy-to-test JavaScriptHow to write easy-to-test JavaScript
How to write easy-to-test JavaScript
 
Sprout core and performance
Sprout core and performanceSprout core and performance
Sprout core and performance
 
Contagion的Ruby/Rails投影片
Contagion的Ruby/Rails投影片Contagion的Ruby/Rails投影片
Contagion的Ruby/Rails投影片
 
HTML5 JavaScript APIs
HTML5 JavaScript APIsHTML5 JavaScript APIs
HTML5 JavaScript APIs
 
Jsp
JspJsp
Jsp
 
Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017
 
Alloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLonAlloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLon
 
Angular.js Fundamentals
Angular.js FundamentalsAngular.js Fundamentals
Angular.js Fundamentals
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
 
Simplify AJAX using jQuery
Simplify AJAX using jQuerySimplify AJAX using jQuery
Simplify AJAX using jQuery
 
Remote code-with-expression-language-injection
Remote code-with-expression-language-injectionRemote code-with-expression-language-injection
Remote code-with-expression-language-injection
 
Better Selenium Tests with Geb - Selenium Conf 2014
Better Selenium Tests with Geb - Selenium Conf 2014Better Selenium Tests with Geb - Selenium Conf 2014
Better Selenium Tests with Geb - Selenium Conf 2014
 
Elasticsearch for SQL Users
Elasticsearch for SQL UsersElasticsearch for SQL Users
Elasticsearch for SQL Users
 
Akka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System Design
 
ERGroupware
ERGroupwareERGroupware
ERGroupware
 
Mastering Oracle ADF Bindings
Mastering Oracle ADF BindingsMastering Oracle ADF Bindings
Mastering Oracle ADF Bindings
 
jQuery PPT
jQuery PPTjQuery PPT
jQuery PPT
 
Schemadoc
SchemadocSchemadoc
Schemadoc
 

Similaire à Hidden Treasures in Project Wonder

Plone Interactivity
Plone InteractivityPlone Interactivity
Plone InteractivityEric Steele
 
Hyperproductive JSF 2.0 @ JavaOne Brazil 2010
Hyperproductive JSF 2.0 @ JavaOne Brazil 2010Hyperproductive JSF 2.0 @ JavaOne Brazil 2010
Hyperproductive JSF 2.0 @ JavaOne Brazil 2010Arun Gupta
 
Learning to run
Learning to runLearning to run
Learning to rundominion
 
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0Arun Gupta
 
Ajax Under The Hood
Ajax Under The HoodAjax Under The Hood
Ajax Under The HoodWO Community
 
Model-Driven Software Development - Strategies for Design & Implementation of...
Model-Driven Software Development - Strategies for Design & Implementation of...Model-Driven Software Development - Strategies for Design & Implementation of...
Model-Driven Software Development - Strategies for Design & Implementation of...Eelco Visser
 
Strategies for Design & Implementation of Domain-Specific Languages
Strategies for Design & Implementation of Domain-Specific LanguagesStrategies for Design & Implementation of Domain-Specific Languages
Strategies for Design & Implementation of Domain-Specific LanguagesEelco Visser
 
How to make Ajax work for you
How to make Ajax work for youHow to make Ajax work for you
How to make Ajax work for youSimon Willison
 
Top Ten Web Defenses - DefCamp 2012
Top Ten Web Defenses  - DefCamp 2012Top Ten Web Defenses  - DefCamp 2012
Top Ten Web Defenses - DefCamp 2012DefCamp
 
BITM3730 10-4.pptx
BITM3730 10-4.pptxBITM3730 10-4.pptx
BITM3730 10-4.pptxMattMarino13
 
BITM3730 10-3.pptx
BITM3730 10-3.pptxBITM3730 10-3.pptx
BITM3730 10-3.pptxMattMarino13
 
Propel sfugmd
Propel sfugmdPropel sfugmd
Propel sfugmdiKlaus
 
PHP security audits
PHP security auditsPHP security audits
PHP security auditsDamien Seguy
 
Week 4 - jQuery + Ajax
Week 4 - jQuery + AjaxWeek 4 - jQuery + Ajax
Week 4 - jQuery + Ajaxbaygross
 

Similaire à Hidden Treasures in Project Wonder (20)

ERRest in Depth
ERRest in DepthERRest in Depth
ERRest in Depth
 
ERRest and Dojo
ERRest and DojoERRest and Dojo
ERRest and Dojo
 
Plone Interactivity
Plone InteractivityPlone Interactivity
Plone Interactivity
 
Hyperproductive JSF 2.0 @ JavaOne Brazil 2010
Hyperproductive JSF 2.0 @ JavaOne Brazil 2010Hyperproductive JSF 2.0 @ JavaOne Brazil 2010
Hyperproductive JSF 2.0 @ JavaOne Brazil 2010
 
Learning to run
Learning to runLearning to run
Learning to run
 
Os Pruett
Os PruettOs Pruett
Os Pruett
 
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
Spark IT 2011 - Simplified Web Development using Java Server Faces 2.0
 
Ajax Under The Hood
Ajax Under The HoodAjax Under The Hood
Ajax Under The Hood
 
Model-Driven Software Development - Strategies for Design & Implementation of...
Model-Driven Software Development - Strategies for Design & Implementation of...Model-Driven Software Development - Strategies for Design & Implementation of...
Model-Driven Software Development - Strategies for Design & Implementation of...
 
Strategies for Design & Implementation of Domain-Specific Languages
Strategies for Design & Implementation of Domain-Specific LanguagesStrategies for Design & Implementation of Domain-Specific Languages
Strategies for Design & Implementation of Domain-Specific Languages
 
How to make Ajax work for you
How to make Ajax work for youHow to make Ajax work for you
How to make Ajax work for you
 
Jquery News Packages
Jquery News PackagesJquery News Packages
Jquery News Packages
 
Top Ten Web Defenses - DefCamp 2012
Top Ten Web Defenses  - DefCamp 2012Top Ten Web Defenses  - DefCamp 2012
Top Ten Web Defenses - DefCamp 2012
 
Real World MVC
Real World MVCReal World MVC
Real World MVC
 
BITM3730 10-4.pptx
BITM3730 10-4.pptxBITM3730 10-4.pptx
BITM3730 10-4.pptx
 
BITM3730 10-3.pptx
BITM3730 10-3.pptxBITM3730 10-3.pptx
BITM3730 10-3.pptx
 
Propel sfugmd
Propel sfugmdPropel sfugmd
Propel sfugmd
 
PHP security audits
PHP security auditsPHP security audits
PHP security audits
 
Week 4 - jQuery + Ajax
Week 4 - jQuery + AjaxWeek 4 - jQuery + Ajax
Week 4 - jQuery + Ajax
 
Introduction to java_script
Introduction to java_scriptIntroduction to java_script
Introduction to java_script
 

Plus de WO Community

In memory OLAP engine
In memory OLAP engineIn memory OLAP engine
In memory OLAP engineWO Community
 
Using Nagios to monitor your WO systems
Using Nagios to monitor your WO systemsUsing Nagios to monitor your WO systems
Using Nagios to monitor your WO systemsWO Community
 
Build and deployment
Build and deploymentBuild and deployment
Build and deploymentWO Community
 
Reenabling SOAP using ERJaxWS
Reenabling SOAP using ERJaxWSReenabling SOAP using ERJaxWS
Reenabling SOAP using ERJaxWSWO Community
 
Chaining the Beast - Testing Wonder Applications in the Real World
Chaining the Beast - Testing Wonder Applications in the Real WorldChaining the Beast - Testing Wonder Applications in the Real World
Chaining the Beast - Testing Wonder Applications in the Real WorldWO Community
 
D2W Stateful Controllers
D2W Stateful ControllersD2W Stateful Controllers
D2W Stateful ControllersWO Community
 
Deploying WO on Windows
Deploying WO on WindowsDeploying WO on Windows
Deploying WO on WindowsWO Community
 
Unit Testing with WOUnit
Unit Testing with WOUnitUnit Testing with WOUnit
Unit Testing with WOUnitWO Community
 
Apache Cayenne for WO Devs
Apache Cayenne for WO DevsApache Cayenne for WO Devs
Apache Cayenne for WO DevsWO Community
 
Advanced Apache Cayenne
Advanced Apache CayenneAdvanced Apache Cayenne
Advanced Apache CayenneWO Community
 
Migrating existing Projects to Wonder
Migrating existing Projects to WonderMigrating existing Projects to Wonder
Migrating existing Projects to WonderWO Community
 
iOS for ERREST - alternative version
iOS for ERREST - alternative versioniOS for ERREST - alternative version
iOS for ERREST - alternative versionWO Community
 
"Framework Principal" pattern
"Framework Principal" pattern"Framework Principal" pattern
"Framework Principal" patternWO Community
 
Filtering data with D2W
Filtering data with D2W Filtering data with D2W
Filtering data with D2W WO Community
 
Localizing your apps for multibyte languages
Localizing your apps for multibyte languagesLocalizing your apps for multibyte languages
Localizing your apps for multibyte languagesWO Community
 

Plus de WO Community (20)

KAAccessControl
KAAccessControlKAAccessControl
KAAccessControl
 
In memory OLAP engine
In memory OLAP engineIn memory OLAP engine
In memory OLAP engine
 
Using Nagios to monitor your WO systems
Using Nagios to monitor your WO systemsUsing Nagios to monitor your WO systems
Using Nagios to monitor your WO systems
 
Build and deployment
Build and deploymentBuild and deployment
Build and deployment
 
High availability
High availabilityHigh availability
High availability
 
Reenabling SOAP using ERJaxWS
Reenabling SOAP using ERJaxWSReenabling SOAP using ERJaxWS
Reenabling SOAP using ERJaxWS
 
Chaining the Beast - Testing Wonder Applications in the Real World
Chaining the Beast - Testing Wonder Applications in the Real WorldChaining the Beast - Testing Wonder Applications in the Real World
Chaining the Beast - Testing Wonder Applications in the Real World
 
D2W Stateful Controllers
D2W Stateful ControllersD2W Stateful Controllers
D2W Stateful Controllers
 
Deploying WO on Windows
Deploying WO on WindowsDeploying WO on Windows
Deploying WO on Windows
 
Unit Testing with WOUnit
Unit Testing with WOUnitUnit Testing with WOUnit
Unit Testing with WOUnit
 
Life outside WO
Life outside WOLife outside WO
Life outside WO
 
Apache Cayenne for WO Devs
Apache Cayenne for WO DevsApache Cayenne for WO Devs
Apache Cayenne for WO Devs
 
Advanced Apache Cayenne
Advanced Apache CayenneAdvanced Apache Cayenne
Advanced Apache Cayenne
 
Migrating existing Projects to Wonder
Migrating existing Projects to WonderMigrating existing Projects to Wonder
Migrating existing Projects to Wonder
 
iOS for ERREST - alternative version
iOS for ERREST - alternative versioniOS for ERREST - alternative version
iOS for ERREST - alternative version
 
iOS for ERREST
iOS for ERRESTiOS for ERREST
iOS for ERREST
 
"Framework Principal" pattern
"Framework Principal" pattern"Framework Principal" pattern
"Framework Principal" pattern
 
Filtering data with D2W
Filtering data with D2W Filtering data with D2W
Filtering data with D2W
 
WOver
WOverWOver
WOver
 
Localizing your apps for multibyte languages
Localizing your apps for multibyte languagesLocalizing your apps for multibyte languages
Localizing your apps for multibyte languages
 

Dernier

"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????blackmambaettijean
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 

Dernier (20)

"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 

Hidden Treasures in Project Wonder

  • 1. Hidden Treasures in Project Wonder Spirit of Mike Schrag Whereabouts Unknown Channeled By Chuck Hill Global Village Consulting
  • 2. What You See • Mike’s Step 1: Look at every damn method in Wonder. • Mike’s Step 1a: Seriously. Every one. • Mike’s Step 2: “Cool” = Chosen
  • 3. What You Get • Notification of existence • Nothing in-depth
  • 4. Type-safe pageWithName • <T extends WOComponent> T pageWithName(Class<T> componentClass) • ERXApplication, ERXDirectAction, ERXComponent • less typing • refactoring updates them • compiler errors for speeling errors
  • 5. Type-safe pageWithName old way MyPage page = (MyPage)pageWithName(“MyPage”); new way MyPage page = (MyPage)pageWithName(MyPage.class.getName()); cool way MyPage page = pageWithName(MyPage.class);
  • 6. IVersionManager • better control of static resource caching • infinite expiration in Apache • change resource url when resource changes • pluggable versioning schemes • “default” = WebObjects default • “properties” = specify version numbers in properties • your own
  • 10. ERXDirectAction / eoAdaptorDebugging url /wa/ERXDirectAction/eoAdaptorDebugging?debug=on&pw=somepw /wa/ERXDirectAction/eoAdaptorDebugging?debug=off&pw=somepw properties er.extensions.ERXEOAdaptorDebuggingPassword=somepw
  • 11. ERXMainRunner • initializes all of Wonder • runs “main” method inside of an Application context • java -classpath ... er.extensions.appserver.ERXMainRunner -mainClass YourClass
  • 12. ERXApplication._rewriteURL • Pretty URLs • One generator method to rule them all
  • 13. ERXApplication._rewriteURL (simple method) properties er.extensions.ERXApplication.replaceApplicationPath.pattern= ↵ /cgi-bin/WebObjects/YourApp.woa er.extensions.ERXApplication.replaceApplicationPath.replace= ↵ /yourapp produces http://server.com/yourapp/wa/default apache rewrite rule RewriteRule ^/yourapp(.*)$ /cgi-bin/WebObjects/YourApp.woa$1 [PT,L]
  • 14. ERXApplication._rewriteURL (complex method) Application subclass @Override public String _rewriteURL(String url) { return convertURLWithFancyRegexOrSomething(url); } apache rewrite rule rewrite rule has to be an inverse of your _rewriteURL implementation
  • 15. ERXRedirect • drop-in replacement for WORedirect • can redirect to a component instance rather than a direct action • generates document.location.href=... in Ajax request • https support • api for setting query parameters
  • 16. ERXRedirect public WOActionResults doSomething() { ERXRedirect redirect = pageWithName(ERXRedirect.class); NextPage nextPage = pageWithName(NextPage.class); nextPage.setState(someStateFromThisPage); redirect.setComponent(nextPage); return redirect; }
  • 17. ERXSession.useSecureSessionCookies • secure cookies are only sent across https requests • wosid and woinst are not secure cookies by default (and thus vulnerable to sniffing off a non-https url)
  • 18. ERXSession.useSecureSessionCookies @Override public boolean useSecureSessionCookies() { return true; } or er.extensions.ERXSession.useSecureSessionCookies=true
  • 19. ERXFlickrBatchNavigation • WOBatchNavigationBar looks like ass • ERXFlickrBatchNavigation does not • Drop-in replacement of WOBatchNavigationBar
  • 20. ERXDataHyperlink • Like WOHyperlink but with object-based attribute passing • Automagically calls accessor methods on pageName component • Safe ... doesn’t leak data to user • An example will make more sense
  • 21. ERXDataHyperlink PersonList page <wo:ERXDataHyperlink pageName=”PersonEdit” ↵ person=”$currentPerson”> edit person </wo:ERXDataHyperlink> PersonEdit page public class PersonEdit extends WOComponent { ... public void setPerson(Person person) { _person = person; } }
  • 22. ERXInlineTemplate • Generate a WOComponent on-the-fly • Generate a WOComponent from a database (i.e. a CMS) • Take over the world?
  • 23. ERXInlineTemplate basic <wo:ERXInlineTemplate html=”$someHtmlString” wod=”$someWodString”/> (using woognl doesn’t require a wod) cache generated component <wo:ERXInlineTemplate html=”$someHtmlString” wod=”$someWodString” cacheKey=”MyCacheKey” cacheVersion=”$computedVersionObject”/> (when cacheVersion changes, regenerate)
  • 24. ERXWOComponentContent / ERXWOTemplate • WOComponentContent but with multiple content areas • example: a DialogComponent has a “title” area and a “content” area
  • 25. ERXWOComponentContent / ERXWOTemplate DialogComponent <div> <div><wo:ERXWOComponentContent templateName=”title”/></div> <div><wo:ERXWOComponentContent templateName=”content”/></div> </div> CallingComponent <wo:DialogComponent> <wo:ERXWOTemplate templateName=”title”> this is the title and you can put real components in here </wo:ERXWOTemplate> <wo:ERXWOTemplate templateName=”content”> this is the content of the dialog </wo:ERXWOTemplate> </wo:DialogComponent>
  • 26. ERXLoremIpsumGenerator • sometimes you just need fake content (test cases, load tests, mockups) • “Lorem ipsum dolor sit amet, ...” • ERXLoremIpsumGenerator.paragraph(3) = 3 paragraphs • ERXLoremIpsumGenerator.sentence(1) = 1 sentence • ERXLoremIpsumGenerator.words(10) = 10 words
  • 27. Captchas and Spam Checks • ERXSimpleSpamCheck (ERExtensions.framework) sets a hidden field with javascript • ERReCaptcha (ERCaptcha.framework) reCAPTCHA wrapper (http:// www.google.com/recaptcha) • ERAkismet (ERCaptcha.framework) Akismet wrapper (http://akismet.com); spam checks blog comments
  • 28. Captchas and Spam Checks • calls validationFailedWithException on failure • sets “valid” binding accordingly
  • 29. Captchas and Spam Checks <wo:form> <wo:ERXSimpleSpamCheck /> <wo:WOTextField value=”$firstName” /> <wo:WOSubmitButton action=”$doSomething” /> </wo:form>
  • 30. ERXRssPage • quickly produce RSS feeds • feedTitle, feedUrl, feedDescription • list : list of items to show in the feed • item : repetition item • itemGuid, itemTitle, itemLink, itemPubDate, itemAuthor • description from WOComponentContent
  • 31. ERXRssPage <wo:ERXRssPage feedTitle=”RSS of People” feedUrl=”http://yourhost.com” feedDescription=”This is my list of people!” list=”$people” item=”$person” itemGuid=”$person.primaryKey” itemTitle=”$person.fullName” itemLink=”$someURLToThePerson” itemPubDate=”$person.creationDate” />
  • 32. ERXWORepetition • WORepetition relies on repetition item indexes • changing item order = you just clicked “delete” on the wrong row ... whoops • uses key instead of index • small risk of collision, but unlikely in tests (use uniqueKey binding to prevent)
  • 33. ERXWORepetition properties # use hash codes of objects instead of index er.extensions.ERXWORepetition.checkHashCodes=true # throw an exception if a match isn’t found er.extensions.ERXWORepetition.raiseOnUnmatchedObject=true unique keys # use item PKs instead of hash codes <wo:ERXWORepetition uniqueKey=”$person.primaryKey”> ...
  • 34. External Services • ERXGoogleSpell.correct(String) • spelling correction like Google’s “did you mean” • ERXYahooContentAnalysisService.termExtra ction(..) • extracts important terms from text • useful for guessing ERTaggable tags • Access keys required, read Javadoc for details
  • 35. ERXEnterpriseObjectCache • caches EO’s based on a keypath • optionally filter with qualifier (dynamically updates!) example: two caches -- published=true, published=false • optional timed expiration
  • 36. ERXEnterpriseObjectCache • use this constructor and shouldRetainObjects=true! public ERXEnterpriseObjectCache( String entityName, String keyPath, EOQualifier qualifier, long timeout, boolean shouldRetainObjects, boolean shouldFetchInitialValues)
  • 37. ERXEnterpriseObjectCache # cache any CMSPage objects by their “name” key # that are published=true # expire them after 60 seconds ERXEnterpriseObjectCache cache = new ERXEnterpriseObjectCache( CMSPage.ENTITY_NAME, CMSPage.NAME_KEY, CMSPage.PUBLISHED.isTrue(), 60 * 1000); EOEditingContext editingContext = ERXEC.newEditingContext(); CMSPage homePage = cache.objectForKey(editingContext, “HomePage”); homePage.setPublished(false); editingContext.saveChanges(); # published = false, so it is dynamically removed from the cache
  • 38. ERXEOControlUtilities • ERXEOControlUtilities.convertEOtoGID / convertGIDtoEO recursively convert data structures from EO’s to GID’s (NSDictionary of String to NSArray of EO’s becomes NSDictionary of String to NSArray of GID’s, etc) and the corresponding inverse method
  • 39. ERXEOControlUtilities • ERXEOControlUtilities.eoEquals compare two EO’s, returning true if their GID’s match, regardless of the EOEditingContext that contains both of them • ERXEOControlUtilities.aggregateFunctionWith Qualifier perform MIN/MAX/AVG/etc database functions on attributes of an entity without writing custom SQL
  • 40. Automatic Batch Faulting • Common problem: Fetch array of Person objects, show them in a table, for each row, show the person.company().name() • Common solution: Manually batch fetch “company.name” on the Person objects. • Bad-ass solution: er.extensions.ERXDatabaseContextDelegate. autoBatchFetchSize=50 • Automatically batch fetches faulted relationships on all EO’s that were fetched from the same query
  • 41. Automatic Batch Faulting NSArray<Person> people = ec.objectsWithFetchSpecification(fspec); # this automatically faults all the companies for # the person objects in the “people” array (up to # your 50 max specified in the property) Company comp = people.objectAtIndex(0).company(); String name = comp.name(); # this automatically faults all the employees for # all the companies that were just batch fetched # above -- it’s magic and recursive NSArray<Person> employees = comp.employees(); # restricts to only the visible objects if attached # to a display group
  • 42. ERXUnitAwareDecimalFormat • automatically format bytes/meters/grams/ seconds in metric decimal form • scales to appropriate unit based on size • 1234567890 bytes becomes “1.15GB” NumberFormat formatter = new ERXUnitAwareDecimalFormat (ERXUnitAwareDecimalFormat.BYTE); formatter.setMaximumFractionDigits(2); formatter.format(1234567890.0);
  • 43. ERXJDBCAdaptor • fixes double connection bug from jdbcInfo • should just be the default • er.extensions.ERXJDBCAdaptor.className = er.extensions.jdbc.ERXJDBCAdaptor
  • 44. ERXMutableURL • java.net.URL is garbage. ERXMutableURL is not. • mutable interface to a URL object • add query parameters one-by-one • supports weird “urls” like “javascript:” and incomplete “/wa/something”
  • 45. ERXMutableURL ERXMutableURL url = new ERXMutableURL( "http://yourhost.com:80/tutorial/index.html?key1=value1#someref"); url.setRef(null); url.removeQueryParameter("key1"); url.addQueryParameter("key2", “value2”); url.addQueryParameters(“key3=value3&key4=value4”); java.net.URL javaneturl = url.toURL(); String urlString = url.toExternalForm();
  • 46. ERXThreadStorage • a ThreadLocal dictionary that resets for each request • Object obj = ERXThreadStorage.valueForKey (String) • ERXThreadStorage.takeValueForKey(Object, String) • common uses: current user, current session, current context
  • 47. ERXValueUtilities • convert objects to various common types including “default” form • example: booleanValue(Object) / booleanValueWithDefault(Object, boolean def) • supports boolean, Boolean, int, Integer, float, Float, double, Double, long, Long, array, set, dictionary, data, bigDecimal, enum • converts from every possible form for you -- handy for bindings
  • 48. ERMemoryAdaptor • acts like a database, but just talking to dictionaries • great for test cases • no SQL support -- don’t try to get tricky • Include JavaMemoryAdaptor.framework • dbConnectAdaptorGLOBAL=Memory or [ModelName].adaptor=Memory
  • 49. ERPDFWrapper • Turn any HTML+CSS page into a PDF • Include ERPDFGeneration.framework • <wo:ERPDFWrapper> <html> ... </wo:ERPDFWrapper> • Done. That’s just cool.
  • 50. PFProfiler / SESnapshotExplorer • These are in another talk. • They’re cool, though. • Pay attention during that talk.
  • 51. ERXResponseRewriter.Delegate • intercept all resource insertions, optionally replacing (or denying) them • example: you have your own prototype.js and you want to replace Ajax.framework’s version with yours • via properties (for simple cases) or via custom delegate • responseRewriterWillAddResource
  • 52. ERXResponseRewriter.Delegate properties er.extensions.ERXResponseRewriter.resource.[framework].[filename]= [newFramework].[newFileName] er.extensions.ERXResponseRewriter.resource.Ajax.prototype.js= app.myprototype.js delegate (example replaces EVERY file with myfile.png -- be smarter) ERXResponseRewriter.setDelegate(new ERXResponseRewriter.Delegate() { public boolean responseRewriterShouldAddResource( String framework, String fileName) { return true; } public ERXResponseRewriter.Resource responseRewriterWillAddResource( String framework, String fileName) { return new ERXResponseRewriter.Resource(“app”, “myfile.png”); });
  • 53. applyRestrictingQualifierOnInsert • er.extensions.ERXEnterpriseObject.applyRest rictingQualifierOnInsert=true • makes new objects automatically match their entity’s restricting qualifier • i.e. if Employee is “personType = 5”, a new Employee will automatically have personType = 5 set on it • no more awakeFromInsertion junk
  • 54. secureDisabled • You use DirectConnect • You don’t have SSL in dev • You want to run your app • er.extensions.ERXRequest.secureDisabled=tr ue • Turns off all https URL generation -- only works in dev
  • 55. ERXAdaptorChannelDelegate • conditionally log slow SQL execution (and some other cool debugging stuff) • took 100ms, log.info the expression • took 1000ms, log.warn the expression • etc ...
  • 57. Q&A Spirit of Mike Schrag Whereabouts Unknown Channeled By Chuck Hill Global Village Consulting