package er.rest.routes.components;
import com.webobjects.appserver.WOApplication;
import com.webobjects.appserver.WOContext;
import com.webobjects.eocontrol.EOEditingContext;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSMutableDictionary;
import er.extensions.appserver.ERXRequest;
import er.extensions.components.ERXComponent;
import er.extensions.components.ERXComponentUtilities;
import er.extensions.eof.ERXEC;
import er.extensions.eof.ERXEnterpriseObject;
import er.rest.ERXRestClassDescriptionFactory;
import er.rest.ERXRestContext;
import er.rest.IERXRestDelegate;
import er.rest.routes.ERXRouteUrlUtils;
/**
* Generate a URL that points to a particular ERXRouteController route (this is a quicky impl and not totally thought out yet).
*
* @author mschrag
* @binding entityName (optional) the name of the entity to link to
* @binding id (optional) the id of the entity to link to
* @binding record (optional) the record to link to
* @binding action (optional) the rest action to perform (defaults to "show" when an id or record is set, "index" if only an entityName is set)
* @binding secure (optional) whether or not to generate a secure url (defaults to the same as the current request)
* @binding queryDictionary (optional) additional query parameters dictionary
* @binding format (optional) the format to link to (defaults to "html")
*/
public class ERXRouteURL extends ERXComponent {
public ERXRouteURL(WOContext context) {
super(context);
}
@Override
public boolean isStateless() {
return true;
}
public Object record() {
return valueForBinding("record");
}
protected void addQueryParameterForKey(Object value, String key, NSMutableDictionary<String, Object> queryParameters) {
if (value instanceof ERXEnterpriseObject) {
queryParameters.setObjectForKey(((ERXEnterpriseObject) value).primaryKeyInTransaction(), key);
}
else if (value != null) {
queryParameters.setObjectForKey(value, key);
}
}
@SuppressWarnings("unchecked")
public String linkURL() {
String linkUrl;
String action = (String) valueForBinding("action");
boolean secure = ERXComponentUtilities.booleanValueForBinding(this, "secure", ERXRequest.isRequestSecure(context().request()));
boolean includeSessionID = context().hasSession() && context().session().storesIDsInURLs();
NSMutableDictionary<String, Object> queryParameters = new NSMutableDictionary<>();
for (String bindingKey : bindingKeys()) {
if (bindingKey.startsWith("?")) {
Object value = valueForBinding(bindingKey);
String key = bindingKey.substring(1);
if (value != null) {
String sessionIdKey = WOApplication.application().sessionIdKey();
if (sessionIdKey.equals(key) && (Boolean.FALSE.equals(value) || "false".equals(value))) {
includeSessionID = false;
}
else {
addQueryParameterForKey(value, key, queryParameters);
}
}
}
}
NSDictionary<String, Object> existingQueryParameters = (NSDictionary<String, Object>) valueForBinding("queryDictionary");
if (existingQueryParameters != null) {
for (String key : existingQueryParameters.allKeys()) {
Object value = existingQueryParameters.objectForKey(key);
addQueryParameterForKey(value, key, queryParameters);
}
}
boolean absolute = booleanValueForBinding("absolute");
if (absolute) {
context().generateCompleteURLs();
}
String format = stringValueForBinding("format", "html");
Object record = record();
if (record != null) {
String entityName = (String) valueForBinding("entityName");
if (entityName == null) {
entityName = ERXRestClassDescriptionFactory.entityNameForObject(record);
}
EOEditingContext editingContext = ERXEC.newEditingContext();
Object entityID = IERXRestDelegate.Factory.delegateForEntityNamed(entityName).primaryKeyForObject(record, new ERXRestContext(editingContext));
editingContext.dispose();
linkUrl = ERXRouteUrlUtils.actionUrlForEntity(context(), entityName, entityID, action, format, queryParameters, secure, includeSessionID);
}
else {
String entityName = (String) valueForBinding("entityName");
String id = (String) valueForBinding("id");
if (entityName != null) {
if (id != null) {
linkUrl = ERXRouteUrlUtils.actionUrlForEntity(context(), entityName, id, action, format, queryParameters, secure, includeSessionID);
}
else {
linkUrl = ERXRouteUrlUtils.actionUrlForEntityType(context(), entityName, action, format, queryParameters, secure, includeSessionID);
}
}
else {
linkUrl = null;
}
}
if (absolute) {
context().generateRelativeURLs();
}
return linkUrl;
}
}