text:
WebObjects/EOF/Using EOF/Caching and Freshness

Overview
There is a large overlap between the content about Memory Management and that of Caching and Freshness. Both should be read to fully understand how caching and memory management should play a part in your application design.

Freshness
One of the most frequently asked, and hard to figure out, questions related to WebObjects is: "My application keeps using old values from the database. How do I ensure it gets fresh data?"

Caveats and Warnings
Until someone else wants to write a chapter on exactly what's going on, and what the Enterprise Objects Framework is doing, that will remain unsaid on this site. But do understand that EOF is attempting to be efficient and not go to the database more often than necessary --- since a db transaction is relatively expensive. Every choice you make in this area is really a trade off between efficiency of your app and 'freshness' of your db values. Depending on the requirements of your app, different choices may be called for.

Some of these methods may also affect 'optimistic locking' behavior, depending on what optimistic locking behavior is necessary. A chapter on OptimisticLockingTechniques in WO/EOF would be welcome, because effectively using optimistic locking (taking account both of values changed by other app instance, and other sessions in the same instance) can be trickier than one would think.

Note: Some people have suggested that using EOFetchSpecification.setRefreshesRefetchedObjects and EOEditingContext.setDefaultFetchTimestampLag together will result in "unable to decrement snapshot" exceptions. Unfortunately, we really don't know anything more about this at this time.

But here are some ways to ensure 'freshness' of database values:

Recommended
EOEditingContext.setDefaultFetchTimestampLag(2);
 * In your Application constructor, call:

This means that every EOEditingContext, when created, will insist on getting data fresh from the database that's no more than two seconds older than the EOEditingContext itself. If the EOEditingContext was created at 1:23:00, and there are snapshots on record from BEFORE 1:22:58, those snapshots won't be used, instead a new fetch to the db will be done.

The argument '2' up there is the number of seconds prior to the creation of the EOEditingContext, that that EOEditingContext is willing to accept data from. You can use whatever value you want. Thinking about it, you'll realize that setting it to '0' as you might initially want to, your app will potentially make very many more db transactions when under very heavy load, without gaining much in 'freshness' of data, so a non-zero value is probably preferable.

[Oops, depending on which documentation you believe for which version, the argument may be in milliseconds instead of seconds. Beware].

[in WO5.2.3 the default is 3600000 so obviously is milliseconds]

[From the WO 5.3 documentation: public static void setDefaultFetchTimestampLag(long lag)

Sets the default timestamp lag for newly instantiated editing contexts to lag. The default lag is 3,600,000 milliseconds (one hour). When a new editing context is initialized, it is assigned a fetch timestamp equal to the current time less the default timestamp lag. Setting the lag to a large number might cause every new editing context to accept very old cached data. Setting the lag to too low a value might degrade performance due to excessive fetching. A negative lag value is treated as 0.]

Just to make this clear: the lag constitutes a fixed time, not a rolling time window. So it ONLY makes sure that any data in your newly created EC is not older than the time of creation minus the lag.

 * For some (or all!) EOFetchSpecifications, call setRefreshesRefetchedObjects(true) on it. This will mean that when you actually execute this fetch spec, and it goes and makes a transaction with the db, the values returned by the db will actually be used! Counter-intuitively, with the default value of refreshesRefetchedObjects==false, WO/EOF will sometimes ignore new values returned from the db in favor of older values in cached snapshots.

Note that combining both methods (setDefaultFetchTimestampLag and setRefreshesRefetchedObjects) is buggy. It is NOT RECOMMENDED. You will see decrementSnapshotCountForGlobalID errors if you do.

Note that if you use setPrefetchingRelationshipKeyPaths on the EOFetchSpecification, the relationships mentioned will be followed and their destinations fetched with this EOFetchSpecification as well, and the setRefreshesRefetchedObjects directive will apply to those destination objects too.

Not Sure Whether to Recommend

 * Some people use various methods to invalidate and/or refault their Enterprise Objects to ensure that the next access of those objects will result in fresh data. I am somewhat cautious of these methods, as the documentation is confusing and in some cases actually recommends against using them. Nonetheless, some people say they use them to good effect. I would recommend using other methods if you can. Maybe someone else wants to contribute more information?

Not Recommended

 * I would NOT recommend trying to use the databaseContextShouldUpdateCurrentSnapshot EODatabaseContext delegate method. The documentation implies you can implement this delegate method such that you will always get fresh data---sort of the effect of setRefreshesRefetchecObjects(true) on every single fetch spec without needing to do that on every single fetch spec. But in my own experience, attempting to do this caused various problems for EOF and various cryptic exceptions would occur. So I don't recommend it.

Jonathan Rochkind
In my own highly interactive and collaborative applications, I place a high value on freshness of data, over efficiency of my app. Implementing the setDefaultTimestampLag with a very low value, and calling setRefreshesRefetchedObjects(true) on the majority of fetches has resulted in acceptable and reasonably fresh data in my applications. I do not really think that the efficiency has suffered much either, but I haven't investigated it fully and I am not concerned with maximizing the number of requests-per-time-period that can be dispatched.

