/*==========================================================================*\
| $Id: PageWithNavigation.java,v 1.3 2011/03/07 18:44:37 stedwar2 Exp $
|*-------------------------------------------------------------------------*|
| Copyright (C) 2006-2011 Virginia Tech
|
| This file is part of Web-CAT.
|
| Web-CAT is free software; you can redistribute it and/or modify
| it under the terms of the GNU Affero General Public License as published
| by the Free Software Foundation; either version 3 of the License, or
| (at your option) any later version.
|
| Web-CAT is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU Affero General Public License
| along with Web-CAT; if not, see <http://www.gnu.org/licenses/>.
\*==========================================================================*/
package org.webcat.core;
import com.webobjects.appserver.*;
import com.webobjects.foundation.*;
import org.webcat.core.Application;
import org.webcat.core.BarePage;
import org.webcat.core.FeedbackPage;
import org.webcat.core.PageWithNavigation;
import org.webcat.core.Session;
import org.webcat.core.TabDescriptor;
import org.webcat.core.User;
import org.webcat.core.WCComponent;
import org.apache.log4j.Logger;
// -------------------------------------------------------------------------
/**
* A page wrapper for logged-in users that includes the standard header,
* tab-based navigation features, and footer. It inherits from
* BarePage (which is also uses), mostly to inherit all the same KVC
* keys, which it passes on to its BarePage container.
*
* @author Stephen Edwards
* @author Last changed by $Author: stedwar2 $
* @version $Revision: 1.3 $, $Date: 2011/03/07 18:44:37 $
*/
public class PageWithNavigation
extends BarePage
{
//~ Constructors ..........................................................
// ----------------------------------------------------------
/**
* Creates a new SimplePage object.
*
* @param context The page's context
*/
public PageWithNavigation( WOContext context )
{
super( context );
}
//~ KVC Attributes (must be public) .......................................
public TabDescriptor selectedRole;
public TabDescriptor secondLevelSelection;
public int tertiaryTabIndex;
public WCComponent thisPage;
public String sideStepTitle;
public boolean hideSteps = false;
// Repetition variables
public TabDescriptor primaryTabItem;
public TabDescriptor secondaryTabItem;
public TabDescriptor tertiaryTabItem;
public TabDescriptor aRole;
public int aRoleIndex;
//~ Methods ...............................................................
// ----------------------------------------------------------
/**
* Set up this component for this response.
* @see com.webobjects.appserver.WOComponent#awake()
*/
public void awake()
{
log.debug( "awake()" );
super.awake();
if ( thisPage == null )
{
WOComponent comp = context().page();
// initialize thisPage if needed
if ( comp instanceof WCComponent )
{
thisPage = (WCComponent)comp;
}
else
{
thisPage = null; // Will probably force a dirty crash
if ( log.isDebugEnabled() )
{
log.debug(
"top-level component "
+ ( ( comp == null )
? "<null>"
: comp.getClass().getName() )
+ " is not a WCComponent"
);
}
}
}
if ( myTab == null )
{
if (thisPage != null)
{
myTab = thisPage.currentTab();
TabDescriptor tabs = ( (Session)session() ).tabs;
selectedRole = tabs.selectedChild();
secondLevelSelection =
selectedRole.selectedChild().selectedChild();
}
if (selectedRole == null)
{
selectedRole = ( (Session)session() ).tabs.selectedChild();
}
if (myTab == null)
{
myTab = selectedRole.selectedDescendant();
secondLevelSelection =
selectedRole.selectedChild().selectedChild();
}
bodyClass = "staff"; // myTab.cssClass();
}
if ( title == null && thisPage != null )
{
title = thisPage.title();
}
if ( title == null )
{
title = myTab.label();
}
}
// ----------------------------------------------------------
public void appendToResponse( WOResponse arg0, WOContext arg1 )
{
if ( sideStepTitle != null )
{
title = sideStepTitle;
}
super.appendToResponse( arg0, arg1 );
}
// ----------------------------------------------------------
/**
* Log's the user out of the current session.
* @return A redirect to the main login page, after terminating this
* session
*/
public WOComponent logout()
{
if ( ( (Session)session() ).user() != null )
{
log.info( "user "
+ ( (Session)session() ).user().userName()
+ " logging out" );
( (Session)session() ).userLogout();
}
return Application.wcApplication().gotoLoginPage( context() );
}
// ----------------------------------------------------------
/**
* Determine whether this page has a set title.
*
* @return True if there is a title
*/
public boolean hasTitle()
{
return ( title != null );
}
// ----------------------------------------------------------
/**
* Retrieve the URL for this page's help information.
* This value is extracted from this page's WCComponent.
*
* @return The desired URL
*/
public String helpURL()
{
if ( helpURL == null )
{
if ( thisPage != null )
{
helpURL = thisPage.helpURL();
}
else
{
return WCComponent.helpBaseURL();
}
boolean hasQ = false;
if ( secondLevelSelection != null )
{
helpURL += "?t1=" + secondLevelSelection.parent().parent()
.selectedChildIndex()
+ "&t2="
+ secondLevelSelection.parent().selectedChildIndex();
hasQ = true;
if ( hasSteps() )
{
helpURL += "&t3="
+ secondLevelSelection.selectedChildIndex();
}
}
User user = ( (Session) session()).user();
if ( user != null )
{
if ( !hasQ ) { helpURL += "?"; hasQ = true; }
else { helpURL += "&"; }
helpURL += "ua=" + user.accessLevel();
}
}
return helpURL;
}
// ----------------------------------------------------------
/**
* Retrieve a sentence-case version of the page's side-step title,
* where only the first letter is capitalized.
*
* @return The title in sentence case
*/
public String lcSideStepTitle()
{
return TabDescriptor.lowerCaseAfterFirst( sideStepTitle );
}
// ----------------------------------------------------------
/**
* Go to the feedback form, and record the necessary information about
* this page as the originating source.
*
* @return The feedback form page
*/
public WOComponent goToFeedback()
{
FeedbackPage feedbackPage = (FeedbackPage)pageWithName(
( (Session)session() ).tabs.selectById( "Feedback" ).pageName() );
feedbackPage.pageTitle = title;
feedbackPage.extraInfo = Application.extraInfoForContext( context() );
return feedbackPage;
}
// ----------------------------------------------------------
/**
* Retrieve the CSS class to use for the list item for a primary tab.
* @return The CSS class
*/
public String primaryTabClass()
{
if ( primaryTabItem.isSelected() )
return "here1";
else
return primaryTabItem.cssClass();
}
// ----------------------------------------------------------
/**
* Determine if the current primary tab can be seen by this user
* (enforce tab hiding when user has toggled to student-only view).
* @return True if this primary tab can be seen
*/
public boolean primaryTabIsVisible()
{
return primaryTabItem.accessLevel() == 0
|| !( (Session)session() ).user().restrictToStudentView();
}
// ----------------------------------------------------------
/**
* Determine if the current secondary tab can be seen by this user
* (enforce tab hiding when user has toggled to student-only view).
* @return True if this secondary tab can be seen
*/
public boolean secondaryTabIsVisible()
{
return secondaryTabItem.accessLevel() == 0
|| !( (Session)session() ).user().restrictToStudentView();
}
// ----------------------------------------------------------
/**
* Retrieve the CSS class to use for the list item for a secondary tab.
* @return The CSS class
*/
public String secondaryTabClass()
{
if ( secondaryTabItem.isSelected() )
return "here2";
else
return secondaryTabItem.parent().cssClass();
}
// ----------------------------------------------------------
/**
* Follow the link for a primary tab.
* @return the new component
*/
public WOComponent primaryTabLink()
{
if (thisPage != null)
{
thisPage.changeWorkflow();
}
return pageWithName( primaryTabItem.selectDefault().pageName() );
}
// ----------------------------------------------------------
/**
* Follow the link for a primary tab.
* @return the new component
*/
public WOComponent switchRole()
{
if (thisPage != null)
{
thisPage.changeWorkflow();
}
return pageWithName(
aRole.selectDefault().selectedDescendant().pageName() );
}
// ----------------------------------------------------------
/**
* Follow the link for a secondary tab.
* @return the new component
*/
public WOComponent secondaryTabLink()
{
if (thisPage != null)
{
thisPage.changeWorkflow();
}
return pageWithName( secondaryTabItem.selectDefault().pageName() );
}
// ----------------------------------------------------------
/**
* Follow the link for a tertiary tab (a wizard step).
* @return the new component
*/
public WOComponent stepLink()
{
return pageWithName( tertiaryTabItem.selectDefault().pageName() );
}
// ----------------------------------------------------------
/**
* Check whether there is a title for a diversionary "side step".
* @return True if we are on a detour in wizard page sequencing
*/
public boolean isSideStep()
{
return sideStepTitle != null && stepIsSelected();
}
// ----------------------------------------------------------
/**
* Determing whether the "Step" menu for third-level tabs should be
* displayed on this page.
* @return True if the step menu should be shown
*/
public boolean hasSteps()
{
return !hideSteps
&& secondLevelSelection != null
&& secondLevelSelection.children().count() > 0;
}
// ----------------------------------------------------------
/**
* Check whether a third-level tab (wizard step) requires a hyperlink.
* @return True if the third-level tab comes before the currently
* selected third level tab
*/
public boolean stepUsesLink()
{
return tertiaryTabIndex < secondLevelSelection.selectedChildIndex()
|| ( tertiaryTabIndex == secondLevelSelection.selectedChildIndex()
&& isSideStep() );
}
// ----------------------------------------------------------
/**
* Returns true for the currently-selected tertiary tab (a wizard step).
* @return True if this wizard step is selected
*/
public boolean stepIsSelected()
{
return tertiaryTabIndex == secondLevelSelection.selectedChildIndex();
}
// ----------------------------------------------------------
/**
* Generate the string representation of the third-level tab number.
* @return the step number
*/
public String tertiaryNumeral()
{
return "" + ( tertiaryTabIndex + 1 );
}
// ----------------------------------------------------------
public void pushValuesToParent()
{
// Make sure to handle logout actions on form pages correctly
// by blocking value pushing if the session is terminating
if ( hasSession() && !session().isTerminating() )
{
super.pushValuesToParent();
}
}
// ----------------------------------------------------------
public boolean hasVisibleSecondaryTabs()
{
boolean result = false;
Session session = (Session)session();
if ( session.user() == null || session.user().restrictToStudentView() )
{
NSArray<TabDescriptor> secondaries = selectedRole.selectedChild()
.children();
for (TabDescriptor secondary : secondaries)
{
if ( secondary.accessLevel() == 0 )
{
result = true;
break;
}
}
}
else
{
result = selectedRole.selectedChild().children()
.count() > 0;
}
return result;
}
// ----------------------------------------------------------
/**
* Toggle the student view setting for this user.
* @return Returns null, to force reloading of the calling page
* (if desired)
*/
public WOComponent toggleStudentView()
{
( (Session)session() ).toggleStudentView();
return pageWithName(
( (Session)session() ).tabs.selectedDescendant().pageName() );
}
// ----------------------------------------------------------
@Override
public WOComponent pageWithName( String name )
{
if (log.isDebugEnabled())
{
log.debug("pageWithName(" + name + ")");
}
return (thisPage == null)
? super.pageWithName(name)
: thisPage.pageWithName(name);
}
//~ Instance/static variables .............................................
private TabDescriptor myTab;
private String helpURL;
static Logger log = Logger.getLogger( PageWithNavigation.class );
}