Class
and Module
constructs,
though other support entities are defined in this module that are worthy of note, including a Firebug-like
console abstraction (the Console
object), and a module-based localization facility
(the Catalog
class).
Individual methods, as well as modules, classes and objects named with a leading underscore ('_')
character are considered internal implementation details. Use of such objects/methods is unsupported
and the behavior and existence of such objects/methods is subject to change without notice.
The Catalog
class is an interface to a module's localization subsystem. A Catalog represents
a set of localized data and is accessed by module-based code to convert default-text strings into
localized versions of those strings when such localized versions are available.
Method Summary | ||
public void
|
load(l10nData)
This method loads a module's catalog with the localization data specified in the l10nData parameter. |
|
public string
|
localize(msg, [varargs])
Returns a localized version of the supplied message, if such a localization can be found. |
Method Detail |
public void load(l10nData)
$MyModule.$meta.getCatalog().load({ "default message value" : "localized message value", // ... });A missing mapping in the l10n data object (or a mapping with a "falsy" value) will result in the use of the default message (the key) for a given lookup. Explicit catalog localization will generally be used for purposes of l10n catalog aggregation, but may also be used to explicitly set or override l10n data on a per-catalog basis, as appropriate.
object l10nData
- A mapping of default message values to localized message valuespublic string localize(msg, [varargs])
var msg = myCatalog.localize("Some default message value with two args: {0} and {1}", "one", "two");
string msg
- A default message value to attempt to localize [varargs]
- Any number of additional parameters to the method to be used as values for message formattingstring
-
A formatted version of the message, localized if matching l10n data was found
The Class
helper provides functionality for declaring new "classes" in the Disc framework.
These classes support single inheritance of instance and static member fields and methods (mixins may be
used in place of multiple inheritance), public or internal initializers, super references, and dynamic
injection and removal of members, as demonstrated below. Additionally, class body declarations may be
expressed multiple ways.
// Declare a base class var Person = bea.wlp.disc.Class.create({ // Base class initializer initialize: function(name) { // Initialize internal instance variables this._name = name; this._greeting = "hi"; }, // Declare some instance methods greet: function(person) { return (this + " says '" + this._greeting + "' to " + person); }, toString: function() { return this._name; } }); // Declare the Cowboy subclass of Person var Cowboy = Person.extend({ initialize: function(name) { // Call this class's super constructor (Person.initialize) this.sup(name); // Override the base class's greeting this._greeting = "howdy"; }, // Override the base class's toString method toString: function() { // Call the super class's toString and prepend the Cowboy designation return "Cowboy " + this.sup(); } }); // Example usage var john = new Person("John"); var bill = new Cowboy("Bill"); assertEquals("John says 'hi' to Cowboy Bill", john.greet(bill)); assertEquals("Cowboy Bill says 'howdy' to John", bill.greet(john));Advanced Example This example demonstrates static field and method inheritance. Additionally, it uses the more expressive (but also more verbose) function style of class body declaration to provide convenient access to the class's static context.
// Declare a base class var Shape = bea.wlp.disc.Class.create(function(Shape) { // Base class initializer this.initialize = function(x, y) { // Initialize internal instance variables this.x = 0; this.y = 0; this.translate(x, y); this._name = "Shape"; }; // Declare some instance methods this.translate = function(x, y) { this.x += (x || Shape.ORIGIN.x); this.y += (y || Shape.ORIGIN.y); }; this.draw = function(x, y) { this.translate(x, y); return (this._name + ": x=" + this.x + ", y=" + this.y); }; // Declare a public static field Shape.ORIGIN = { x: 0, y: 0 }; }); // Subclass Shape to create the Circle class var Circle = Shape.extend(function(Circle) { // Declare a private static variable var DEFAULT_RADIUS = 1; // Initializer this.initialize = function(x, y, r) { this.sup(x, y); this.r = (r || DEFAULT_RADIUS); this._name = "Circle"; }; // Override Shape's draw method this.draw = function(x, y) { // Indirectly reference the base class's ORIGIN static var containsOrigin = Circle.contains(this, Circle.ORIGIN); return (this.sup(x, y) + ", r=" + this.r + ", contains origin=" + containsOrigin); }; // Static public method Circle.contains = function(circle, point) { var xd = point.x - circle.x; var yd = point.y - circle.y; return (Math.abs(Math.sqrt(xd * xd + yd * yd)) < circle.r); }; }); var circle = new Circle(); assertEquals("Circle: x=0, y=0, r=1, contains origin=true", circle.draw()); circle = new Circle(2, 2, 2); assertEquals("Circle: x=4, y=4, r=2, contains origin=false", circle.draw(2, 2));Built-in Constructor Statics The following static methods are automatically mixed in to class constructors created with
Class.create
:
extend(subdecl) {typeof subdecl == "object" or "function"; returns new class constructor}
The extend
static method supports subclassing as demonstrated in the above examples.
In the following example the extend
method of the SuperClass
constructor function
is used to declare the SubClass
subclass of SuperClass
.
var SuperClass = bea.wlp.disc.Class.create(); var SubClass = SuperClass.extend(); assertTrue(new SubClass() instanceof SuperClass);inject(name, value) {typeof name == "string" or "object" && typeof value == "object" or "function"} The
inject
static method is used to insert a method or field into a class declaration after
it has been created with Class.create
. The following example shows the use of
inject
to do just that.
var Cowboy = bea.wlp.disc.Class.create({ initialize: function(name) { this._name = name; } }); Cowboy.inject("lasso", function(target) { return "Cowboy " + this._name + " lassoed a " + target + "!"; }); assertEquals("Cowboy Bill lassoed a goat!", new Cowboy("Bill").lasso("goat"));The
inject
method can also be used to batch inject the contents of a mixin. As such, the
previous example can be rewritten like this:
var Cowboy = bea.wlp.disc.Class.create({ initialize: function(name) { this._name = name; } }); Cowboy.inject({ lasso: function(target) { return "Cowboy " + this._name + " lassoed a " + target + "!"; }}); assertEquals("Cowboy Bill lassoed a goat!", new Cowboy("Bill").lasso("goat"));Of course more than one item can be injected using the batch syntax:
var Cowboy = bea.wlp.disc.Class.create({ initialize: function(name) { this._name = name; } }); Cowboy.inject({ lasso: function(target) { return "Cowboy " + this._name + " lassoed a " + target + "!"; }, shoot: function(target) { return "Cowboy " + this._name + " shot a " + target + "!"; } }); var bill = new Cowboy("Bill"); assertEquals("Cowboy Bill lassoed a goat!", bill.lasso("goat")); assertEquals("Cowboy Bill shot a varmint!", bill.shoot("varmint"));remove(name) {typeof name == "string" or "object"} The
remove
static method is used to remove methods or fields from a class declaration. This
method is the counterpart to the inject
method, though it does not necessarily have to operate
on members added to the class via injection. The following example shows the remove
method
removing members created through both declaration mechanisms.
var MyClass = bea.wlp.disc.Class.create({ one: function() { return "remove me"; } }); MyClass.inject("two", function() { return "remove me, too"; }); var instance = new MyClass(); assertNotNull(instance.one); assertNotNull(instance.two); // ... later ... MyClass.remove("one"); MyClass.remove("two"); instance = new MyClass(); assertUndefined(instance.one); assertUndefined(instance.two);The
remove
method can also be used in batch mode just like inject
:
var mixin = { one: function() { return "remove me"; }, two: function() { return "remove me, too"; } } var MyClass = bea.wlp.disc.Class.create(); MyClass.inject(mixin); var instance = new MyClass(); assertNotNull(instance.one); assertNotNull(instance.two); // ... later ... MyClass.remove(mixin); instance = new MyClass(); assertUndefined(instance.one); assertUndefined(instance.two);The design and implementation of this class framework was influenced by several sources, especially the work of Ben Newman at http://seraph.im.
Method Summary | ||
public function
|
create([decl])
Create a new class. |
Method Detail |
public function create([decl])
create
method in one of three
main ways:
...with a body expressed in object literal notation:
This approach creates a new class whose body is defined by the object literal passed as the value of the
decl
argument.
var MyClass = bea.wlp.disc.Class.create({ myMethod: function() { return "some stuff I did"; } }); var myInstance = new MyClass(); assertNotNull(myInstance.myMethod); assertEquals("some stuff I did", myInstance.myMethod());...with a body declared as a static initializer function: This approach creates a new class whose body is defined by the function passed as the value of the
decl
argument. Note that the term "static initializer function" is used to describe this
function since it staticly initializes the class when constructing the class's actual
constructor function. Any local variables over which closures are created in this context will act like
class static variables since they will be shared by all instances of the class.
Also note the argument passed to the function used in this example: MyClass
. This argument
provides a static context for the class to which can be attached any public, inheritable, static members
that maybe be appropriate for the class being created. The name of this argument should generally
match the name of the class being created, for clarity, but this convention is not enforced by the
create
function.
var MyClass = bea.wlp.disc.Class.create(function(MyClass) { this.myMethod = function() { return "some stuff I did"; }; MyClass.PI = 3.14; }); var myInstance = new MyClass(); assertNotNull(myInstance.myMethod); assertEquals("some stuff I did", myInstance.myMethod()); assertEquals(3.14, MyClass.PI);...or without a body: This approach creates a bare new class without any unique members. Members can be added after declaration as needed using the newly created class constructor's
inject
method, as follows:
var MyClass = bea.wlp.disc.Class.create(); MyClass.inject("myMethod", function() { return "some stuff I did"; }); var myInstance = new MyClass(); assertNotNull(myInstance.myMethod); assertEquals("some stuff I did", myInstance.myMethod());This approach is discouraged in favor of the use of the more encapsulated forms described above but may still be useful in some scenarios, such as the dynamic application of mixins.
object|function [decl]
- An optional object or static initializer function to serve as the class's bodyfunction
-
A constructor function for the new created classA basic configuration API for the core Disc module.
Method Summary | ||
public string
|
getContextPath()
Returns the current context path setting. |
|
public string
|
getScriptPath([scriptName])
Returns the current script path setting, with any additional path information (indicated by the optional scriptName argument) appended.
|
|
public void
|
setContextPath(contextPath)
This method should be used to set the webapp's context path. |
Method Detail |
public string getContextPath()
string
-
The context path, if set; null otherwisepublic string getScriptPath([scriptName])
scriptName
argument) appended. The script path is the result of combining
the webapp's context path with the constant "framework/scripts/".string [scriptName]
- Additional path/filename information to be appended to this object's script path setting,
if any; if not specified, the bare script path is returnedstring
-
The raw script path value or the union of said and the scriptName param or an empty string
if neither value is definedpublic void setContextPath(contextPath)
string contextPath
- The value to use as context path for on-demand module loading
The Console
object provides a simple abstraction over the well-known but not always present
Firebug or Firebug Lite console
global. Writing Firebug console operations to this object
instead of the global Firebug console ensures that when that global console is not present, the operation
will not fail due to the console object being undefined. When not available, the firebug-level operations
on this object may execute as no-ops.
Method Summary | ||
public void
|
addListener(listener)
This method allows listeners to be added to the global Disc console object. |
|
public void
|
assert()
|
|
public void
|
count()
|
|
public void
|
debug()
|
|
public void
|
dir()
|
|
public void
|
dirxml()
|
|
public void
|
error()
|
|
public void
|
group()
|
|
public void
|
groupEnd()
|
|
public void
|
info()
|
|
public void
|
log()
|
|
public void
|
profile()
|
|
public void
|
profileEnd()
|
|
public void
|
removeListener(listener)
This method simply removes a listener from the Disc console object if previously added. |
|
public void
|
time()
|
|
public void
|
timeEnd()
|
|
public void
|
trace()
|
|
public void
|
warn()
|
Method Detail |
public void addListener(listener)
addListener
or removeListener
) called on this object will cause
registered listener callback functions to be invoked. Listener callback functions should accept two
parameters: "op" and "args". The former is the name of the operation that was invoked (e.g. "log"), and
the latter is the list of arguments with which it was called. Possible operation names include:
"assert", "count", "debug", "dir", "dirxml", "error", "group", "groupEnd", "info", "log", "profile",
"profileEnd", "time", "timeEnd", "trace", and "warn". Applying appropriate semantics to each operation
is left as an exercise to each listener implementation.
For example, the following code would register a naive listener that routed all messages to an element
named "myConsoleOutput", simply appending a new "line" for each routed message:
bea.wlp.disc.Console.addListener(function(op, args) { var output = document.getElementById("myConsoleOutput"); output.appendChild(document.createElement("br")); output.appendChild(document.createTextNode(op + ": " + args.join(","))); });
function listener
- The listener callback function to be addedpublic void assert()
public void count()
public void debug()
public void dir()
public void dirxml()
public void error()
public void group()
public void groupEnd()
public void info()
public void log()
public void profile()
public void profileEnd()
public void removeListener(listener)
function listener
- The listener function to be removedpublic void time()
public void timeEnd()
public void trace()
public void warn()
The Module
class comprises one of the most central facilities of the Disc core API: it provides
a namespacing infrastructure for managing modularized code in the global execution context. While this class
facilitates the creation of and interaction with namespace objects (modules), it does not impose a fixed
structure upon them.
bea.wlp.*
namespace; any modifications
to that namespace (and/or the constituents thereof) which are not supported through public APIs may result in
undefined and unsupported behavior.
Modules are created via calls to the static Module.create
function. Modules should be named to
follow typical Java package naming conventions, that is, a '.' delimited list of valid JavaScript
identifiers, typically composed of all lower-case letters.
Each module contains, at a minimum, a $meta
field that provides a number of basic operations
around the module itself, including accessors for this module's name, parent module, catalog, and an
indication of whether or not the module has been formally defined (or if, instead, it exists purely for
namepsacing purposes).
Modules support loading via either static script tag references (HTML) or dynamic loading via sync-XHR. The
former should be used to deliver module source (or compiled module bundles) in production-mode scenarios.
The latter can be a convenient tool for iteratively developing Disc-based JavaScript. Production-mode
construction and deployment of module bundles is performed automatically for well-known Disc APIs; for
custom Disc APIs, such construction and deployment is currently left as an exercise to the API developer.
Dynamic module loading is driven through the use of the static Module.use
method.
Dynamically loaded modules assume a specific file layout on the resource server. Each individual
name-component of the overall module name (i.e. each identifier in the module name chain, delimited with '.'
characters) is assumed to be a directory. The filesystem hierarchy of these directories must match the
hierarchy specified by the overall module name. Each directory with a non-trivial module (that is, any
bottom-level module for which one may call Module.use
) must contain a file named
module.js
, containing an appropriate call to Module.create
. Any module facets to
be contributed to the dynamically loaded module must live in the module's directory, peer to it's
module.js
file. For example, the hypothetical module named "my.fancy.api" might look like
this on the filesystem:
+ my | ----+ fancy | ----+ api | ---- module.js | ---- FacetOne.js | ---- FacetTwo.js...where the module declaration in
module.js
specifies its facet inclusions as
include: ["FacetOne", "FacetTwo"]
(see Module.create
and
Module.contribute
for module and facet declaration details). This structure will then be
synchronously loaded and realized on-demand, via the Module.use
invocation.
Lastly, each Module
instance has an associated Catalog
instance used for the
organization of any given module's localizable messages. See the documentation for the Catalog
class for more information.
Module instantiation should only be performed internally; use bea.wlp.disc.Module.create
to
explicitly create a new module. Directly contructing modules via the new
operator is not
supported.
Field Summary | |
public object
|
$meta
This field is a special member of all Module instances that provides some simple
metadata getters.
|
Method Summary | ||
public bea.wlp.disc.Catalog
|
$meta.getCatalog()
Returns this module's bea.wlp.disc.Catalog instance.
|
|
public string
|
$meta.getName([sub])
Returns the name of the current module. |
|
public bea.wlp.disc.Module|window|object
|
$meta.getParent()
Returns the module's parent object. |
|
public boolean
|
$meta.isDeclared()
Indicates whether or not this module has been explicitly declared, or is instead a placeholder module existing (so far) purely for namepsacing. |
|
public static void
|
contribute(decl)
This method is used to contribute module facets to an existing module. |
|
public static bea.wlp.disc.Module
|
create(name, decl)
Creates a new module. |
|
public static bea.wlp.disc.Module|object
|
find(name)
Attempts to locate and return a module or an object child of a module. |
|
public static boolean
|
isDefined(nameOrModule)
Determines whether or not the specified module both exists and has been declared. |
|
public string
|
toString()
This method returns this module's name as a string. |
|
public static bea.wlp.disc.Module
|
use(name)
Attempts to return a module instance by name; if the requested module does not yet exist or exists but has not yet been created, this method attempts to load the module from this script's host server, according to the setting(s) in bea.wlp.disc.Config .
|
Field Detail |
public object $meta
Module
instances that provides some simple
metadata getters.Method Detail |
public bea.wlp.disc.Catalog $meta.getCatalog()
bea.wlp.disc.Catalog
instance.bea.wlp.disc.Catalog
-
This module's catalog; not nullpublic string $meta.getName([sub])
sub
param, sub is appended to the module name returned in
the no-args version; e.g. bea.wlp.disc.$meta.getName("foo") == "bea.wlp.disc.foo".
For example:
bea.wlp.disc.Module.create("ns.mod", { }); assertEquals("ns.mod", ns.mod.$meta.getName()); assertEquals("ns.mod.sub", ns.mod.$meta.getName("sub"));
string [sub]
- An additional string to append to the normal result of getName()
, if anystring
-
The module's name, with the sub
param appended if specifiedpublic bea.wlp.disc.Module|window|object $meta.getParent()
bea.wlp.disc.Module
, but may be another object type or the global
window
object if called on a root module, such as bea
. Calls to
this method should always check the type of the returned object before making assumptions
about that object's properties.
For example:
bea.wlp.disc.Module.create("ns.mod", { }); assertEquals(ns, ns.mod.$meta.getParent()); assertEquals(window, ns.$meta.getParent());
bea.wlp.disc.Module|window|object
-
The value returned is one of bea.wlp.disc.Module, the global window
object, or another object; the exact result depends on the environment in which the module
was created
public boolean $meta.isDeclared()
bea.wlp.disc.Module.create("ns.mod", { }); assertFalse(ns.$meta.isDeclared()); assertTrue(ns.mod.$meta.isDeclared());
boolean
-
True if the module has been explicitly declared; false otherwisepublic static void contribute(decl)
decl
parameter supplied to this method is an initializer function exactly like those
used to create modules. It can receive the same parameters as module initializers (i.e. $
and L
, which respectively refer to the target module's self reference and catalog's
localization function) and whose this
reference also points to the target module. In
essence this function provides an additional module initializer to use in the context in which the
call to contribute
is made.object|function decl
- A module initializer object or function used to supply additional content for the module with which it
is associatedpublic static bea.wlp.disc.Module create(name, decl)
Module.create
.
Module names should typically be defined as a sequence of valid JavaScript identifiers delimited with the '.'
character. Each '.' in the name specifies a tier in the overall module hierarchy, with each distinct
identifier representing a distinct module. Any parent modules not already in existence will be created on
the fly to support the bottom-level module in the specified name passed to this method. Any modules so
created will be valid Disc modules, but will not be technically "declared" until a subsequent call to
Module.create
is made with that module as the bottom-level module in the overall module name
(which may never occur). Such modules exist in support of the namespacing hierarchy, but do not
necessarily provide any meaningful APIs in and of themselves.
The decl
param passed to this method must be an object supplying one or more of the following
fields:
module.js
file named as "<facet name>.js"; see the
Module.contribute
static method for more information on facet contribution to a
moduleClass.create
in form and function, except
that, if specified as a function, accepts exactly two (optional) arguments, typically named
$
and L
; the $
argument is the module's self-reference (a
shortcut for the "this" reference), and the L
argument is a convenience shortcut
function for this module's catalog's localize
function
(alternately addressable as $.$meta.getCatalog().localize
)declare
field; called once this module and any modules upon which this module depends
(as specified in the require
field) are fully realizedstring name
- The name of the new moduleobject decl
- A declaration object, as defined abovebea.wlp.disc.Module
-
The module associated with the indicated module namepublic static bea.wlp.disc.Module|object find(name)
bea.wlp.disc.Module.create("ns.mod", { declare: function($, L) { $.AnObject = { data: "stuff" }; } }); assertTrue(!!bea.wlp.disc.Module.find("ns")); assertTrue(!!bea.wlp.disc.Module.find("ns.mod")); assertTrue(!!bea.wlp.disc.Module.find("ns.mod.AnObject")); assertEquals("stuff", bea.wlp.disc.Module.find("ns.mod.AnObject").data);Note that any module instance returned by this method is not guaranteed to be declared. Module instances may exist as simple namespace constructs without having their own explicit declarations, yet this method does not distinguish between the two. Use
bea.wlp.disc.Module.isDefined
to determine if a module exists and has been declared.
Unlike bea.wlp.disc.Module.use
, this method does not attempt to load a module if it was not
found.string name
- The name of the module or object to findbea.wlp.disc.Module|object
-
The module or object, if foundpublic static boolean isDefined(nameOrModule)
myModule.$meta.isDeclared()
. If a string
name is passed, this method attempts to find the module, and then, if it exists, returns its declaration
status, as above.string|bea.wlp.disc.Module nameOrModule
- Either a module or module name to determineboolean
-
True if the module exists and is declared; false otherwisepublic string toString()
string
-
The name of the module on which this method was calledpublic static bea.wlp.disc.Module use(name)
bea.wlp.disc.Config
. If you wish to simply check whether or
not a module exists, consider using bea.wlp.disc.Module.find
or
bea.wlp.disc.Module.isDefined
.
// bea.wlp.disc is created var $Disc = bea.wlp.disc.Module.use("bea.wlp.disc"); assertTrue(!!$Disc); assertTrue($Disc.$meta.isDeclared()); // my.module not yet created var $MyModule = bea.wlp.disc.Module.use("my.module") assertTrue(!!$MyModule); assertFalse($MyModule.$meta.isDeclared());This method always returns a module instance whether or not the instance could be resolved and loaded/created. That is, if no declaration for the module can be resolved, a module is still created and returned. If you are unsure that a module will be resolved when calling this method, you can check to see whether or not it was loaded/created by checking its
$meta.isDeclared()
value.string name
- The name of the module to usebea.wlp.disc.Module
-
A module for the requested name, whether or not a declaration for the module was created
Oracle Fusion Middleware Disc API Reference for Oracle WebLogic Portal
10g Release 3 (10.3.4)
E14257-04
Copyright © 2011, Oracle. All rights reserved.