Michael Johnston
When an eo absolutely has to be fresh (example 1, choosing an hourly winner in a game that had > 500,000 games played per day at it's peak; example two an asynchronous event processor that receives events both over the wire and from internal threads) I use two step fetch-save with a lock column, with a polling loop with a random, increasing sleep time. This is multi-instance, multi-app-server safe but doesn't ever lock up a thread for more than .8 of a second running against oracle. So far. I tried using database locking, but it resulted in several-second lockups.

Jesse Barnum
I use this code on the detail view of my enterprise objects when I want to make sure that they are up-to-date. I'm not explicitly doing a fetch, I just invalidate the particular object plus it's related objects, and they will automatically be refaulted and fetched when the page is displayed. As shown in the code sample, you must explicitly invalidate related objects. If you can count on your users knowing when information is stale, then a nifty technique is to trigger this code if a user hits reload in their browser.

EOEditingContext ec = object.editingContext; NSMutableArray ids = new NSMutableArray; // Invalidate the object ids.addObject(ec.globalIDForObject(object)); // Invalidate a to-one related item ids.addObject(ec.globalIDForObject((EOEnterpriseObject)object.valueForKey("adreq"))); // Invalidate a to-many relationship Enumeration en = ((NSArray)object.valueForKey("correspondences")).objectEnumerator; while(en.hasMoreElements) ids.addObject(ec.globalIDForObject((EOEnterpriseObject)en.nextElement)); ec.invalidateObjectsWithGlobalIDs(ids);

Chuck Hill
The freshness methods described above are limited in that they only refresh the attributes and the to-one relationships (in other words, the data directly in the row). They do not refresh to-many relationships to show changes in which objects are in the relationship. This means that if objects are added to the relationship by another process (or in another Object Store) your code will not see them as being related. Conversely, if objects are removed from the relationship in another object store they will still appear in the relationship. I don't know why this is, perhaps it is simply a shortcoming of EOF. Refreshing to-many relationships is unfortunately expensive and laborious.

One solution is to invalidate the objects that you need to refresh to-many relationships for. While this works, it can be expensive in terms of processing and have unintended side effects if the invalidated objects had unsaved changes.

There is another option that I've used but which I'm still not 100% convinced has no bad side effects when edits are in progress. This method of refreshing to-many relationships works by setting the snapshot for the to-many relationship to null. It only works for one object and one relationship at a time so refreshing many objects can be a little annoying. The implementation is slightly convoluted as we need to get down to the EODatabase level.

Here is gist of the code which refreshes relationshipName on sourceObject:

sourceEditingContext = sourceObject.editingContext; EOEntity sourceObjectEntity = EOUtilities.entityForObject(sourceEditingContext, sourceObject); EOModel sourceObjectModel = sourceObjectEntity.model; EOGlobalID sourceGlobalID = sourceEditingContext.globalIDForObject(sourceObject); EODatabaseContext dbContext = EODatabaseContext.registeredDatabaseContextForModel(sourceObjectModel, sourceEditingContext); EODatabase database = dbContext.database; database.recordSnapshotForSourceGlobalID(null, sourceGlobalID, relationshipName);

Anjo Krank
While the method above will get fresh data the next time an EO is created you will have to perform an additional step to see the new data in an existing object:

Object o = eo.storedValueForKey(relationshipName); if(o instanceof EOFaulting) { EOFaulting toManyArray = (EOFaulting)o; if (!toManyArray.isFault) { EOFaulting tmpToManyArray = (EOFaulting)((EOObjectStoreCoordinator)ec.rootObjectStore).arrayFaultWithSourceGlobalID(gid, relationshipName, ec); toManyArray.turnIntoFault(tmpToManyArray.faultHandler); } } else { // we should check if the existing object is an array, too EOFaulting tmpToManyArray = (EOFaulting)((EOObjectStoreCoordinator)ec.rootObjectStore) .arrayFaultWithSourceGlobalID(gid, relationshipName, ec); eo.takeStoredValueForKey(tmpToManyArray, relationshipName); }

Pierre Bernard
It is my understanding that when pre-fetching relationships using a fetch specification set to refresh objects the relationship ought to be refreshed to. Unfortunately that is not what WebObjects 5.1 and 5.2 do. I have not yet tested later versions. In order to fix this, you will need to add the following to a subclass of EODatabaseContext:

/**  * Internal method that handles prefetching of to-many relationships. * // TBD This is a workaround to what looks like a bug in WO 5.1 & WO 5.2. * Remove as soon as it's no longer needed *  * The problem is that even refreshing fetches don't refresh the to-many * relationships they prefetch. */ public void _followToManyRelationshipWithFetchSpecification(EORelationship relationship,      EOFetchSpecification fetchspecification, NSArray objects,      EOEditingContext editingcontext) {   int count = objects.count; for (int i = 0; i < count; i++) { EOEnterpriseObject object = (EOEnterpriseObject) objects.objectAtIndex(i); EOGlobalID sourceGlobalID = editingcontext.globalIDForObject(object); String relationshipName = relationship.name; if (!object.isFault) { EOFaulting toManyArray = (EOFaulting) object.storedValueForKey(relationshipName); if (!toManyArray.isFault) { EOFaulting tmpToManyArray = (EOFaulting) arrayFaultWithSourceGlobalID(             sourceGlobalID, relationshipName, editingcontext); // Turn the existing array back into a fault by assigning it         // the fault handler of the newly created fault toManyArray.turnIntoFault(tmpToManyArray.faultHandler); }     }    }    super._followToManyRelationshipWithFetchSpecification(relationship, fetchspecification,        objects, editingcontext); }

EOEntity's Cache-In-Memory Setting
When you set Cache In Memory to true for an EOEntity, it tells EOF that you want it to try to always use an in-memory cache to store all instances of this entity. The first time that you fetch an object of the entity marked Cache In Memory, ALL instances of that entity will be fetched into memory. This is very useful for relatively static data (like enumerated type EO's, or other similar types of data that are infrequently modified in your application). Note that this is completely independent of EOF's normal snapshot caching, which will be in use regardless of the value of this setting. This setting is only used to determine if the ENTIRE dataset of your entity should be cached AT ALL TIMES. There are some very important implementation details that you should be aware of when you use this setting.

All behaviors described below MAY change from WO release to WO release and are not intrinsic requirements of the Cache In Memory feature, but are important considerations for anyone using the feature. All of these were verified to be true as of WebObjects 5.3:

The first is that Cache in Memory bypasses snapshot reference counting. Cache In Memory objects WILL NOT be released by EOF. In the end, this should not matter much, because you should not be using this flag on entities that have very large numbers of objects anyway.

On the performance front, be aware that Cache In Memory objects are indexed ONLY by EOGlobalID (primary key). If you are using an EOQualifier to find your objects (as opposed to traversing a to-one or to-many relationship that CONTAINS the object, which uses a primary key lookup), you will be doing a "full table scan" of your objects in memory. This is further reason to only use cache in memory on small cardinality entities. If you cache your 2 million row entity, it may likely be SLOWER to fetch EO's with an EOQualifier than if you just let the database take care of its business if the first place.

Another major performance detail of Cache In Memory is that if you make a change to ANY EO of the cached entity's type, ALL EO's of that type will be flushed from the cache and reloaded on the next access. This further supports the best practice of not using Cache In Memory for mutable EO's. If you have a Person EO set to cache-in-memory and you change the name of one Person, your entire cache will be dumped. The next time you fetch any person, the entire Person table will be reloaded. This can be catastrophic on a large series of changes (you can end up trashing the cache -- you save one EO, cache flushes, it then reloads the entire cache, you save the next one, the cache flushes, etc etc).

Lastly, there is a quirk of Cache In Memory EO's where the cache will not be used unless your EOFetchSpecification has setDeep(true) on it. If isDeep is false on your fetch specification, a normal database fetch will occur (negating the usefulness of your cache). This is also true of EOUtilities methods that use EOFetchSpecifications internally. Project Wonder provides alternative implementations of several of the common EOUtilities fetch methods that setDeep(true).

invalidateAllObjects BAD!
First, and most importantly, the concept of invalidation in EOF is about cache coherency with the database, NOT memory management.

Now, invalidation does have some side effects which can have positive influences on Java memory usage, but using it for this purpose is akin to using a 50# sledge hammer to drive those miniature picture hanging nails into the wall.

I strongly recommend you only use invalidation when you as the application programmer have external information which is inaccessible to EOF regarding changes in the state of the database. i.e. You just executed an arbitrary stored procedure which had side effects all over your table. Or you got an RMI message from another process saying it updated a row. Or it's Monday, 3am, and on Monday, 2am, your DBA's cron job always deletes everything in a "temp" table. Or you've found a bug in EOF (alas, it happens), and this is the only workaround.

As others have noted, invalidation forcefully nukes the snapshot in the EODatabase cache. This increases the cache miss rate, reducing the performance of your application. Depending on your pattern of firing faults, 10,000 rows which took only 1 fetch to retrieve initially might take 10,000 fetches to restore into the cache. BAD. Prefetching and batch faulting can ameliorate this a little bit. They're a lot better than naive faulting, actually, but nothing can replace doing the right fetch the first time. Nothing by several orders of magnitude.

Nuking the snapshot has a number of other deleterious consequences. This cache is a shared resource used by all the ECs in your application. When one EC annihilates the resource all the other ECs are depending on ... So, EOF posts notifications about invalidation. Whenever something is invalidated, all the ECs in the application are affected, and must process the notification. In a large web application with many concurrent sessions, this can be a lot of unnecessary chatter. Invalidation and its ensuing notifications are very stressful on concurrently operating threads. Invalidations are propagated throughout the entire application, even if they were initiated from a nested EC.

[More technically precise: throughout the entire EOF stack centered around the EOObjectStoreCoordinator. In 5.1, it is theoretically possible to have several of these stacks, each with their own cache and EOObjectStoreCoordinator. Most EOF notifications are not passed between ECs using different OSCs. In practice, for 5.1, this is the entire application.]

Refaulting is much kinder and gentler. It only affects the EC it is invoked upon, so it won't interfere with ECs for other users. It will decrement the reference count on the snapshot (which may or may not release the snapshot). It will break outbound references within that EC. And if the current snapshot in the cache is "fresh enough" as defined by that EC's fetchTimestamp, firing the fault will use the cache instead of generating another fetch. Refaulting does not post notifications (although if the snapshot is not fresh, firing the fault will cause a fetch which will post)

Okay, so all of that had to do with databases. This thread is really about memory management with EOF in Java, so back to the point.

What does ec.dispose do?
EOEditingContext does a lot of work. It has relationships to a number of other objects (including registering itself to receive notifications) and it is primarily responsible for maintaining a very large cyclic graph of objects (EOs). dispose tells the EC that it will never be used again, and it should perform as much clean up work as possible. This decrements snapshot reference counts, unregisters for various things, and breaks references. Depending on your JVM, this may or may not help the GC reclaim memory faster. If you don't invoke dispose, the EC's finalizer will. Most applications do not need to directly invoke dispose, but your mileage may vary.

dispose does not invoke any invalidate method.

For batch style EOF operations, the undo functionality is frequently overlooked as a source of problems (strong references). By default, EOF uses an unlimited undo/redo stack. If you are not going to use undo/redo, then you should seriously consider either setting the EC's undo manager to null, or performing removeAllActions on the EC's undo manager at logical checkpoints (like after saveChanges). The only downside to setting the EC's undo manager to null is that you will not be able to recover from validation exceptions. Depending on your batch operations, that may not be an issue. For a robust application, I would leave the undo manager, but use setLevelsOfUndo to keep the stack small, and invoke removeAllActions regularly.

For applications using EOF outside of an WebObjects application, some processing is left until the end of the current event. You may need to manually invoke eventEnded on the NSDelayedCallbackCenter. Inside a WebObjects application, this is done for you at the end of a request.

In WO 5.1, EOEditingContexts have strong references to all their registered EOs, and EOs have NO reference to their editing context. The implications for GC should be fairly obvious.

invalidate does not clear away the EO objects themselves. It will force the memory for the database cache to go away, but the EOs will still be in memory and retained by their EC ...

Avoiding unnecessary trips to the Database - some tips
When optimising for performance, we usually turn on EOAdaptorDebugEnabled (or it's NSLog equivalent). One of the things that comes up quite often, is how do you reduce / eliminate redundant database fetches?

EOF has a snapshot which stores dictionaries that represent objects that you request from the database. This is basically a application-wide cache. When you first fetch an object into an EOEditingContext, a dictionary is stored in the snapshot (with a timestamp lag used for expiring the dictionary). The editingcontext increments the reference count for that snapshot entry. When you dispose that editingcontext, the reference count in the snapshot for that entry is decremented. When the snapshot count for that dictionary falls to 0, at some point it is removed from the snapshot. So the next time you request that object again, it has to make a trip to the db to fetch it, even if it was quite fresh...

If you are using the session's defaultEditingContext (not recommended - but sometimes possible in legacy applications), be aware, that when the session terminates, it disposes its editingcontext. This means if you only have fetched a object into that editingcontext, it will likely be released from the snapshot. If you make a repeat fetch from another editingcontext for the same object, it will have to make a return trip to the db. I once came across a app that uses the session defaulteditingcontext via direct actions. When the directaction had finished creating its page, it terminated the session. Repeat calls for the same content, resulted in repeat trips to the db for the same data.

One way to get around this is to fetch EOs into an EOEditingcontext that has a longer life (one for example that survives across sessions), and use EOUtilities to create a localinstance of that object for any temporary editingcontext uses.

A second common problem faced by developers is the query by key value. For example, consider this fetch:

EOQualifier qualifier = EOQualifier.qualifierWithQualifierFormat ("lastName = 'Smith'", null); EOFetchSpecification fetchspec = new EOFetchSpecification("Person", qualifier, null); editingContext.objectsWithFetchSpecification(fetchSpec,editingContext);

This results in a request to the DB every time, even if it is the same objects always returned. The reason, is that it is not possible for EOF to know if the number of objects matching the query has changed.

If you are in a situation where you are querying on the primary key, or know that the objects returned aren't changing often, consider implementing a cache. Your cache should just store the EOGlobalID of the objects returned. That way, when you make this fetch in the future, you can check the key against your cache, and just return the EOGlobalIDs matching that key *without* a fetch to the DB.

Raw Rows
Raw Row results are never cached. If your application is using raw rows for its batch operations and is still having memory problems, then you need to evaluate your code. OptimizeIt or JProbe is definitely worth having. That's true even if you aren't doing raw row work.


text:
Esperanto/Appendix/Esperanto-English word list

In the Part of speech column there is an abbreviation indicating how the word is to be used. The following is a key, listing the abbreviations and explaining what they stand for:

Ŭ
In modern Esperanto, use of the letter Ŭ as a standalone consonant has fallen out of favour. It used to be common to use it for loanwords and foreign names like (for "Washington"), but the modern preference is.

The only modern use for Ŭ is in diphthongs.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
WebObjects/EOF/Using EOF/EOGenerator

Overview
If you've ever used EOModeler's Java source code generator, you know how much of a pain it can be when you make changes to your model objects and have to merge changes in later. One solution for this is to use EOGenerator, an application developed by Rubicode Software, which uses the Generation Gap pattern to create your Java files from your EOModels. EOGenerator produces TWO java files for each Entity rather than one. Take the example of a Person entity. The first java file is _Person.java, which contains all of the autogenerated methods. The second java file is Person.java, and Person extends _Person. The second file is where you place all of your customizations. Any time your model changes, only your _Xxx.java files are updated, and your customizations are left untouched. Additionally, EOGenerator allows for the creation of extensive custom templates for your files, which provides the ability to place convenience methods in your _Xxx.java files.

Advantages
There are several advantages to using EOGenerator over EOModeler's default Java file generation and merging with FileMerge.

 * EOGenerator uses the Generation Gap pattern, which provides a much cleaner separation of autogenerated vs customized code with no need to deal with merging at all. There are border cases with FileMerge that can cause you to deal with annoying conflicts.
 * EOGenerator uses the MiscMerge language for its templates. This allows you to extend the core templates with extensive customizations (see the EOGenerator Mods section below), better supporting your own custom development process and workflow.
 * As David LaBer put it, "all the cool kids use it - and we all know looking cool is the *most* important criteria".

How To Use It
Kieran Kelleher has writtten an Introduction to EOGenerator on his blog.

It's actually very simple to use. The quick start is:

 * Download and untar EOGenerator from the Rubicode site
 * Run the following command:

eogenerator -model /path/to/model/YourModel.eomodeld -destination /path/to/source/folder -subclassDestination /path/to/source/folder -templatedir /path/to/EOGenerator/templates -java -packagedirs

Voila. EOGenerator will spit out your Java files for you. Let's break down the commands you can pass in:

 * -define-EOGenericRecord, allows you to specify the _Person class's superclass. For instance, if you use Project Wonder, you would specify -define-EOGenericRecord er.extensions.ERXGenericRecord
 * -destination, the folder that _Person.java-style java files will be produced in (the non-editable files)
 * -java, produce java files
 * -javaTemplate, the name of the Java template to use inside of the template dir (_Person)
 * -model, Passes in the path of a .eomodeld you would like to generate Java files for. You can actually include multiple -model commands on the commandline
 * -packagedirs, produce package directory for any package statements defined in your Java files (not necessary if you don't specify package names on your entities. By the way, you should specify packages on your entities :) )
 * -refmodel, Passes in the path of an .eomodeld that is required for generating Java files, but that won't actually have Java files generated for it. For instance, you should -refmodel any prototypes, or any models in other frameworks that you depend on
 * -subclassDestination, the folder that Person.java-style java files will be produced in (the editable files)
 * -subclassJavaTemplate, the name of the Java subclass template to use inside of the template dir (Person)
 * -templatedir, the path to the folder that contains EOGenerator templates
 * -verbose, turn on verbose output

Zak Burke
Allow setting nulls on a to-one relationship (and turn it into a remove). Note, this is also included in Jonathan Rentzsch's templates.

public void save<$ToOneRelationship.name.initialCapitalString$>(<$ToOneRelationship.destinationEntity.referenceJavaClassName$> value) {   if (value == null) {     <$ToOneRelationship.destinationEntity.referenceJavaClassName$> object = <$ToOneRelationship.name$>; if (object != null) removeObjectFromBothSidesOfRelationshipWithKey(object, "<$ToOneRelationship.name$>"); }   else {     addObjectToBothSidesOfRelationshipWithKey(value, "<$ToOneRelationship.name$>"); } }

Chuck Hill
Return the list of changes between the current EO and the last committed version of the EO:

public NSDictionary changedProperties { NSDictionary commitedValues = editingContext.committedSnapshotForObject(this); return changesFromSnapshot(commitedValues); }

Jonathan Rentzsch
Jonathan Rentzsch has provided his base EOGenerator templates, which are a must-have:

http://rentzsch.com/share/eogenerator52templates.zip

Markus Ruggiero
Constants for all attributes and relationships. This allows compile time error checking in situations like addObjecttoBothSidesOfRelationshipWithKey(myObject, Person.TO_MANY_Children)

<$foreach attribute classAttributes.@reversedArray do$> public static final String ATTRIBUTE_<$attribute.name$> = "<$attribute.name$>";<$endforeach do$>

<$foreach ToOneRelationship classToOneRelationships.@reversedArray do$> public static final String TO_ONE_<$ToOneRelationship.name$> = "<$ToOneRelationship.name$>";<$endforeach do$>

<$foreach ToManyRelationship classToManyRelationships.@reversedArray do$> public static final String TO_MANY_<$ToManyRelationship.name$> = "<$ToManyRelationship.name$>";<$endforeach do$>

We also make heavy use of the user info dictionary on entity and attribute level. Allows to generate customized methods and what not. One example is booleans that are stored in the DB as strings with values "true" and "false".

<$if attribute.userInfo.usage == booleanFlag $>   // boolean accessors public void <$attribute.userInfo.setterName$>(boolean newBoolean) { set<$attribute.name.initialCapitalString$>(newBoolean ? "true" : "false"); }   public boolean <$attribute.userInfo.getterName$> { return "true".equals(<$attribute.name$>) ? true : false; }   // validation public String validate<$attribute.name.initialCapitalString$>(String newValue) { if ( newValue == null ) { return "false"; } else if ( !newValue.equals("true") && !newValue.equals("false") ) { String errorMessage = MessageHandler.format("INVALID_BOOLEAN_FLAG <$classNameWithoutPackage$>.<$attribute.name$>", null); throw new NSValidation.ValidationException(errorMessage); }     return newValue; } <$endif$>

Mike Schrag
Add a constant that represents the name of the entity so that you can refer to Person.ENTITY_NAME in fetches rather than the String (allows refactoring support in Eclipse):

public static final String ENTITY_NAME = "<$name$>";

Add a static factory method to your EO's ( Person createPerson(...) ) that shows you what required attributes and relationships are configured for you entity (attempts to provide a replacement "constructor" since EO constructors are empty):

public static <$classNameWithoutPackage$> create<$classNameWithoutPackage$>(EOEditingContext _editingContext<$foreach Attribute classAttributes.@sortedNameArray do$><$if !Attribute.allowsNull$>, <$Attribute.javaValueClassName$> _<$Attribute.name$><$endif$><$endforeach do$><$foreach ToOneRelationship classToOneRelationships.@sortedNameArray do$><$if ToOneRelationship.isMandatory$>, <$ToOneRelationship.destinationEntity.referenceJavaClassName$> _<$ToOneRelationship.name$><$endif$><$endforeach do$>) { <$classNameWithoutPackage$> eoObject = (<$classNameWithoutPackage$>)EOUtilities.createAndInsertInstance(_editingContext, <$GEN_PREFIX$><$classNameWithoutPackage$>.ENTITY_NAME);<$foreach Attribute classAttributes.@sortedNameArray do$><$if !Attribute.allowsNull$> eoObject.set<$Attribute.name.initialCapitalString$>(_<$Attribute.name$>);<$endif$><$endforeach do$><$foreach ToOneRelationship classToOneRelationships.@sortedNameArray do$><$if ToOneRelationship.isMandatory$> eoObject.set<$ToOneRelationship.name.initialCapitalString$>Relationship(_<$ToOneRelationship.name$>);<$endif$><$endforeach do$> return eoObject; }

Here's a little bitty fancier (read: nastier) version that also handles superclass mandatory attributes and fields (one level). It skips any attribute that is referenced in the restricting qualifier of your subclass (since you are probably going to set that in your awakeFromInsertion):

public static <$classNameWithoutPackage$> create<$classNameWithoutPackage$>(EOEditingContext editingContext<$foreach Attribute classAttributes.@sortedNameArray do$><$if !Attribute.allowsNull$>, <$Attribute.javaValueClassName$> <$Attribute.name$><$endif$><$endforeach do$><$foreach Attribute parentEntity.classAttributes.@sortedNameArray do$><$if !Attribute.allowsNull$><$set RestrictingQualifierKey = false$><$foreach QualifierKey restrictingQualifier.allQualifierKeys do$><$if Attribute.name = QualifierKey$><$set RestrictingQualifierKey = true$><$endif$><$endforeach do$><$if RestrictingQualifierKey = false$>, <$Attribute.javaValueClassName$> <$Attribute.name$><$endif$><$endif$><$endforeach do$><$foreach ToOneRelationship classToOneRelationships.@sortedNameArray do$><$if ToOneRelationship.isMandatory$>, <$ToOneRelationship.destinationEntity.referenceJavaClassName$> <$ToOneRelationship.name$><$endif$><$endforeach do$><$foreach ToOneRelationship parentEntity.classToOneRelationships.@sortedNameArray do$><$if ToOneRelationship.isMandatory$>, <$ToOneRelationship.destinationEntity.referenceJavaClassName$> <$ToOneRelationship.name$><$endif$><$endforeach do$>) { <$classNameWithoutPackage$> eoObject = (<$classNameWithoutPackage$>)EOUtilities.createAndInsertInstance(editingContext, <$GEN_PREFIX$><$classNameWithoutPackage$>.ENTITY_NAME);<$foreach Attribute classAttributes.@sortedNameArray do$><$if !Attribute.allowsNull$> eoObject.set<$Attribute.name.initialCapitalString$>(<$Attribute.name$>);<$endif$><$endforeach do$><$foreach ToOneRelationship classToOneRelationships.@sortedNameArray do$><$if ToOneRelationship.isMandatory$> eoObject.set<$ToOneRelationship.name.initialCapitalString$>Relationship(<$ToOneRelationship.name$>);<$endif$><$endforeach do$><$foreach Attribute parentEntity.classAttributes.@sortedNameArray do$><$if !Attribute.allowsNull$><$set RestrictingQualifierKey = false$><$foreach QualifierKey restrictingQualifier.allQualifierKeys do$><$if Attribute.name = QualifierKey$><$set RestrictingQualifierKey = true$><$endif$><$endforeach do$><$if RestrictingQualifierKey = false$> eoObject.set<$Attribute.name.initialCapitalString$>(<$Attribute.name$>);<$endif$><$endif$><$endforeach do$><$foreach ToOneRelationship parentEntity.classToOneRelationships.@sortedNameArray do$><$if ToOneRelationship.isMandatory$> eoObject.set<$ToOneRelationship.name.initialCapitalString$>Relationship(<$ToOneRelationship.name$>);<$endif$><$endforeach do$> return eoObject; }

Add a bunch of convience fetch methods (fetchAllPersons, fetchRequiredPerson, and other variants). It's not smart about pluralization, so it's just going to put an "s" on the end of the entity name:

public static NSArray fetchAll<$classNameWithoutPackage$>s(EOEditingContext _editingContext) { return <$GEN_PREFIX$><$classNameWithoutPackage$>.fetchAll<$classNameWithoutPackage$>s(_editingContext, null); }

public static NSArray fetchAll<$classNameWithoutPackage$>s(EOEditingContext _editingContext, NSArray _sortOrderings) { return <$GEN_PREFIX$><$classNameWithoutPackage$>.fetch<$classNameWithoutPackage$>s(_editingContext, null, _sortOrderings); }

public static NSArray fetch<$classNameWithoutPackage$>s(EOEditingContext _editingContext, EOQualifier _qualifier, NSArray _sortOrderings) { EOFetchSpecification fetchSpec = new EOFetchSpecification(<$GEN_PREFIX$><$classNameWithoutPackage$>.ENTITY_NAME, _qualifier, _sortOrderings); fetchSpec.setIsDeep(true); NSArray eoObjects = _editingContext.objectsWithFetchSpecification(fetchSpec); return eoObjects; }

public static <$classNameWithoutPackage$> fetch<$classNameWithoutPackage$>(EOEditingContext _editingContext, String _keyName, Object _value) { return <$GEN_PREFIX$><$classNameWithoutPackage$>.fetch<$classNameWithoutPackage$>(_editingContext, new EOKeyValueQualifier(_keyName, EOQualifier.QualifierOperatorEqual, _value)); }

public static <$classNameWithoutPackage$> fetch<$classNameWithoutPackage$>(EOEditingContext _editingContext, EOQualifier _qualifier) { NSArray eoObjects = <$GEN_PREFIX$><$classNameWithoutPackage$>.fetch<$classNameWithoutPackage$>s(_editingContext, _qualifier, null); <$classNameWithoutPackage$> eoObject; int count = eoObjects.count; if (count == 0) { eoObject = null; }   else if (count == 1) { eoObject = (<$classNameWithoutPackage$>)eoObjects.objectAtIndex(0); }   else { throw new IllegalStateException("There was more than one <$classNameWithoutPackage$> that matched the qualifier '" + _qualifier + "'."); }   return eoObject; } public static <$classNameWithoutPackage$> fetchRequired<$classNameWithoutPackage$>(EOEditingContext _editingContext, String _keyName, Object _value) { return <$GEN_PREFIX$><$classNameWithoutPackage$>.fetchRequired<$classNameWithoutPackage$>(_editingContext, new EOKeyValueQualifier(_keyName, EOQualifier.QualifierOperatorEqual, _value)); }

public static <$classNameWithoutPackage$> fetchRequired<$classNameWithoutPackage$>(EOEditingContext _editingContext, EOQualifier _qualifier) { <$classNameWithoutPackage$> eoObject = <$GEN_PREFIX$><$classNameWithoutPackage$>.fetch<$classNameWithoutPackage$>(_editingContext, _qualifier); if (eoObject == null) { throw new NoSuchElementException("There was no <$classNameWithoutPackage$> that matched the qualifier '" + _qualifier + "'."); }   return eoObject; }

Add methods for getting local instances of EO's. The static one is handy if you have a reference to an EO that might be null (it does a null check first):

public <$classNameWithoutPackage$> localInstanceOf<$classNameWithoutPackage$>(EOEditingContext _editingContext) { return (<$classNameWithoutPackage$>)EOUtilities.localInstanceOfObject(_editingContext, this); }

public static <$classNameWithoutPackage$> localInstanceOf<$classNameWithoutPackage$>(EOEditingContext _editingContext, <$classNameWithoutPackage$> _eo) { return (_eo == null) ? null : (<$classNameWithoutPackage$>)EOUtilities.localInstanceOfObject(_editingContext, _eo); }

If you've ever wanted to be able to qualify a toMany relationship on your EO's, but sometimes you want to fetch them w/ a fetch spec, and sometimes you want to filter in-memory, you can use the following:

<$if !ToManyRelationship.inverseRelationship$> public NSArray <$ToManyRelationship.name$>(EOQualifier qualifier) { return <$ToManyRelationship.name$>(qualifier, null); } <$endif$> <$if ToManyRelationship.inverseRelationship$> public NSArray <$ToManyRelationship.name$>(EOQualifier qualifier) { return <$ToManyRelationship.name$>(qualifier, null, false); } 	public NSArray <$ToManyRelationship.name$>(EOQualifier qualifier, boolean fetch) { return <$ToManyRelationship.name$>(qualifier, null, fetch); } <$endif$> public NSArray <$ToManyRelationship.name$>(EOQualifier qualifier, NSArray sortOrderings<$if ToManyRelationship.inverseRelationship$>, boolean fetch<$endif$>) { NSArray results; <$if ToManyRelationship.inverseRelationship$> if (fetch) { EOQualifier fullQualifier; EOQualifier inverseQualifier = new EOKeyValueQualifier(<$ToManyRelationship.destination.className$>.<$ToManyRelationship.inverseRelationship.name.uppercaseUnderbarString$>_KEY, EOQualifier.QualifierOperatorEqual, this); if (qualifier == null) { fullQualifier = inverseQualifier; } 			else { NSMutableArray qualifiers = new NSMutableArray; qualifiers.addObject(qualifier); qualifiers.addObject(inverseQualifier); fullQualifier = new EOAndQualifier(qualifiers); } 			results = <$ToManyRelationship.destination.className$>.fetch<$ToManyRelationship.destination.name$>s(editingContext, fullQualifier, sortOrderings); } 		else { <$endif$> results = <$ToManyRelationship.name$>; if (qualifier != null) { results = EOQualifier.filteredArrayWithQualifier(results, qualifier); } 			if (sortOrderings != null) { results = EOSortOrdering.sortedArrayUsingKeyOrderArray(results, sortOrderings); } <$if ToManyRelationship.inverseRelationship$> } <$endif$> return results; }

John Huss
I wanted to share a wonderful bit of knowledge I learned today. If you're using Java 1.5 you can add @SuppressWarnings("all") to the template for your _EO base classes and eliminate annoying compiler messages (usually uneeded import statements).

@SuppressWarnings("all") public class _Invoice extends ERXGenericRecord { }

Guido Neitzer
Create awakeFromInsertion and awakeFromFetch in your EOGenerator template as a method stub that only calls super and has a comment for "initialize your object here ...". You only have to put in the code at that place and can't possibly forget to call super. Here is an example:

/**     * Initialization of the instance while inserting it into an editing context */    public void awakeFromInsertion (EOEditingContext editingContext) { super.awakeFromInsertion (editingContext); // initialize your object here }

This is from my JavaSubclassSourceTemplate.eotemplate

title: WebObjects/EOF/Using EOF/EOGenerator


text:
WebObjects/EOF/Using EOF/Validation

Overview
http://developer.apple.com/documentation/WebObjects/Enterprise_Objects/BusinessLogic/chapter_4_section_4.html

mmalcolm's StepWise article entitled "Data validation with WebObjects 5": http://www.stepwise.com/Articles/Technical/2001-06-13.01.html

Jerry W. Walker
WO and EOF have an incredible array of validation mechanisms. Here are some notes you might find helpful:

 * User interface:
 * prevent/discourage user from entering inappropriate data
 * Formatters:
 * formatting
 * Only accepts data with valid format
 * type coercion
 * bad type raises exception
 * simple validation
 * raises exception and ignores value
 * must be different from current value or not assigned
 * WOComponent's validationFailedWithException(Throwable t, Object value, String keyPath)
 * Called when an Enterprise Object or formatter failed validation during an assignment.
 * The default implementation ignores the error.
 * Subclassers can override to resolve the error.
 * Model
 * attribute constraints
 * checks for:
 * allows null
 * string length
 * numeric precision
 * relationship integrity
 * checks these before going to DB
 * relationship integrity constraints
 * optionality
 * for both to-one & to-many
 * delete rule
 * if source deleted, then what
 * ownership, owned object is:
 * deleted if relationship broken
 * created if relationship added
 * delete rules (if user tries to delete relationship source):
 * cascade - delete all destination objects too
 * nullify - nullify back references
 * deny - prohibit delete if there are destination objects
 * nothing - delete and ignore destination objects
 * EO
 * property-level (or key-level) validation
 * called when a value changes
 * default methods in superclass check model based constraints
 * can be overridden for custom validation
 * called BEFORE EO's properties have changed
 * validation methods throw exception on failure
 * validateValueForKey("weight") triggers: public validateWeight(Object newWeight) throws NSValidation.ValidationException {
 * object-level validation
 * called when saving insert/delete/update changes
 * public void validateForInsert throws NSValidation.ValidationException
 * public void validateForUpdate throws NSValidation.ValidationException
 * public void validateForDelete throws NSValidation.ValidationException
 * all above in superclass by default call:
 * public void validateForSave throws NSValidation.ValidationException
 * super's implementation calls key-level validation
 * called AFTER EO's properties have changed
 * validation performed when:
 * form values are pushed into EO attributes through bindings
 * saving changes in the editing context
 * called programmatically

Changing an EO after Validation
Question: I would like to make a change to an EO after it has validated but before it has saved to the graph/DB. Is this possible?

Chuck Hill
You don't want to do this, you should not want to do this, and the frameworks will fight you tooth and nail if you try. validateForSave is the gatekeeper for the object store. Its job is to ensure that nothing gets saved unless it has validated it. Modifying the object graph after validateForSave finished would violate its very reason for existence.

As I see it, you have three options:
 * 1) Do it in the component
 * 2) Do it in the EO
 * 3) Do it in another object

I agree that the component might not be the place to do this and I also don't like to have my EOs call saveChanges. You might want to think of the third option, having some sort of ShiftManager object that is responsible for overseeing the closing and opening of shifts. It can provide information to the page on what is valid and what options there are and it can handle the two phase save.

Before I did that, I would consider some other options. Here are some ideas that might spark some of your own:

 * Defer resetting the cash box balance until the _start_ of the next shift. The last time I was a cashier (thankfully long ago) that is how it worked.  You handed in your cash tray and discrepancy notes, the boss shook his head and muttered.  He then recorded all that information.  For the next worker, he then restocked the cash drawer.  Often that did not happen until the next morning.

 * Add a method to Shift like this:

public void close throws ValidationException { validateForSave; cashBox.resetBalance; }

and in your component

try { shift.close; ec.saveChanges; } catch (ValidationException v) { // do the right thing } catch (EOGeneralAdaptorException e) { // do the right thing }

 * I had another one, but it has slipped my mind. :-)

title: WebObjects/EOF/Using EOF/Validation


text:
WebObjects/EOF/Using EOF/Concurrency

Brendan Duddridge
We're trying to fix some of our editing context issues we've been having and we're thinking of creating an architecture like the following:

Note first... we have WOAllowsConcurrentRequestHandling = true

 * Create a ThreadLocal to lazily instantiate an EOEditingContext with it's own new EOObjectStoreCoordinator
 * When a direct action request comes in, ask the ThreadLocal for it's editing context in performActionNamed.
 * Lock the ThreadLocal's editingContext in a try block.
 * Process the request and call generateResponse.
 * unlock the ThreadLocal's editing context in the finally block.
 * Return the response.

So what we'll end up with is a separate connection to the database for each worker thread. So we could potentially have many connections to the database. As worker threads are finalized, we'll close the connection to the database. We may end up using the JavaPoolingJDBCAdaptor to limit the connections to the database. But this would provide for good multi-threaded concurrent access to our application.

Does anyone foresee any undesired issues with this approach? I've never seen this approach postulated in the WO dev archives. One of my developers suggested this approach and I thought it sounded good, so I'd see what others thought first before implementing it. We'd be happy to share our findings and code if it works out well.

David LaBer
I've worked on an application architected this way, and was not happy. Just so you know where I'm coming from :-)

A couple of thoughts:

 * You will have multiple snapshots - one for each of your EOObjectStoreCoordinators. They will not be synchronized. So, you will loose optimistic locking and will have to either implement some kind of inter-stack notification or ensure fresh data by fetching often (sacrificing caching).
 * You will complicate your Application architecture making it harder to maintain, harder to understand, and harder to hand off to other WebObjects developers.
 * Do you really require multiple concurrent connections to your database for all of your queries? I can understand doing this for queries that profiling has identified as being bottlenecks. However, I'd probably look at other optimizations if possible (ie: shifting as much load as possible to SQL server).
 * Multiple instances (although more costly in hardware) will be more cleaner and more maintainable (even *with* implementing a change notification architecture).

As always these opinions are my own, and are open to discussion :-)

Chuck Hill
Locking-wise, I think that will be fine. Memory usage is the most likely issue that you will run into. The extra EOF stacks will consume more memory than a single stack implementation. I'm assuming that this is OK for your purposes, that the requests will not be fetching in a lot of data. If they do fetch a lot of data, or you do end up with many worker threads, you may find that you apps runs out of memory rather quickly. You might want to consider some sort of round robin usage of a set of stacks stored at the app level. This will at least somewhat limit memory usage. You may also get more optimistic locking failures at the database like this. If you are running multiple instances (which I recall is the case) you have to handle these anyway so that becomes a non-issue.

title: WebObjects/EOF/Using EOF/Concurrency


text:
WebObjects/EOF/Using EOF/Optimistic Locking

Overview
Note that this section covers the locking strategy EOF uses at the databases layer as opposed to EOEditingContext locking which happens much higher in the stack. For information on EOEditingContext locking, please see Context and Database Locking.

There are two primary styles of locking that can be used with a database API: pessimistic and optimisic. Pessimistic locking actively prevents two participants from updating the same row by explicitly locking access to it when the first participant begins to make a change (effectively locking others out until the change is complete). Optimistic locking allows participants to make changes to the resources without an explicit lock, assuming success, and fails only if the changes actually cause a conflict. EOF takes the optimistic approach when locking data.

As an example of how optimistic locking in EOF works, assume you have a Person EO with the PersonID 123, first name "Bob", and last name "Roberts". If you change the first name to "Robert" and saveChanges on your editing context, you would see the following SQL sent to your database:

update Person set FirstName = 'Robert' where PersonID = 123 and FirstName = 'Bob' and LastName = 'Roberts'

The key to optimistic locking is the where clause on the update. If you were the only one to change this EO, this update command would return that 1 row was updated, which EOF expected as a successful result. However, assume another user was editing at the same time and changed Bob's last name to 'Wilson'. Rerun the above query, and you'd find that ZERO rows would be updated, because the LastName = 'Roberts' clause in the qualifier would not match (the last name in the database is now 'Wilson'). The result of this situation in EOF would be an optimistic locking exception thrown from saveChanges.

When you run EOModeler, you may have noticed the column in the Attributes view with the lock icon in its heading. This column defines which attributes of your entity will be used for optimistic locking. All attributes that are checked will appear in the 'where' clause of an update to your object. Note that all locked columns are checked on an update, not just the columns of the attributes that were modified.

A common problem people run into with EOF is the use of "imprecise" types as locking columns. By imprecise types, I am referring to types whose precision may change during the lifetime of an EO even when it has not been modified by a user. The most notorious data types for this problem are dates and floating point types. It is very common that the precision of Java for floating point types does not match the precision of your database. The result of this is that when EOF brings the float out of the database, puts it in a Float, and places it in your snapshost, the very act of loading it into a Float changes its value. This can often cause very strange problems with locking where you will end up with optimistic locking failures even when there was no concurrent update. The recommendation for this case is to uncheck the Lock column on attributes with date and floating point types if your database is causing problems. The obvious downside of this is that these fields will not be elligible for detection of optimistic locking failures (that is, "last write wins" for that column and your program won't be notified of a collision of updates).

mmalcolm gave a presentation at O'Reilly's 2002 Mac OS X conference titled "A Lack of Conflicts in EOF, or 'Hey Mom, Someone Overwrote My Data!'" and the slides are available at http://conferences.oreillynet.com/presentations/macosx02/crawford_eoconflicts.pdf

Optimistic Locking and Performance
There have been several threads of discussion about the additional database server load with optimistic locking (as the database must verify all of the locked column values prior to an update).

In January 2006, a benchmark was run on WebObjects 5.3 with the following scenario:

This was run on the latest version of FrontBase as of Jan 2006 on an Intel iMac with WO 5.3:

Two identical entities were created which have 3 ints, 3 booleans, 3 strings, and 3 dates as properties, but one locks all attrs and one locks none. 10,000 instances of each were inserted into the db, followed by an update of the same attribute for each with the same change in value.

For the entity with all columns locked, it took 25753ms to complete the run. For the entity with no columns locked, it took 7111ms to complete the run. It was 3.6x faster to not lock any columns in this example, with this database, on this hardware.

Modifying the scenario to lock on one date column results in the entity with the lock taking 25574ms to complete the run, while the unlocked entity took 14125ms to complete, for a speed difference of 1.81x.

It really depends on the type of application you have. If you're doing 100,000 updates, you probably care that it takes an extra 190 seconds (or whatever the time differential might be) to perform the update. But if you're just periodically updating "normal" datasets, it may not matter that it takes an extra few milliseconds. The trade-off, obviously, is data integrity.

Database benchmarks are never simple, and often don't apply across databases of different vendors, so take these results with a grain of salt. Always profile your application before you make large sacrifices in functionality.

Kieran Kelleher
Here is the easiest way to trigger it.

 * 1) Pull an object into an edit page in WO.
 * 2) Now go in the back door to the database using command line or some other tool independent of WebObjects and directly edit some attributes (that have the little lock ON in EOModel) of the databases record that represents the object.
 * 3) Now submit your object editing page
 * 4) An optimistic locking exception will now get thrown because the original snapshot that was read in from the database before you edited the object is different to the values in the database now.

Let's say we have a table with a primary key 'oid' and one optimistically locked attribute named 'field1'. Now we fetch the object with primary key 273 and its DB value is "original".

Now let's say you change the field1 to be "new" in WO in a form and BEFORE you submit, let's say you changed the DB field1 value directly to "changed", then when you submit, EOF generates SQL something like: UPDATE table T1 set field1 = "new" where oid = 273 and field1 = "original";

.... and this update will FAIL because there is NO record having oid = 273 and field1 = "original". There IS a record with oid = 273 and field1 = "changed", but WO does not know that because some other application has changed it.

If you log out the SQL while changing you will see that optimistic locking effects the WHERE part of all the UPDATE statements that are generated.


text:
WebObjects/EOF/Using EOF/Fetch Limits

Overview
By default, when you use an EOFetchSpecification, it will fetch all of the EOs that match its EOQualifier. However, often the user interface you will be using is paginated, and there are large performance wins by instead loading your results in pages.

Core WO
EOFetchSpecification provides a setFetchLimit(int) method, but it does not directly support pagination, rather it will simply stop returning results after the number specified. This is useful for a cut-and-run approach to querying, but if you need to provide multiple pages of results, you will likely need to look elsewhere.

Project Wonder
Project Wonder provides several facilities for addressing this problem:

 * ERXEOControlUtilities.objectsInRange(ec, fs, start, end) for Postgres, MySQL, and Frontbase
 * ERXBatchingDisplayGroup
 * ERXRecursiveBatchFetching

WODisplayGroup

title: WebObjects/EOF/Using EOF/Fetch Limits


text:
User:Some P. Erson

This is my Wikibooks page. For my general page, go here.

title: User:Some P. Erson


text:
French/Lessons/Introductory/Exercises

Grammar
Exercises

title: French/Lessons/Introductory/Exercises


text:
User talk:24.128.205.16

The previous version gave three "forms" of Zorn's Lemma, marking one as "most popular." Since I have only heard the "popular" form actually called "Zorn's Lemma", and it seems confusing at any rate to use one name for quite three distinct propositions (one of which already has a well-known name of its own), I have reorganized.

More seriously, the previous proofs of equivalence had serious flaws. I have corrected the proofs and I hope increased the readability too.

title: User talk:24.128.205.16


text:
French/Lessons/Level one/Exercises

Grammar
Exercises

title: French/Lessons/Level one/Exercises


text:
Talk:Sicilian

Untitled

 * Someone has dumped a heap of Italian on a page that is meant to be about Sicilian, and some of it is incorrect to boot.

the italian alphabet is not exactly the same as english in fact there are some letters that dont exist some of those words are z,k,j,and some more.

hello:bonjorno

goodbye:erivedeci

what is the wheather:che tempo fa oggi

how old are you: quantaniai

whats your name: come di ciami come here: venequa

listen here: sente cha

Its cold:fa freddo

its warm:fa caldo

blue:azzuro

purple:viola

pink:rossa

red:rosso

verde:green

arrangione:orange

marrone:brown

white:bianco

yellow:giallo

eat:mangga

1:uno

2:due

3:tre

4:quatro

5:chinque

6:sei

7:sette

8:otto

9:nove

10:dieci

11:undeci

12:dodeci

13:tredici

14:qudodici

15:quindeci

16:sedeci

17:dicesette

18:diceotto

19:dicenove

20:venti

have fun with your italian for more info go to www.italianlearning.com or for learning italian games go to www.languages online.com

title: Talk:Sicilian


text:
French/Lessons/Level two/Exercises

Grammar
Exercises

title: French/Lessons/Level two/Exercises


text:
French/Lessons/Level three/Exercises

Grammar
Exercises

title: French/Lessons/Level three/Exercises


text:
6502 Assembly

This book is a guide to the 6502 Assembly language. This book will teach the different memory addressing modes and instructions of the 8-bit 6502 processor.

You might want to learn 6502 assembly language programming if you want to do Atari 2600/8-bit family/5200/7800 Programming, Commodore PET/VIC/64/128 Programming, Acorn 8 Bit Programming, Apple I/II Programming, NES Programming or Super NES Programming.

Syntax
Syntax will vary between assemblers - this book will use the following syntax throughout:

Memory layout
16-bit values are stored in memory in little-endian, so the least significant byte is stored before the most significant. E.g. if address  contains   and address   contains , reading a two-byte value from   will result in.

Signed integers are in two's complement and can represent values from -128 to +127. Bit 7 is set if the integer is negative.

The 6502's program counter is 16 bits wide, so up to 2^16 (65536) bytes of memory are addressable. Certain regions of memory are reserved for particular purposes:

Memory Addressing Modes
Each instruction uses one of thirteen memory addressing modes, which determines the operand of the instruction. An example is provided for each.

Accumulator: A
The Accumulator is implied as the operand, so no address needs to be specified.

 Example

Using the ASL (Arithmetic Shift Left) instruction with no operands, the Accumulator is always the value being shifted left.

ASL

Implied: i
The operand is implied, so it does not need to be specified.

 Example

The operands being implied here are X, the source of the transfer, and A, the destination of the transfer.

TXA

Immediate: #
The operand is used directly to perform the computation.

 Example

The value  is loaded into the Accumulator.

LDA #$22

Absolute: a
A full 16-bit address is specified and the byte at that address is used to perform the computation.

 Example

The value  at address   is loaded into the X register.

LDX $D010

Zero Page: zp
A single byte specifies an address in the first page of memory, also known as the zero page, and the byte at that address is used to perform the computation.

 Example

The value at address  is loaded into the Y register.

LDY $02

Relative: r
The offset specified is added to the current address stored in the Program Counter (PC). Offsets can range from -128 to +127.

 Example

The offset  is added to the address in the Program Counter (say  ). The destination of the branch (if taken) will be.

BPL $2D

Absolute Indirect: (a)
The little-endian two-byte value stored at the specified address is used to perform the computation. Only used by the  instruction.

 Example

The addresses  and   are read, returning   and   respectively. The address  is then jumped to.

JMP ($A001)

Absolute Indexed with X: a,x
The value in  is added to the specified address for a sum address. The value at the sum address is used to perform the computation.

 Example

The value  in   is added to   for a sum of. The value  at address   is used to perform the add with carry ( ) operation.

ADC $C001,X

Absolute Indexed with Y: a,y
The value in  is added to the specified address for a sum address. The value at the sum address is used to perform the computation.

 Example

The value  in   is added to   for a sum of. The value  at address   is incremented ( ) and   is written back to.

INC $F001,Y

Zero Page Indexed with X: zp,x
The value in  is added to the specified zero page address for a sum address. The value at the sum address is used to perform the computation.

 Example

The value  in   is added to   for a sum of. The value  at address   is loaded into the Accumulator.

LDA $01,X

Zero Page Indexed with Y: zp,y
The value in  is added to the specified zero page address for a sum address. The value at the sum address is used to perform the computation.

 Example

The value  in   is added to   for a sum of. The value  at address   is loaded into the Accumulator.

LDA $01,Y

Zero Page Indexed Indirect: (zp,x)
The value in  is added to the specified zero page address for a sum address. The little-endian address stored at the two-byte pair of sum address (LSB) and sum address plus one (MSB) is loaded and the value at that address is used to perform the computation.

 Example

The value  in   is added to   for a sum of. The address  at addresses   and   will be where the value   in the Accumulator is stored.

STA ($15,X)

Zero Page Indirect Indexed with Y: (zp),y
The value in  is added to the address at the little-endian address stored at the two-byte pair of the specified address (LSB) and the specified address plus one (MSB). The value at the sum address is used to perform the computation. Indeed addressing mode actually repeats exactly the Accumulator register's digits.

 Example

The value  in   is added to the address   at addresses   and   for a sum of. The Accumulator is then exclusive ORed with the value  at.

EOR ($2A),Y

Instructions
These are the instructions for the 6502 processor including an ASCII visual, a list of affected flags, and a table of opcodes for acceptable addressing modes.

Compare and Test Bit
The Negative (N), Zero (Z), and Carry (C) status flags are used for conditional (branch) instructions.

All Compare instructions affect flags in the same way:

 Test Bits in Memory with Accumulator:

A & M

Flags: N = M7, V = M6, Z

Stack
The processor status is stored as a single byte with the following flags bits from high to low: NV--DIZC.

Subroutines and Jump
 Jump to New Location:

Jump to new location by changing the value of the program counter.

Warning: When used with the absolute indirect addressing mode, a hardware bug can result in unexpected behavior when the specified address is. E.g.  will read the low byte from   and the high byte from , instead of reading the high byte from   as one would expect. This is due to an overflow in the lower byte of the indirect address not being carried into the upper byte.

Flags: none

 Jump to New Location Saving Return Address:

Jumps to a subroutine

The address before the next instruction (PC - 1) is pushed onto the stack: first the upper byte followed by the lower byte. As the stack grows backwards, the return address is therefore stored as a little-endian number in memory. PC is set to the target address.

Flags: none

 Return from Subroutine:

Return from a subroutine to the point where it called with.

The return address is popped from the stack (low byte first, then high byte). The return address is incremented and stored in PC.

Flags: none

 Return from Interrupt:

Return from an interrupt.

P is popped from the stack. PC is popped from the stack.

Flags: all

Miscellaneous
 Break:

Force an Interrupt

Flags: B = 1, I = 1

 No Operation:

No Operation

Flags: none

title: 6502 Assembly


text:
Cookbook:Soufflé

A soufflé is a light, fluffy baked dish made with egg yolks and beaten egg whites combined with various other ingredients and served as a main dish or sweetened as a dessert. The word soufflé is the past participle of the French verb souffler which means "to blow up" or more loosely "puff up" - an apt description of what happens to this combination of custard and egg whites.

Every soufflé is made from 2 basic components; a flavoured sauce or purée base, and beaten egg whites. The base provides the flavor and some structural support, and the whites provide the "lift". Common varieties include cheese, chocolate, and lemon (the last two made as desserts, with a good deal of sugar).

Soufflé is considered a great delicacy. When it comes out of the oven, a soufflé is generally very large and fluffy, and will 'fall' after 20 or 30 minutes (as risen dough does). For best results, soufflé should be eaten quickly, while hot and before it falls.

Soufflé can be made in containers of all shapes and sizes, but the best are tall cylindrical containers which conduct heat well. It is traditional to make soufflé in "soufflé cups" or ramekins.

Since a soufflé has a delicate structure, making one requires cleanliness and precision. The bowl and beaters should be perfectly clean, and the egg whites should be at room temperature before beating. The whites should be beaten until they are smooth, shiny and hold a soft peak; if the whites appear grainy or clump together, another egg white can be added and the mixture should be beaten again. Always cook soufflés on the bottom rack of the oven or the resulting soufflé may have a leathery top crust.

RECIPE: The most commonly used recipe for soufflé is to use 1 quart of heavy cream per 11 eggs. after pouring the mixture into a heavy baking dish, sprinkle croûtons, shredded cheese, and salt and pepper into the mixture. bake in a 325F oven for one hour or until you can toothpick the center until dry.

title: Cookbook:Soufflé


text:
Category:Soufflé recipes

A soufflé is a light, fluffy baked dish made with egg yolks and beaten egg whites combined with various other ingredients and served as a main dish or sweetened as a dessert. The word soufflé is the past participle of the French verb souffler which means "to blow up" or more loosely "puff up" - an apt description of what happens to this combination of custard and egg whites.

title: Category:Soufflé recipes


text:
WebObjects/Web Applications/Development/WOForm Best Practices

Pierre Bernard
I do create the EO and insert it into an editing context dedicated to the task of creating and eventually saving that EO. That editing context is peer to the default editing context. Actually all my edits happen in dedicated peer contexts. The session default is used for reads only. This eliminates the risk of having a pending change hang around.

Doing so I get the default values set in awakeFromInsertion in my initial form.

I however do not bind the EO directly to the form. I transform the EO into a dictionary of strings. Using key-value coding I first extract a set of values I want in the form. Then again using key-value coding as well as formatters I derive a string representation for each value. The form is bound to a _clone_ that dictionary of values.

After the form is submitted I compare the modified clone to the original dictionary. Only for the changed values I do a reverse transformation from String to object or EO value. This is done by first parsing the string using a formatter and the possibly calling a fetch specification.

This has the following advantages:
 * I can map to-one relationships to a plain form
 * I only set actually modifed values on the EO
 * I do not lose precision on a value which internally had a higher precision than what the form shows
 * I handle parsing exceptions in code. For one this allows keeping the unparsable value in the form

Ondra Cada
Depends on the application.

But most often, I am eating my cake and still having it by creating the EO first, but saving it into EC only when properly set up. That way, it can be wired up directly, and still, if the user abandons it, it just vanishes when the GC decides so :)

Geoff Hopson
I find it much cleaner to have a formValues NSMutableDictionary and have the key names the same as my EO attribute names. In my WOD file I can bind text field values etc. to 'formValues.myAttribute. It also allows me to preset some defaults, hide any hidden fields I may need, stuff like that. I can then easily blat the dictionary into an inserted EO once I am pretty happy with the data that has been collected.

Mike Schrag
Do most of you create the EO up-front and attach the form fields directly to the attributes of the EO, or do you clone the fields into the WOComponent and attach to those, then move them into a new EO in the "save" action? The problem with the first route is that if someone navigates away, you've got an empty EO inserted into the EC and the user doesn't realize that it's still sitting in their session, but it's obviously nicer because you can just wire up directly to the EO attributes and you don't have to keep the Component and the EO fields in-sync

Jean-François Veillette
I use a new EO, in a 'peer' editingContext used for insertion/edition. That way, If changes are made to the eo, but not saved, and user change page, or even use the browser back button, I do not care, he doesn't screw-up the 'main' editingContext.

I forgot to mention another option that I used in some special situation : Instead of binding to an EO, bind to a NSMutableDictionary, then when you're ready to save, you can create your eo and apply the dictionary values to it (there is a method for that).


text:
WebObjects/Web Applications/Development/WO Session

Overview
A WOSession provides the encapsulation of all the state that is associated with a user's use of your application. Each WebObjects application has its own subclass of WOSession, which is a significant difference between session tracking in WebObjects and J2EE. In J2EE, HttpSession is not subclassed, and all state is stored as attributes in HttpSession's Map. In WebObjects, sessions are much richer, providing the ability to take advantage of all the benefits of being a full-blown class (typed fields, methods, etc). WOSessions have a timeout time, which by default is configured in the WOApplication configuration. This timeout time determines how long the server will keep the session alive without any active requests. When the session times out, it will be garbage collected.

Accessing the Session
Session session = (Session)session;

Note that this works only in WOComponent or WODirectAction subclasses. If you want to access the session from elsewhere, pick an answer from this list:
 * Your design is wrong; don't access the session from that class.
 * Create and maintain an index of which thread is dealing with which session, then you can always find the current session from anywhere.
 * Run single-threaded only, and maintain a store of which session is current.
 * Pass the session in from the calling component or direct action. But, see the first item.

Just one more word of caution do not set the session as a class variable of WOComponent or WODirectAction, this would create a loop and prevent the garbage collection of old sessions.

''Is the above really true? In a WO5 pure-Java application, circular references like this might create more work for the garbage collector, but shouldn't prevent anything from getting garbage collected. The Java garbage collector is supposed to handle circular references just fine. -- JonathanRochkind''

If you like to simplify your code just insert the following method in your component (this will save you some typing):

public Session Session { return (Session)this.session; }

We always begin our projects with a WOComponent subclass that we use as a superclass for all the rest of our components. We include this method as well as a few other useful utility methods. -- JoshuaMarker

As I recall the warnings about storing references to Session were specific to inner classes of Session. Storing references to Session inside another component is perfectly ok, although an accessor method is better. -- BrianMarquis

''I still think even this is not a problem in WO5, although it probably is in WO4.5. JRE 1.3.1 is supposed to garbage collect circular references just fine, whether involving an inner class or not. But maybe the JRE doesn't do what it's supposed to? -- JonathanRochkind''

Session Tracking
The first time a session is requested for a request, WebObjects ensures that all subsequent requests from the same user will use the same WOSession instance. WebObjects achieves this session tracking with one of three techniques: URL rewriting, cookies, or query strings.

With URL rewriting, once the session is initialized, generated URLs will include the session's ID in the URL path. For instance, if you use a WOHyperlink, the generated URL will look something like "http://hostname.com/cgi-bin/WebObjects/AppName.woa/1/wo/EMVnGH1g8VLOW2TRMm3Ptg/6.0.19.15.1.3.1". The "EMVnGH1g8VLOW2TRMm3Ptg" in this example is the uniquely generated session ID. All requests that come in with this session ID in the URL will be attached to the same WOSession instance.

Cookies work in a similar fashion, except that instead of rewriting URLs to pass the session ID, the session ID is passed in a cookie called "wosid".

Lastly, you can pass a query string attribute named "wosid" that contains the session ID. This is often used when calling DirectActions that need access to the user's session.

Performance Implications
Session creation and persistence must be carefully monitored in large deployments due to the memory usage required to keep the session alive. It is generally recommended to minimize session creation whenever possible. When using "normal" WebObjects techniques, this can be difficult. The default behavior of WOHyperlink, for instance, when calling an action on your WOComponents is to cause sessions to be generated. The typical method for avoiding session creation is to implement your application using DirectActions. DirectActions do not require a page cache to be created for page state preservation, and thus can be used in a completely stateless way. The downside of using only DirectActions is that you lose the benefits of a more stateful approach. For instance, when using DirectActions only, you will find that you have to manually wire up your state objects by interpreting query string variables.

You can check for the existence of a session in a DirectAction by calling the existingSession method. If a session exists, it will be returned. If a session has not yet been created, then this method will return null.

Adjusting your session timeout can have a large impact on performance. The longer a session timeout is, the longer the session will consume memory. Under heavy load, "dead" sessions can build up, so the timeout time should be tuned to be as low as possible without negatively affecting your user's experience with your application.

Hanging Sessions
There are certain cases in WebObjects where thrown exceptions can cause a session to not be checked back into the WOSessionStore, which will deadlock the session. One of the more common causes of this is an exception thrown from a DirectAction that uses a session. If you use Project Wonder's ERXApplication, ERXSession, etc, it provides a prevention mechanism for this problem. However, if you are using a default WebObjects installation without Project Wonder, you will need to deal with this problem yourself. You should not let your DirectActions throw an exception in this case.

Checking for Existing Session
If you are in a DirectAction method when trying to do this, check the following WOAction method (WOAction is WODirectAction's superclass):

public WOSession existingSession Restores the session based on the request. If the request did not have a session ID or the session ID referred to a non-existent session, then this method returns null. To determine if a session failed to restore, check the request's session ID to see if it non-null and if so, call this method to check its result.

Returns: a WOSession object which represents periods during which access to a WebObjects application and its resources is granted to a particular client

If you're not in a DirectAction method, look at WOContext's method:

public boolean hasSession Returns true if a session exists for the receiving context, false otherwise.


text:
WebObjects/EOF/Using EOF/Multiple Stacks or Instances

Anjo Krank
This is what the ERXObjectStoreCoordinatorPool does. You need to create each EC via the ERXEC factory to use it. Basically it assigns each session an OSC from a pool (more info is in the docs and the code). This does not help you when you have long-running statements going on, as there still sessions blocked - albeit not so many.

If you have long-running stuff, then you should create an OSC especially for them and use a long-running page.

Synchronizing Multiple EOF Stacks
The problem is synchronizing multiple EOF stacks is essentially the same as synchronizing multiple instances of your WebObjects application. Typically the same tricks apply to both.

WireHose

 * Wirehose Change Notification
 * ERChangeNotificationJMS
 * ERXObjectStoreCoordinatorSynchronizer

Christian Pekeler
I prefer architectures where the database is the private store of one application (or a set of related applications built using the same technology - WO/EOF in our case). So if you need a different kind of application to change data, let it go trough the application that own the DB instead of giving it direct access to the DB.

Just recently I was involved in a project that heavily relied on DB triggers. We created a new WO application called CheckInProcessor. It listened on a port for new data (using a proprietary protocol). The external app that used to write new data directly to the DB was changed to send the data to the CheckInProcessor. The CheckInProcessor writes that new data to the DB, performs tasks equivalent to the old triggers, and notified the other WO apps of any changes (using WONDER's EOUpdateNotification framework).


text:
WebObjects/EOF/Using EOF/Localization and Internationalization

Using UTF-8 encoding
Place the following code in your WOApplication's dispatchRequest

worequest.setContentEncoding(_NSUtilities.UTF8StringEncoding); worequest.setHeader("text/html; charset=UTF-8; encoding=UTF-8", "content-type");

This will make every page use UTF8 encoding when sending content back to the browser.

Santi
To use UTF-8 encoding you need four steps:

NLS_DATE_FORMAT = "YYYY-MM-DD HH24:MI:SS"; NLS_LANG = AMERICAN_AMERICA.UTF8; databaseEncoding = "UTF-8";
 * You must ensure that your database is using UTF-8 as a storing format. It is the default for FrontBase but you need a bit of tweaking for Oracle. If I remember correctly you need to add these to your connection dictionary in EOModeler:

--enable-multibyte flag, so you can create a new database specifying the encoding with: createdb -U postgres -E UNICODE
 * With PostgreSQL, to enable UTF-8 support you have to compile it with the

{"WebObjects Release" = "WebObjects 5.0"; encoding = NSUTF8StringEncoding; }
 * Encode your page in UTF-8. Set it as the default in WO builder and check the encoding by examinig the *.woo file inside the *.wo folder.

If they are not yet encoded in UTF-8 you can copy-paste the above line into your .woo file. Then you can change the encoding of the .wod and .html files (in pbx) by going to the "Format" menu and choosing "file Encodings".

The reason for doing this step is to minimize conversion at run time. If all your component are UTF-8 encoded then WO does not need to do any conversion during the page generation process. I have never actually tested the performance so it may be unwarranted.
 * Add the following META to your headers

 * You also need to overwrite Session.appendToResponse and set the encoding to "UTF8"; before calling super, the same applies to takeValuesFromRequest . You may also want to add a meta in the header giving the encoding (I am not sure this is necessary with modern browsers).

public void appendToResponse(WOResponse aResponse, WOContext aContext) { // set the encoding before anything is garbled aResponse.setContentEncoding( _NSUtilities.UTF8StringEncoding ); super.appendToResponse(aResponse, aContext); }

public void takeValuesFromRequest(WORequest aRequest, WOContext aContext) { aRequest.setDefaultFormValueEncoding( _NSUtilities.UTF8StringEncoding ); super.takeValuesFromRequest(aRequest, aContext); }

Beware of the two spelling when setting the encoding in a WOMessage the name is "UTF8"; or use the private function _NSUtilities.UTF8StringEncoding. Everywhere else it is "UTF-8"

''Is this really necessary? Is not enough to add WOMessage.setDefaultEncoding("UTF8") in the application constructor?''

And by the way, I don't understand well the difference between WOMessage.defaultEncoding and WORequest.defaultFormValueEncoding

''One is about the URL an the other about the data within the form? I'm a bit confused.''

David Paules
The first step in modifying the EOModel's connection dictionary was unnecessary for me. I used OpenBase as my backend database. OpenBase allows you to create a database with one of n different encodings (UTF8 is one of them). The EO Framework was capable of storing and retrieving UTF8 character data from OpenBase without any customization of the connection dictionary (ie, the connection dictionary only had the jdbc driver and database URL and user/password).

Since you must modify the session's appendToResponse method, you can simplify the process of adding the META tags to all your pages by doing it in code once. Simply add

aResponse.setHeader("text/html; charset=UTF-8; encoding=UTF-8", "content-type");

before calling

super.appendToResponse(aResponse, aContext);

Another person adds: Note, this is NOT the same as adding a meta tag to all your pages at once. It's adding a header to all your responses. But that should be just as good, or better. The META tag is really just meant to simulate the header.

For WebObjects 4.x using ObjectiveC you will need to following code in the WOComponent class:

-(void) appendToResponse: (WOResponse *) r inContext: (WOContext *) c { [r setHeader:@"text/html; charsetUTF-8; encoding=UTF8"; forKey:@"Content-type"]; [r setContentEncoding:NSUTF8StringEncoding]; [super appendToResponse:r inContext:c]; }

-(void) takeValuesFromRequest: (WORequest *) r inContext: (WOContext *) c { [r setFormValueEncodingDetectionEnabled:NO]; [r setDefaultFormValueEncoding:NSUTF8StringEncoding]; [super takeValuesFromRequest:r inContext:c]; }

You also need to disable the encoding detection... at least I had to do it in my case.


text:
Category:Baked recipes

Recipes for items other than Breads and Desserts which are prepared by baking.

Recipes for breads and dessert which are prepared by baking can found at Category:Baking recipes

title: Category:Baked recipes


text:
User talk:JSJohnson

Comments
...are welcome!

title: User talk:JSJohnson


text:
User:Yakudza

uk:User:Yakudza

title: User:Yakudza


text:
Educational Technology Innovation and Impact/Edutainment/Educational Television Programs for Children

The British Broadcasting Corporation, otherwise known as the BBC brings it to our attention that Education is at the heart of many of children’s programmes aired on TV. For example from Bite-size revision for GCSE students and schools TV to learning through play programmes the BBC argues that it makes learning more enjoyable and relevant to children of all ages (BBC Website 2006)

CBeebies is a good example and has a number of stimulating programmes built around the national pre-school curriculum. It helps pre-school children to play along and learn through watching their favourite characters on screen. Tikkabilla is one good example of this as it encourages children to join in singing, dancing and make-and-do activities grouped around early learning topics such as “where I live” and telling the time. Big Cook Little Cook is another excellent example and is the first pre-school cookery show that teaches children how to make healthy and fun food.

The National Literacy Trust commissioned a study into how educational children’s programmes can benefit a child’s literacy development. The review found that television can enhance many aspects of children's language, particularly for children between the ages of two and five, depending on quality and age-appropriateness of the content, and parent/carer interactions during and after viewing. Educational television, such as Sesame Street, has been found to enhance vocabulary, comprehension and expressive language development in pre-schoolers. It has been suggested in American research that pre-schoolers are not exposed to enough educational television, which can prepare them for school. (Literacy Trust website 2006)

For older children, there are programmes on the CBBC Channel that encourage 6–12 year olds to find things out for fun, exploring their existing interests or even developing new ones. Children are given the chance to explore new hobbies and build on their talents, such as cookery with Planet Cook or art with Smart.

Children with learning difficulties can take advantage of a programme called Something Special. This is designed to offer new and exciting ways to communicate for children with learning difficulties. It uses Makaton and a character called Mr Tumble teaches young children and their parents and carers to sign along to stories, songs and activities, and encourages children of all abilities to play together.

Other programmes such as Grange Hill have helped children understand social issues and the storylines have tackled drugs, rape and teenage pregnancy.

References; http://web.archive.org/web/20050629081745/http://www.bbc.co.uk/thefuture/text/children_bpv.html (accessed 3 May 2006) www.literacytrust.org.uk/pubs/close (accessed 3 May 2006)


text:
Talk:False Friends of the Slavist/Map borъ

Untitled
In ukrainian бір, not бор - necessary to include? --Yakudza 11:43, 7 May 2006 (UTC) I added, because it becomes from *borъ Szugar (talk) 11:12, 6 June 2009 (UTC)


text:
Template:Equipment

Effect

 * This template changes name of the tab the article is under to "Equipment"
 * Unless the parameter noincludecat is specified, the article is added to Category:Cookbook equipment
 * For example,  will not add the article to any categories
 * This template takes an optional sort key for the category:

title: Template:Equipment


text:
Template:Unit of measurement

Effect

 * This template changes name of the tab the article is under to "Unit of measurement"
 * Unless the parameter noincludecat is specified, the article is added to Category:Cookbook units
 * For example,  will not add the article to any categories
 * This template takes an optional sort key for the category:

title: Template:Unit of measurement


text:
Template:Cookdp

Cookbook | Recipes | Ingredients | Equipment | Techniques | Cookbook Disambiguation Pages

title: Template:Cookdp


text:
Category:Low-GI recipes

Recipes in accordance with a Low-GI Diet.

title: Category:Low-GI recipes


text:
Category:Duplicate recipes

Recipes which are duplicated in the cookbook. Both recipes should be added to this category.

__HIDDENCAT__

title: Category:Duplicate recipes


text:
Category:Meals and courses

Different types of meals.

title: Category:Meals and courses


text:
Wikijunior:Kings and Queens of England/The House of Saxe-Coburg-Gotha

Edward VII (1901-1910)
Edward VII was born at Buckingham Palace on 9 November 1841. His parents were Queen Victoria and Prince Albert. Edward VII was King of the United Kingdom of Great Britain and Ireland, King of the Dominions of the British Empire and the Emperor of India from 22 January 1901 to his death on 6 May 1910. He was the first British monarch of the House of Saxe-Coburg-Gotha. Despite taking the name "King Edward", he was known to his family as "Bertie" as his first name was Albert.

Early life
Queen Victoria and Prince Albert wanted their eldest son to have an education that would prepare him to be a model constitutional monarch. Aged seven, Bertie started a rigorous educational programme devised by the Prince Consort. However, he was not a good student, with his main talents being his tact and charm. Edward hoped to have a career in the British Army, but this was denied him because he was heir to the throne, although he did serve briefly in the Grenadier Guards in 1861. As a young man, he gained a reputation as a playboy.

Marriage
Once widowed, Queen Victoria withdrew from public life, but she did arrange for her son to marry Princess Alexandra of Denmark, the beautiful elder daughter of King Christian IX of Denmark. The couple married on 10 March 1863. However, Edward kept mistresses throughout his married life.

Heir apparent
During Victoria's widowhood, Edward represented her at public gatherings, but Victoria did not allow him to have an active role in the running of the country. Several incidents, including a court appearance in a notorious divorce case, brought him bad press and caused him to be regarded as unsuitable material for a future monarch. He was known for his love of gambling and country sports. But Edward was also a patron of the arts and sciences and helped found the Royal College of Music.

Reign
When Queen Victoria died on 22 January 1901, Bertie, then aged 59, became king. Edward VII and Queen Alexandra were crowned at Westminster Abbey on 9 August 1902. His coronation was going to be on 26 June, but two days before on 24 June, Edward developed appendicitis. He needed what may have been a life-saving operation. Two weeks later it was announced that the King was out of danger.

As king, Edward's main interests lay in the fields of foreign affairs and naval and military matters. Fluent in French and German, he made a number of visits abroad. One of his most important foreign trips was an official visit to France in spring 1903 as the guest of President Émile Loubet. This visit helped build the Anglo-French Entente Cordiale, which was an informal agreement setting out what territories were British and French colonies in North Africa, with the aim of preventing future wars between the two countries.

Edward VII, mainly through his mother and his father-in-law, was related to nearly every other European monarch and came to be known as the Uncle of Europe. The German Emperor Wilhelm II, Tsar Nicholas II of Russia, King Alphonso XIII of Spain and Carl Eduard, Duke of Saxe-Coburg-Gotha were Edward's nephews. King Haakon VII of Norway was his son-in-law and nephew by marriage. King George I of the Hellenes and King Frederick VIII of Denmark were his brothers-in-law. King Albert I of the Belgians, King Manuel II of Portugal, King Ferdinand of Bulgaria, Queen Wilhelmina of the Netherlands and Prince Ernst August, Duke of Brunswick-Lüneburg, were his cousins.

In the last year of his life, Edward was involved in a constitutional crisis when the Conservative majority in the House of Lords refused to pass the "People's Budget" proposed by the Liberal government of Prime Minister Herbert Henry Asquith. The King died before the Liberal victory in the 1910 general election resolved the situation, but he told Asquith that he would, if necessary, appoint new peers to allow the Budget to pass through the House of Lords.

Death
Edward died from a heart attack brought on by bronchitis on 6 May 1910. He was succeeded by his eldest surviving son, who became George V.

George V (1910-1936)
George V was born at Marlborough House on 3 June 1865. His parents were Edward VII and Queen Alexandra. He was King of the United Kingdom of Great Britain and Ireland, King of the Dominions of the British Empire and Emperor of India from 6 May 1910 until his death on 20 January 1936.

Early life
As a younger son of the Prince of Wales (as Edward VII then was), he was not expected to become king. However, as George was born only fifteen months after his brother Prince Albert Victor, it was decided to educate both royal princes together. Given the importance of Prince Albert Victor's expected future role as king, both brothers were given a strict programme of study, although neither did well at their studies.

Later the royal brothers served as Naval cadets on HMS Bacchante. They toured the British Empire, visiting the colonies in Australia and the Far East, and also getting tattooed in Japan. When they returned to the UK, the brothers were parted with George joining the Royal Navy and Albert Victor attending Trinity College, Cambridge. George served in the navy until 1891. He travelled the world and visited many areas of the British Empire. He also got many more tattoos, and a parrot that he took home to England with him.

Marriage
In 1891, Prince Albert Victor became engaged to his second cousin once removed, Princess Victoria Mary of Teck (always called "May"), the only daughter of Prince Francis, Duke of Teck and Princess Mary Adelaide of Cambridge. However, Albert Victor died of pneumonia six weeks later, leaving George second in line to the throne and likely to succeed after his father. Queen Victoria still favoured Princess May as a suitable bride for a future King, so she persuaded George to propose to May and May accepted. Despite its being an arranged marriage, George and May's marriage was largely successful, and unlike his father, George is not believed to have had a mistress. They married on 6 July 1893, and they had six children in total. David and Bertie were the first two. Then came Mary, Henry, George and John. The first two were later to become King Edward VIII and King George VI respectively.

Time before becoming king
In 1892 Queen Victoria made George the Duke of York. As Duke and Duchess of York, George and May carried out a wide variety of public duties. In 1900, they toured the British Empire, visiting Australia, where the Duke opened the first session of the Australian Parliament on the creation of the Commonwealth of Australia.

In 1901, Queen Victoria died and George became next in line to the throne. His father, Edward VII, made him Prince of Wales later that year. In contrast with Queen Victoria, who excluded Edward from state affairs, George was given wide access to state documents and papers. He often read over the papers with his wife, Princess May, who was cleverer than him. May also helped write speeches for her husband.

Reign
On 6 May 1910, King Edward VII died and George became George V. Princess May became Queen Mary. On 11 December 1911, the King and Queen travelled to India for the Delhi Durbar, where they were presented to Indian dignitaries and princes as the Emperor and Empress of India. George wore the newly-created Imperial Crown of India at the ceremony. Later, the Emperor and Empress travelled throughout India visiting their new subjects.

As King and Queen, George and Mary saw Britain through World War I. This war was fought against Germany, amongst others, which made it a difficult time for the Royal Family, as they had many German relatives. On 17 July 1917 he changed the name of the British Royal House from the German-sounding House of Saxe-Coburg-Gotha to the House of Windsor. He also renounced all use of German titles and styles for his British relatives.

Death
World War I took its toll on George's health, which rapidly worsened. He had always had a weak chest, which was not helped by his smoking. An illness saw him go to the seaside, by Bognor Regis in Sussex, where Queen Mary helped nurse him back to health (however, reputedly the King's last words, upon being told that he would soon be well enough to revisit Bognor Regis were "... bugger Bognor!") He did live to see the Silver Jubilee of his reign, in 1935, by which time he had become a well-loved king.

George died on 20 January 1936 at Sandringham House in Norfolk. He was buried at St George's Chapel, Windsor Castle. It is said his death was hastened by his doctor giving him a lethal injection of cocaine and morphine, both to end the King's suffering and to make sure he died by midnight so that his death could be announced in the morning newspapers.