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
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
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)
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
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
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”
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
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 ...