/* Copyright 2005 The JA-SIG Collaborative. All rights reserved.
* See license distributed with this file and
* available online at http://www.uportal.org/license.html
*/
package org.jasig.portal.channels.cusermanager;
import java.util.Enumeration;
import java.text.MessageFormat;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasig.portal.IChannel;
import org.jasig.portal.security.IPerson;
import org.jasig.portal.security.IPermission;
import org.jasig.portal.security.provider.PersonImpl;
//import edu.cornell.uportal.channels.cusermanager.provider.PersonImpl;
import org.jasig.portal.ChannelStaticData;
import org.jasig.portal.ChannelRuntimeData;
import org.jasig.portal.ChannelRuntimeProperties;
import org.jasig.portal.PortalEvent;
import org.jasig.portal.PortalException;
import org.jasig.portal.IPermissible;
import org.jasig.portal.AuthorizationException;
import org.jasig.portal.utils.XSLT;
import org.jasig.portal.utils.DocumentFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.ContentHandler;
/**
* @author smb1@cornell.edu
* @version $Revision: 1.6.2.1 $ $Date: 2005/08/05 18:39:26 $
*/
public class CUserManager extends CUserManagerPermissions implements IChannel, IPermissible {
private static final Log LOG = LogFactory.getLog(CUserManager.class);
private IDataHandler datasource;
private String mode = Constants.MODEDISPLAY;
private ChannelStaticData CSD;
private ChannelRuntimeData CRD;
private boolean ManagerMode = false;
private boolean PwdChngMode = true;
private PortalEvent lastEvent;
/** for pwd chng mode, we want to cache the user's info because
* there will be many more of these than admin channels
*/
private Document PersonalDocument = null;
/**
*/
public CUserManager() {
}// CUserManager
/**
* Returns channel runtime properties.
* Satisfies implementation of Channel Interface.
*
* @return handle to runtime properties
*/
public ChannelRuntimeProperties getRuntimeProperties() {
return new ChannelRuntimeProperties();
}// getRuntimeProperties
/**
* Process layout-level events coming from the portal.
* Satisfies implementation of IChannel Interface.
*
* @param PortalEvent ev a portal layout event
*/
public void receiveEvent(PortalEvent ev) {
this.lastEvent = ev;
}// receiveEvent
/**
* Receive static channel data from the portal.
* Satisfies implementation of IChannel Interface.
*
* @param ChannelStaticData sd static channel data
*/
public void setStaticData(ChannelStaticData sd) {
CSD = sd;
// Ignore since 2.0 (2003.04.21)
// if( CSD.getParameter( Constants.CHNPARAMNOTMGR ) != null )
// ManagerMode = false;
// let determine the user's rights
try{
IPermission[] perms = CSD.getAuthorizationPrincipal().getAllPermissions(
Constants.PERMISSION_OWNERTOKEN, null, Constants.PERMISSION_OWNERTARGET );
for( int i = 0; i < perms.length; i++ ) {
if( perms[ i ].getActivity().equals( Constants.PERMISSION_MNGRRIGHT )
&& perms[ i ].getType().equals( IPermission.PERMISSION_TYPE_GRANT ))
ManagerMode = true;
if( perms[ i ].getActivity().equals( Constants.PERMISSION_PWDCHNGRIGHT )
&& perms[ i ].getType().equals( IPermission.PERMISSION_TYPE_DENY ))
PwdChngMode = false;
}// for
}catch( AuthorizationException ae ){
LOG.error(ae,ae);
}
}// setStaticData
/**
* Receive channel runtime data from the portal.
* Satisfies implementation of IChannel Interface.
*
* @param ChannelRuntimeData rd handle to channel runtime data
*/
public void setRuntimeData(ChannelRuntimeData rd) {
CRD = rd;
}// setRuntimeData
/** Output channel content to the portal
* @param out a sax document handler
*/
public void renderXML(ContentHandler out) throws PortalException {
// first, be sure they are allowed to be here
if( !ManagerMode && !PwdChngMode )
throw new AuthorizationException( MessageFormat.format(
Constants.ERRMSG_NORIGHTS, new Object[]
{ (String)CSD.getPerson().getAttribute( IPerson.USERNAME ) } ));
try{
String message_to_user_about_action = ""; // these always start blank
Document doc = null;
IPerson[] people = null;
mode = Constants.MODEDISPLAY;
// now, b4 we get going, there may have been an event to deal with
if( CRD.getParameter( Constants.FORMACTION ) == null && lastEvent != null ) {
if( lastEvent.getEventNumber() == PortalEvent.ABOUT_BUTTON_EVENT )
CRD.setParameter( Constants.FORMACTION, "10" );
if( lastEvent.getEventNumber() == PortalEvent.HELP_BUTTON_EVENT )
CRD.setParameter( Constants.FORMACTION, "11" );
lastEvent = null; // don't need that anymore
}// if, null & !null
// see if we have form data to process
if( CRD.getParameter( Constants.FORMACTION ) != null ){
LOG.debug("form.action=" + CRD.getParameter( Constants.FORMACTION ));
switch( Integer.parseInt( CRD.getParameter( Constants.FORMACTION ))) {
case 1: { // update
getDataSource().setUserInformation( crd2persion( CRD ));
message_to_user_about_action = Constants.MSG_SAVED;
break;
}// 1
case 2: { // choose
mode = Constants.MODEDISPLAY;
break;
}// 2
case 3: { // choose
people = getDataSource().getAllUsers();
mode = Constants.MODECHOOSE;
break;
}// 3
case 4: { // search
if( CRD.getParameter( Constants.FORMSRCHSTR ) == null ) {
people = new PersonImpl[0];
mode = Constants.MODESEARCH;
}else{
// if they did not enter a src str, display mode
people = getDataSource().getAllUsersLike(
CRD.getParameter( Constants.FORMSRCHSTR ));
if( people.length == 1 ) {
// this will cause a second lookup but the user experience will benifit
mode = Constants.MODEDISPLAY;
CRD.setParameter( Constants.UNFIELD,
(String)people[0].getAttribute( Constants.UNFIELD ));
}else
mode = Constants.MODECHOOSE; // they will need to select to narrow
}// if
break;
}// 4
case 5: { // prepare add new user
CRD.setParameter( Constants.UNFIELD,(String)
CSD.getPerson().getAttribute( Constants.ATTRUSERNAME ));
mode = Constants.MODEADD;
break;
}// 5
case 6: { // add new user
try{ getDataSource().addUser( crd2persion( CRD ));
}catch( Exception adde ) {
if( adde.getMessage().indexOf( Constants.ALREADY_EXISTS ) > -1 )
message_to_user_about_action = adde.getMessage();
else
throw adde;
}// catch
mode = Constants.MODEDISPLAY;
break;
}// 6
case 7: { // prepare password chng
people = new IPerson[] { getDataSource().getUser(
CRD.getParameter( Constants.UNFIELD )) };
mode = Constants.MODEPWDCHNG;
break;
}// 7
case 8: { // password chng
message_to_user_about_action = Constants.MSG_PWD_SAVED;
try{
getDataSource().setUserPassword( crd2persion( CRD ),
( ManagerMode?null: CRD.getParameter( Constants.PWDFIELD )));
}catch( Exception pwdchng ) {
if( pwdchng.getMessage()
.equals( Constants.ERRMSG_PWDNOTMATACHED ))
message_to_user_about_action = pwdchng.getMessage();
else
throw pwdchng;
}// catch
mode = Constants.MODEDISPLAY;
PersonalDocument = null;
break;
}// 8
case 9: { // delete user
getDataSource().removeUser( crd2persion( CRD ));
mode = Constants.MODEDISPLAY;
PersonalDocument = null;
break;
}// 9
case 10: { // about
mode = Constants.MODEABOUT;
break;
}// 10
case 11: { // help
mode = Constants.MODEHELP;
break;
}// 11
default: {
mode = Constants.MODEDISPLAY;
CRD.remove( Constants.UNFIELD );
}// default
}// switch
}// if
if( !ManagerMode && PersonalDocument == null
&& !mode.equals(Constants.MODEABOUT) && !mode.equals(Constants.MODEHELP) ) // always override
mode = Constants.MODEDISPLAY; // force a read
// look up the person we are supposed to display
if( mode.equals( Constants.MODEDISPLAY ) || mode.equals( Constants.MODEADD ))
people = new IPerson[] { getDataSource().getUser(
( CRD.getParameter( Constants.FORMCHOSEN ) == null?
( CRD.getParameter( Constants.UNFIELD ) == null?
(String)CSD.getPerson().getAttribute( Constants.ATTRUSERNAME )
: CRD.getParameter( Constants.UNFIELD ))
: CRD.getParameter( Constants.FORMCHOSEN ) )) };
if( !ManagerMode && !mode.equals(Constants.MODEABOUT) && !mode.equals(Constants.MODEHELP) ) // always override
mode = Constants.MODEPWDCHNG;
if( (ManagerMode || ( !ManagerMode && PersonalDocument == null ))
&& !mode.equals(Constants.MODEABOUT) && !mode.equals(Constants.MODEHELP) ) {
doc = DocumentFactory.getNewDocument();
// fill in info about the user
Element outtermost = doc.createElement( "people" );
Element person;
for( int i = 0; i < people.length; i++ ) {
person = doc.createElement( "person" );
Element attr = null;
String worker = null;
Enumeration E = people[ i ].getAttributeNames();
while( E.hasMoreElements()) {
worker = (String)E.nextElement();
attr = doc.createElement( worker );
attr.appendChild( doc.createTextNode(
(String)people[ i ].getAttribute( worker )));
person.appendChild( attr );
}// while
outtermost.appendChild( person );
}// for
doc.appendChild( outtermost );
// end - fill in info about the user
if( !ManagerMode )
PersonalDocument = doc;
}else{
doc = PersonalDocument;
}// if
// Create a new XSLT styling engine
XSLT xslt = XSLT.getTransformer( this, CRD.getLocales());
// XSLT xslt = new XSLT( this );
// we could have a blank document, help and about
if( doc == null ) {
doc = DocumentFactory.getNewDocument();
doc.appendChild( doc.createElement( mode )); // null;
}// doc null
// pass the result XML to the styling engine.
xslt.setXML( doc );
// specify the stylesheet selector
xslt.setXSL( Constants.SSLFILE, mode, CRD.getBrowserInfo());
// set parameters that the stylesheet needs.
xslt.setStylesheetParameter( Constants.BASEACTION, CRD.getBaseActionURL());
xslt.setStylesheetParameter( Constants.MODE, mode );
xslt.setStylesheetParameter(
Constants.DISPLAYMESSAGE, message_to_user_about_action );
String MM = (!ManagerMode?"yes":"no");
xslt.setStylesheetParameter( Constants.MODEUSRPWDCHNG, MM );
/** If I write the above as shown below it does not work. Wasted a .5hr on that! */
// xslt.setStylesheetParameter( Constants.MODEUSRPWDCHNG, (!ManagerMode?"yes":"no"));
// set the output Handler for the output.
xslt.setTarget( out );
// do the deed
xslt.transform();
}catch( Exception e ){
LOG.error(e,e);
throw new PortalException(
(e.getMessage()!=null?e.getMessage():e.toString()));
}// catch
}// renderXML
private IDataHandler getDataSource() throws Exception {
if( datasource == null )
datasource = (IDataHandler)
Class.forName(
(
CSD.getParameter( Constants.CHNPARAMDATAHANDLER ) == null?
Constants.DEFAULTDATAHANDLER
:
CSD.getParameter( Constants.CHNPARAMDATAHANDLER )
)
).newInstance();
return datasource;
}// getDataSource
private IPerson crd2persion( ChannelRuntimeData CRD ) throws Exception {
String worker = null;
IPerson newborn = new PersonImpl();
Enumeration E = CRD.getParameterNames();
while( E.hasMoreElements()){
worker = (String)E.nextElement();
if( !worker.equals( Constants.FORMACTION ))
newborn.setAttribute( worker,
( CRD.getParameter( worker ) == null?
"" : CRD.getParameter( worker ) ));
}// while
return newborn;
}// crd2persion
}// eoc