Skip to content

Commit

Permalink
Refactored the factory functionality in the childlist into separate f…
Browse files Browse the repository at this point in the history
…unctions.
  • Loading branch information
specialunderwear committed Jun 26, 2011
1 parent 2bb40dc commit c14451c
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 87 deletions.
215 changes: 129 additions & 86 deletions src/dung/dung/dung/core/ChildList.as
Original file line number Diff line number Diff line change
Expand Up @@ -91,42 +91,6 @@ package dung.dung.dung.core
_dataProvider = dataProvider;
}

//---------------------------------------
// PROTECTED METHODS
//---------------------------------------

/**
* When the IChildList methods are accessed, the dataProvider must be parsed
* into DungVO objects, this will sort the object to be created by type.
* @private
*/

protected function prepareObjects():void
{
if (! _prepared) {
var currentNode:Node;

for each (var node:XML in _dataProvider) {
currentNode = nodeMap.resolve(node);

// create type dict array
if (_typeDict[currentNode.viewClass] === undefined)
_typeDict[currentNode.viewClass] = [];

// push new dung
_typeDict[currentNode.viewClass].push(new DungVO(
currentNode.viewClass,
currentNode.voClass,
node,
injector)
);
}
// we don't need the dataProvider anymore.
_dataProvider = null;
_prepared = true;
}
}

//---------------------------------------
// PUBLIC METHODS
//---------------------------------------
Expand Down Expand Up @@ -184,7 +148,7 @@ package dung.dung.dung.core
}
return allChildren;
}

/**
* Creates an array of objects of type <code>type</code> and returns them
* in an array.
Expand All @@ -200,63 +164,142 @@ package dung.dung.dung.core

// loop though dungs of certain type.
for each (var dung:DungVO in _typeDict[type]) {
// If we allready created the object, return existing instance.
if (! dung.viewInstance) {
// map properties
for each (var childNode:XML in dung.node.children()) {
childrenOfType.push(objectDefinedBy(dung));
}

// if the node is named whatever childListNodeName is set to,
// don't map that for the vo, it goes in the view.
if (childNode.name() == childListNodeName) {
continue;
}

// If the node is complex, bind as xml.
if (childNode.hasComplexContent()) {
injector.mapValue(XML, childNode, childNode.name());
} else { // if simple bind as String
injector.mapValue(String, childNode.text(), childNode.name())
}
}
return childrenOfType;
}

public function iteratorForType():void
{

}

//---------------------------------------
// PRIVATE & PROTECTED METHODS
//---------------------------------------

/**
* When the IChildList methods are accessed, the dataProvider must be parsed
* into DungVO objects, this will sort the objects to be created by type.
* @private
*/

protected function prepareObjects():void
{
if (! _prepared) {
var currentNode:Node;

// create value object defined in dung
if (dung.voClass is Class) {

// create value object with all values mapped above injected
// and map it because it will be injected into view.
// must use instantiate for the VO creation, because we are
// mapping the same Class with mapValue!!
injector.mapValue(dung.voClass, injector.instantiate(dung.voClass));
for each (var node:XML in _dataProvider) {
currentNode = nodeMap.resolve(node);

// create type dict array
if (_typeDict[currentNode.viewClass] === undefined)
_typeDict[currentNode.viewClass] = [];

// push new dung
_typeDict[currentNode.viewClass].push(new DungVO(
currentNode.viewClass,
currentNode.voClass,
node,
injector)
);
}
// we don't need the dataProvider anymore.
_dataProvider = null;
_prepared = true;
}
}

/**
* Maps the passed node in the injector and automatically selects the correct type.
*
* Simple nodes will be mapped as string, but XML nodes will be mapped as XML.
* @param childNode A single xml node that should be bound to a VO or view component.
* @private
*/

protected function mapAsStringOrXML(childNode:XML):void {
// If the node is complex, bind as xml.
if (childNode.hasComplexContent()) {
injector.mapValue(XML, childNode, childNode.name());
} else { // if simple bind as String
injector.mapValue(String, childNode.text(), childNode.name())
}
}

/**
* Creates a new child list from an <code>XMLList</code> and maps it for injection.
*
* The <code>ChildList</code> will have it's own injector, so it doesn't matter at all if
* you override mappings when inside a viewcomponent being constucted by the childlist.
* @param children The <code>XMLList</code> that contains all the data needed to construct the objects as defined in the <code>NodeMap</code>.
* @private
*/

protected function mapChildListFrom(children:XMLList):void
{
var childList:ChildList = new ChildList(children);

// create child injector so we can override mappings without
// messing up global mappings.
var childInjector:Injector = injector.createChildInjector();
// remap Injector to use the child injector here.
childInjector.mapValue(Injector, childInjector);
// inject injector and nodeMap, using the childInjector, which overrides the Injector mapping.
childInjector.injectInto(childList);

// map as IChildList to be injected into the view, with the normal injector.
injector.mapValue(IChildList, childList);
}

/**
* Returns the object/viewCompenent defined by the data in the <code>dung</code> parameter.
* Such an object is mapped in the <code>NodeMap</code>.
*
* If the object does not yet exist, it will be created.
* @param dung The value object that holds all data relevant for constructing an object mapped in <code>NodeMap</code>.
* @private
*/

protected function objectDefinedBy(dung:DungVO):Object
{
// If we allready created the object, return existing instance.
if (! dung.viewInstance) {
// map properties
for each (var childNode:XML in dung.node.children()) {

// if the node is named whatever childListNodeName is set to,
// don't map that for the vo, it goes in the view.
if (childNode.name() == childListNodeName) {
continue;
}

// if there are children, map an IChildList with that node
// as the dataProvider.
if (dung.node.hasOwnProperty(childListNodeName)) {

var children:XMLList = dung.node[childListNodeName].children();
var childList:ChildList = new ChildList(children);
mapAsStringOrXML(childNode);
}

// create chil injector so we can override mappings without
// messing up global mappings.
var childInjector:Injector = injector.createChildInjector();
// remap Injector to use the child injector here.
childInjector.mapValue(Injector, childInjector);
// inject injector and nodeMap, using the childInjector, which overrides the Injector mapping.
childInjector.injectInto(childList);

// map as IChildList to be injected into the view, with the normal injector.
injector.mapValue(IChildList, childList);
}
// create value object defined in dung
if (dung.voClass is Class) {

// create view object with all dependencies injected.
dung.viewInstance = injector.getInstance(dung.viewClass);
// create value object with all values mapped above injected
// and map it because it will be injected into view.
// must use instantiate for the VO creation, because we are
// mapping the same Class with mapValue!!
injector.mapValue(dung.voClass, injector.instantiate(dung.voClass));
}
childrenOfType.push(dung.viewInstance);

// if there are children, map an IChildList with that node
// as the dataProvider.
if (dung.node.hasOwnProperty(childListNodeName)) {

var children:XMLList = dung.node[childListNodeName].children();
mapChildListFrom(children);
}

// create view object with all dependencies injected.
dung.viewInstance = injector.getInstance(dung.viewClass);
}

return childrenOfType;
return dung.viewInstance;
}


}
}
2 changes: 1 addition & 1 deletion test/Runner.mxml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<![CDATA[
import org.flexunit.runner.FlexUnitCore;
import org.flexunit.listeners.UIListener;
import org.flexunit.listeners.CIListener;
/*import org.flexunit.listeners.CIListener;*/
import org.flexunit.internals.TraceListener;
import Suite;
Expand Down

0 comments on commit c14451c

Please sign in to comment.