/* * 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; import org.apache.log4j.Logger; import com.webobjects.appserver.WOApplication; import com.webobjects.appserver.WOComponent; import com.webobjects.appserver.WOContext; import com.webobjects.appserver.WOSession; import com.webobjects.directtoweb.ConfirmPageInterface; import com.webobjects.directtoweb.D2W; import com.webobjects.directtoweb.D2WComponent; import com.webobjects.directtoweb.D2WContext; import com.webobjects.directtoweb.D2WModel; import com.webobjects.directtoweb.D2WPage; import com.webobjects.directtoweb.D2WUtils; import com.webobjects.directtoweb.ERD2WContext; import com.webobjects.directtoweb.EditPageInterface; import com.webobjects.directtoweb.EditRelationshipPageInterface; import com.webobjects.directtoweb.ErrorPageInterface; import com.webobjects.directtoweb.InspectPageInterface; import com.webobjects.directtoweb.ListPageInterface; import com.webobjects.directtoweb.QueryAllPageInterface; import com.webobjects.directtoweb.QueryPageInterface; import com.webobjects.directtoweb.SelectPageInterface; import com.webobjects.eoaccess.EOEntity; import com.webobjects.eoaccess.EOModelGroup; import com.webobjects.eoaccess.EOUtilities; import com.webobjects.eocontrol.EOEditingContext; import com.webobjects.eocontrol.EOEnterpriseObject; import com.webobjects.foundation.NSArray; import er.directtoweb.interfaces.ERDErrorPageInterface; import er.extensions.eof.ERXEC; import er.extensions.eof.ERXEOControlUtilities; import er.extensions.foundation.ERXStringUtilities; import er.extensions.foundation.ERXUtilities; /** * Not used at the moment, but shows how it might be used in the future. */ public class ERD2WFactory extends D2W { @Override protected void init() { D2WModel model = D2WModel.defaultModel(); if (!(model instanceof ERD2WModel)) { ERD2WModel erModel = ERD2WModel.erDefaultModel(); D2WModel.setDefaultModel(erModel); } super.init(); } @Override public EditPageInterface editPageForEntityNamed(String entityName, WOSession session) { return (EditPageInterface) pageForConfigurationNamed("Edit" + entityName, session); } @Override public EditRelationshipPageInterface editRelationshipPageForEntityNamed(String entityName, WOSession session) { return (EditRelationshipPageInterface) pageForConfigurationNamed("EditRelationship" + entityName, session); } @Override public InspectPageInterface inspectPageForEntityNamed(String entityName, WOSession session) { return (InspectPageInterface) pageForConfigurationNamed("Inspect" + entityName, session); } @Override public ConfirmPageInterface confirmPageForEntityNamed(String entityName, WOSession session) { return (ConfirmPageInterface) pageForConfigurationNamed("Confirm" + entityName, session); } @Override public ListPageInterface listPageForEntityNamed(String entityName, WOSession session) { return (ListPageInterface) pageForConfigurationNamed("List" + entityName, session); } @Override public QueryAllPageInterface queryAllPage(WOSession session) { return (QueryAllPageInterface) pageForConfigurationNamed("QueryAll", session); } @Override public QueryPageInterface queryPageForEntityNamed(String entityName, WOSession session) { return (QueryPageInterface) pageForConfigurationNamed("Query" + entityName, session); } @Override public SelectPageInterface selectPageForEntityNamed(String entityName, WOSession session) { return (SelectPageInterface) pageForConfigurationNamed("Select" + entityName, session); } /** logging support */ protected static final Logger log = Logger.getLogger(ERD2WFactory.class); /** * Gets the D2W factory cast as an ERD2WFactory objects. * * @return the singleton factory */ public static ERD2WFactory erFactory() { return (ERD2WFactory) D2W.factory(); } private D2WContext _privateContext; /** holds a reference to the default delegate */ protected Object defaultListPageDisplayGroupDelegate; public D2WContext privateContext(WOSession s) { if (_privateContext == null) { _privateContext = ERD2WContext.newContext(s); } _privateContext.takeValueForKey(s, "session"); return _privateContext; } @Override public NSArray visibleEntityNames(WOSession s) { return D2WUtils.visibleEntityNames(privateContext(s)); } /** * Gets the default list page delegate for display groups * * @return default list page display group delegate */ public Object defaultListPageDisplayGroupDelegate() { return defaultListPageDisplayGroupDelegate; } @Override public WOComponent defaultPage(WOSession wosession) { D2WContext d2wcontext = ERD2WContext.newContext(wosession); return pageWithContextTaskEntity(d2wcontext, d2wcontext.startupTask(), d2wcontext.startupEntityName(), wosession.context()); } protected WOComponent pageWithContextTaskEntity(D2WContext d2wcontext, String s, String s1, WOContext wocontext) { myCheckRules(); d2wcontext.setTask(s); EOEntity eoentity = s1 != null ? EOModelGroup.defaultGroup().entityNamed(s1) : null; if (eoentity == null && s1 != null && !s1.equals("") && !s1.equals("*all*")) { throw new IllegalArgumentException( "Could not find entity named " + s1); } d2wcontext.setEntity(eoentity); WOComponent wocomponent = WOApplication.application().pageWithName(d2wcontext.pageName(), wocontext); if (wocomponent instanceof D2WComponent) { ((D2WComponent) wocomponent).setLocalContext(d2wcontext); } return wocomponent; } /** * Sets the default display group delegate for list pages * * @param delegate * object */ public void setDefaultListPageDisplayGroupDelegate(Object delegate) { defaultListPageDisplayGroupDelegate = delegate; } public void myCheckRules() { init(); boolean checkRules = !WOApplication.application().isCachingEnabled(); if (checkRules) { ERD2WModel.erDefaultModel().checkRules(); } } @Override public WOComponent pageForConfigurationNamed(String name, WOSession s) { myCheckRules(); D2WContext d2wcontext = ERD2WContext.newContext(s.context().session()); d2wcontext.setDynamicPage(name); if (d2wcontext.task() == null || d2wcontext.entity() == null) { String reason = null; if (d2wcontext.task() == null && d2wcontext.entity() == null) { reason = "task and entity is null, it seems that one model, maybe ERDirectToWeb d2w.d2wmodel is not loaded!"; } else if (d2wcontext.task() == null) { reason = "task is null, it seems that one model, maybe ERDirectToWeb d2w.d2wmodel is not loaded!"; } else if (d2wcontext.entity() == null) { reason = "entity is null, it seems that one model, maybe ERDirectToWeb d2w.d2wmodel is not loaded!"; } throw new IllegalStateException("Couldn't find the dynamic page named " + name + " in your DirectToWeb model."+ reason); } return pageWithContextTaskEntity(d2wcontext, d2wcontext.task(), d2wcontext.entity().name(), s.context()); // return super.pageForConfigurationNamed(name, s); } private EOEntity _entityNamed(String entityName, WOSession session) { EOEditingContext ec = (session != null ? session.defaultEditingContext() : null); EOModelGroup group = (ec == null) ? EOModelGroup.defaultGroup() : EOUtilities.modelGroup(ec); return entityName != null ? group.entityNamed(entityName) : null; } private EOEnterpriseObject _newObjectWithEntity(EOEntity entity, EOEditingContext ec) { if (entity.isReadOnly()) { throw new IllegalArgumentException(" You can't create a new instance of " + entity.name() + ". It is a read-only entity. It is marked read-only in the model."); } if (entity.isAbstractEntity()) { throw new IllegalArgumentException(" You can't create a new instance of " + entity.name() + ". It is an abstract entity"); } EOEnterpriseObject eo; try { ec.lock(); eo = ERXEOControlUtilities.createAndInsertObject(ec, entity.name()); } finally { ec.unlock(); } return eo; } @Override public EditPageInterface editPageForNewObjectWithEntityNamed(String entityName, WOSession session) { EditPageInterface epi = (EditPageInterface) pageForConfigurationNamed("Create" + entityName, session); EOEditingContext peerContext = ERXEC.newEditingContext(session.defaultEditingContext().parentObjectStore()); EOEnterpriseObject newObject = _newObjectWithEntity(_entityNamed(entityName, session), peerContext); epi.setObject(newObject); peerContext.hasChanges(); return epi; } @Override public EditPageInterface editPageForNewObjectWithConfigurationNamed(String configurationName, WOSession session) { EditPageInterface epi = (EditPageInterface) pageForConfigurationNamed(configurationName, session); EOEditingContext peerContext = ERXEC.newEditingContext(session.defaultEditingContext().parentObjectStore()); D2WContext d2wcontext = ((D2WPage) epi).d2wContext(); EOEnterpriseObject newObject = _newObjectWithEntity(d2wcontext.entity(), peerContext); epi.setObject(newObject); peerContext.hasChanges(); return epi; } @Override public WOComponent pageForTaskAndEntityNamed(String task, String entityName, WOSession session) { String pageConfiguration = ERXStringUtilities.capitalize(task) + (entityName == null ? "" : entityName); return pageForConfigurationNamed(pageConfiguration, session); } public WOComponent printerFriendlyPageForD2WContext(D2WContext context, WOSession session) { myCheckRules(); D2WContext newContext = ERD2WContext.newContext(session); String newTask = context.task().equals("edit") ? "inspect" : context.task(); newContext.takeValueForKey(newTask, "task"); // not using subTask directly here because the cache mechanism relies on // being able to compute wether this key // is 'computable' (subTask is since a rule can fire to give a default) // or an external output // newContext.takeValueForKey("printerFriendly","subTask"); newContext.takeValueForKey("printerFriendly", "forcedSubTask"); newContext.takeValueForKey(context.valueForKey("pageName"), "existingPageName"); newContext.takeValueForKey(context.valueForKey("subTask"), "existingSubTask"); newContext.takeValueForKey(context.valueForKey("pageConfiguration"), "pageConfiguration"); newContext.takeValueForKey(context.entity(), "entity"); WOComponent result = WOApplication.application().pageWithName((String) newContext.valueForKey("pageName"), session.context()); ((D2WPage) result).setLocalContext(newContext); return result; } public WOComponent csvExportPageForD2WContext(D2WContext context, WOSession session) { myCheckRules(); D2WContext newContext = ERD2WContext.newContext(session); newContext.takeValueForKey(context.task(), "task"); // not using subTask directly here because the cache mechanism relies on // being able to compute wether this key // is 'computable' (subTask is since a rule can fire to give a default) // or an external output newContext.takeValueForKey("csv", "forcedSubTask"); newContext.takeValueForKey(context.valueForKey("pageName"), "existingPageName"); newContext.takeValueForKey(context.valueForKey("subTask"), "existingSubTask"); newContext.takeValueForKey(context.valueForKey("pageConfiguration"), "pageConfiguration"); newContext.takeValueForKey(context.entity(), "entity"); WOComponent result = WOApplication.application().pageWithName((String) newContext.valueForKey("pageName"), session.context()); ((D2WPage) result).setLocalContext(newContext); return result; } public WOComponent pageForTaskSubTaskAndEntityNamed(String task, String subtask, String entityName, WOSession session) { myCheckRules(); D2WContext newContext = ERD2WContext.newContext(session); newContext.setTask(task); newContext.setEntity(_entityNamed(entityName, session)); newContext.takeValueForKey(subtask, "subTask"); WOComponent result = WOApplication.application().pageWithName((String) newContext.valueForKey("pageName"), session.context()); ((D2WPage) result).setLocalContext(newContext); return result; } public QueryPageInterface queryPageWithFetchSpecificationForEntityNamed(String fsName, String entityName, WOSession s) { WOComponent result = pageForTaskSubTaskAndEntityNamed("query", "fetchSpecification", entityName, s); result.takeValueForKey(fsName, "fetchSpecificationName"); return (QueryPageInterface) result; } public WOComponent errorPageForException(Throwable e, WOSession s) { myCheckRules(); ErrorPageInterface epi = D2W.factory().errorPage(s); if (epi instanceof ERDErrorPageInterface && e instanceof Exception) { ((ERDErrorPageInterface) epi).setException((Exception) e); } epi.setMessage(ERXUtilities.stackTrace(e)); epi.setNextPage(s.context().page()); return (WOComponent) epi; } /** * Produces an error page that displays the provided message and returns the user to the current page. * @param message to display * @param session - the active session * @return the error page */ public WOComponent errorPageWithMessage(String message, WOSession session) { return errorPageWithMessageAndDestination(message, session.context().page(), session); } /** * Produces an error page that displays the provided message and returns the user to the destination page. * @param message to display * @param destination page to which the error component returns the user * @param session - the active session * @return the error page */ public WOComponent errorPageWithMessageAndDestination(String message, WOComponent destination, WOSession session) { myCheckRules(); ErrorPageInterface epi = D2W.factory().errorPage(session); epi.setMessage(message); epi.setNextPage(destination); return (WOComponent)epi; } // ak: These next set of methods are intented to be overidden and extended // however, the java compiler refuses to create a object method with the // same name as a static one, thus the "_" prefix /** * Gets the <code>pageConfiguration</code> from the current page. */ protected String _pageConfigurationFromPage(WOComponent page) { String pageConfiguration = null; if (page instanceof D2WPage) { if (((D2WPage) page).d2wContext() != null) { pageConfiguration = ((D2WPage) page).d2wContext().dynamicPage(); } } if (pageConfiguration == null) { String task = taskFromPage(page); String entityName = entityNameFromPage(page); if (task != null) { task = ERXStringUtilities.capitalize(task); } else { task = ""; } if (entityName != null) { entityName = ERXStringUtilities.capitalize(entityName); } else { entityName = ""; } pageConfiguration = task + entityName; } return pageConfiguration; } /** * Gets the task from the current page. Currently we have this class because * the corresponding method in D2W is protected. But it will be enhanced to * take the ERD2W interfaces into account. */ // FIXME ak We need to take the ERD2W interfaces into account protected String _taskFromPage(WOComponent page) { if (page == null) return null; if (page instanceof D2WPage) return ((D2WPage) page).task(); if (page instanceof EditRelationshipPageInterface) return "editRelationship"; if (page instanceof QueryPageInterface) return "query"; if (page instanceof ListPageInterface) return "list"; if (page instanceof EditPageInterface) return "edit"; if (page instanceof InspectPageInterface) return "inspect"; if (page instanceof SelectPageInterface) return "select"; return ""; } /** * Gets the entity name from the current page. Not that this does not go up * the component tree, but rather calls <code>entityName()</code> and * tries the "super" implementation if that fails. */ protected String _entityNameFromPage(WOComponent page) { if (page instanceof D2WPage) { try { return ((D2WPage) page).entityName(); } catch (Exception ex) { log.warn("Page " + page.getClass().getName() + " does not return an entityName(), please implement the method entityName() correctly"); } } return D2W.entityNameFromPage(page); } /** * Gets the <code>entityName</code> from the current page. Simply wrap the * factory method {@link #_entityNameFromPage(WOComponent)}. */ public static String entityNameFromPage(WOComponent page) { return ERD2WFactory.erFactory()._entityNameFromPage(page); } /** * Gets the <code>task</code> from the current page. Simply wrap the * factory method {@link #_taskFromPage(WOComponent)}. */ public static String taskFromPage(WOComponent page) { return ERD2WFactory.erFactory()._taskFromPage(page); } /** * Gets the <code>pageConfiguration</code> from the current page. Simply * wrap the factory method {@link #_pageConfigurationFromPage(WOComponent)}. */ public static String pageConfigurationFromPage(WOComponent page) { return ERD2WFactory.erFactory()._pageConfigurationFromPage(page); } }