/*
* Copyright (C) NetStruxr, Inc. All rights reserved.
*
* This software is published under the terms of the NetStruxr
* Public Software License version 0.5, a copy of which has been
* included with this distribution in the LICENSE.NPL file. */
package er.directtoweb.components.strings;
import java.util.Enumeration;
import org.apache.log4j.Logger;
import com.webobjects.appserver.WOContext;
import com.webobjects.appserver.WORequest;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSMutableArray;
import com.webobjects.foundation.NSValidation;
import er.directtoweb.ERDirectToWeb;
import er.directtoweb.components.ERDCustomEditComponent;
import er.extensions.foundation.ERXArrayUtilities;
import er.extensions.foundation.ERXKeyValuePair;
import er.extensions.localization.ERXLocalizer;
/**
* Provides a toOne relationship-like component except the value is pushed in as a string.<br />
* The coices can be either given as an NSDictionary with {key1=val1;key2=val2...}, an NSArray of
* NSDictionaries with ({key1=val1;},{key2=val2;}...) or a means not yet clear to me (ak:).
*/
public class ERDEditStringWithChoices extends ERDCustomEditComponent {
/**
* 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;
public ERDEditStringWithChoices(WOContext context) {super(context);}
/** logging support */
public static final Logger log = Logger.getLogger(ERDEditStringWithChoices.class);
public String entityForReportName;
public ERXKeyValuePair currentElement;
@Override
public boolean synchronizesVariablesWithBindings() { return false; }
@Override
public boolean isStateless() { return true; }
protected NSArray _availableElements;
public NSArray availableElements(){
if(_availableElements==null){
Object choices = valueForBinding("possibleChoices");
if(choices != null) {
NSMutableArray keyChoices = new NSMutableArray();
if(choices instanceof NSArray) {
for(Enumeration e = ((NSArray)choices).objectEnumerator(); e.hasMoreElements(); ) {
NSDictionary dict = (NSDictionary)e.nextElement();
String key = (String)dict.allKeys().lastObject();
String value = (String)dict.objectForKey(key);
keyChoices.addObject(new ERXKeyValuePair(key, ERXLocalizer.currentLocalizer().localizedStringForKeyWithDefault(value)));
}
} else if(choices instanceof NSDictionary) {
NSArray keys = ((NSDictionary)choices).allKeys();
keys = ERXArrayUtilities.sortedArraySortedWithKey(keys, "toString");
for(Enumeration e = keys.objectEnumerator(); e.hasMoreElements(); ) {
String key = (String)e.nextElement();
String value = (String)((NSDictionary)choices).objectForKey(key);
keyChoices.addObject(new ERXKeyValuePair(key, ERXLocalizer.currentLocalizer().localizedStringForKeyWithDefault(value)));
}
}
_availableElements = keyChoices;
}
if(_availableElements==null){
if(log.isDebugEnabled()) log.debug("key ="+key());
String keyForAvailableObjects = key()+"Available";
entityForReportName = (String)valueForBinding("entityNameForReport");
_availableElements =
ERDirectToWeb.displayableArrayForKeyPathArray((NSArray)object().valueForKeyPath(keyForAvailableObjects),
entityForReportName);
}
if(_availableElements==null){
_availableElements = NSArray.EmptyArray;
}
if(log.isDebugEnabled()) log.debug("availableElements = "+_availableElements);
}
return _availableElements;
}
@Override
public void reset(){
super.reset();
_availableElements = null;
entityForReportName = null;
currentElement = null;
}
public ERXKeyValuePair selectedElement() {
Object value = objectPropertyValue();
ERXKeyValuePair selectedElement = null;
for(Enumeration e = availableElements().objectEnumerator(); e.hasMoreElements() && selectedElement == null;) {
ERXKeyValuePair current = (ERXKeyValuePair) e.nextElement();
if(current.key().equals(value)) {
selectedElement = current;
}
}
return selectedElement;
}
public void setSelectedElement(Object value) {
ERXKeyValuePair kvp = (ERXKeyValuePair)value;
if (kvp!=null) {
object().validateTakeValueForKeyPath(kvp.key(), key());
} else {
object().validateTakeValueForKeyPath(null, key());
}
}
/** Extends the parent implementation in order to force validation. */
@Override
public void takeValuesFromRequest(WORequest r, WOContext c) {
super.takeValuesFromRequest(r,c);
if (c.wasFormSubmitted()) {
try {
object().validateTakeValueForKeyPath(objectPropertyValue(), key());
} catch (NSValidation.ValidationException e) {
validationFailedWithException(e, objectPropertyValue(), key());
}
}
}
}