package er.directtoweb.assignments.defaults;
import com.webobjects.directtoweb.D2WContext;
import com.webobjects.eocontrol.EOGenericRecord;
import com.webobjects.eocontrol.EOKeyValueUnarchiver;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSDictionary;
import er.directtoweb.assignments.ERDAssignment;
import er.extensions.eof.ERXEOControlUtilities;
import er.extensions.foundation.ERXDictionaryUtilities;
import er.extensions.foundation.ERXStringUtilities;
/**
* An assignment to auto-compute a unique(ish), human-readable DOM ids from the d2wContext for Selenium, CSS, Ajax, Javascript, etc.
* For Ajax updates you may also use this assignment to compute an updateContainerID key (by setting it to idForSection, idForPageConfiguration, etc. as required).
*
* This assignment provids defaults for the following keys:
* <ul>
* <li><code>idForProperty</code></li>
* <li><code>idForSection</code></li>
* <li><code>idForPageConfiguration</code></li>
* <li><code>idForEmbeddedPageConfiguration</code></li>
* <li><code>idForEmbeddedProperty</code></li>
* <li><code>idForForm</code></li>
* </ul>
*
* To use: Bind D2W component id binding to d2wContext.id (or d2wContext.idForProperty or d2wContext.idForSection, etc)
*
* You may also override these auto computed id by setting rules for the above keys, if necessary.
*
* @author mendis
*
*/
public class ERDDefaultIDAssignment extends ERDAssignment {
/**
* Do I need to update serialVersionUID?
* See section 5.6 <cite>Type Changes Affecting Serialization</cite> on page 51 of the
* <a href="http://java.sun.com/j2se/1.4/pdf/serial-spec.pdf">Java Object Serialization Spec</a>
*/
private static final long serialVersionUID = 1L;
/** holds the array of keys this assignment depends upon */
protected static final NSDictionary keys = ERXDictionaryUtilities.dictionaryWithObjectsAndKeys( new Object [] {
new NSArray(new Object[] {"propertyKey", "task", "entity.name"}), "idForProperty",
new NSArray(new Object[] {"pageConfiguration", "task", "entity.name", "sectionKey"}), "idForSection",
new NSArray(new Object[] {"pageConfiguration", "task", "entity.name"}), "idForPageConfiguration",
new NSArray(new Object[] {"pageConfiguration", "task", "entity.name", "object"}), "idForEmbeddedPageConfiguration",
new NSArray(new Object[] {"propertyKey", "task", "entity.name", "object"}), "idForEmbeddedProperty",
new NSArray(new Object[] {"pageConfiguration", "task", "entity.name"}), "idForForm",
});
/**
* Implementation of the {@link er.directtoweb.assignments.ERDComputingAssignmentInterface}. This array
* of keys is used when constructing the
* significant keys for the passed in keyPath.
* @param keyPath to compute significant keys for.
* @return array of context keys this assignment depends upon.
*/
public NSArray dependentKeys(String keyPath) {
return (NSArray)keys.valueForKey(keyPath);
}
/**
* Static constructor required by the EOKeyValueUnarchiver
* interface. If this isn't implemented then the default
* behavior is to construct the first super class that does
* implement this method. Very lame.
* @param eokeyvalueunarchiver to be unarchived
* @return decoded assignment of this class
*/
// ENHANCEME: Only ever need one of these assignments.
public static Object decodeWithKeyValueUnarchiver(EOKeyValueUnarchiver eokeyvalueunarchiver) {
return new ERDDefaultIDAssignment(eokeyvalueunarchiver);
}
/**
* Public constructor
* @param u key-value unarchiver used when unarchiving
* from rule files.
*/
public ERDDefaultIDAssignment (EOKeyValueUnarchiver u) { super(u); }
/**
* Public constructor
* @param key context key
* @param value of the assignment
*/
public ERDDefaultIDAssignment (String key, Object value) { super(key,value); }
/**
* a DOM id based on the triple <task, entity, propertyKey>
*
* @param c d2w context
* @return an id representing the <task, entity, propertyKey>
*
* TODO Maybe change to pageConfig + propertyKey?
*/
public Object idForProperty(D2WContext c) {
return ERXStringUtilities.safeIdentifierName(c.entity().name() + "_" + c.task() + "_" + c.propertyKey());
}
/**
* a DOM id based on the triple <task, entity, propertyKey, pk>
*
* @param c d2w context
* @return an id representing the <task, entity, propertyKey, pk>
*
* TODO Maybe change to pageConfig + propertyKey?
*/
public Object idForEmbeddedProperty(D2WContext c) {
return idForProperty(c) + "_" + ERXEOControlUtilities.primaryKeyStringForObject((EOGenericRecord) c.valueForKey("object"));
}
/**
* A DOM id based on the pageConfig
*
* @param c d2w context
* @return an id representing the <task, entity>
*/
public Object idForPageConfiguration(D2WContext c) {
String _idForPageConfiguration = (c.dynamicPage() != null) ? c.dynamicPage() : c.task() + "_" + c.entity().name();
return ERXStringUtilities.safeIdentifierName(_idForPageConfiguration);
}
/**
* A DOM id based on the pageConfig + primaryKey
*
* @param c d2w context
* @return an id representing the <task, entity, pk>
*/
public Object idForEmbeddedPageConfiguration(D2WContext c) {
return idForPageConfiguration(c) + "_" + ERXEOControlUtilities.primaryKeyStringForObject((EOGenericRecord) c.valueForKey("object"));
}
/**
* A DOM id based on the pageConfig and sectionKey
*
* @param c d2w context
* @return an id representing the section in a tab page
*/
public Object idForSection(D2WContext c) {
String sectionKey = (String) c.valueForKey("sectionKey");
String section = !"".equals(sectionKey) ? ERXStringUtilities.safeIdentifierName(sectionKey) : "section";
return idForPageConfiguration(c) + "_" + section;
}
/**
* A DOM id based on the pageConfig
*
* @param c d2w context
* @return an id representing the form for the d2w page
*/
public Object idForForm(D2WContext c) {
return idForPageConfiguration(c) + "_form";
}
}