/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Jetspeed" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache" or
* "Apache Jetspeed", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.jetspeed.modules.actions.controls;
// Turbine stuff
import org.apache.turbine.modules.Action;
import org.apache.turbine.util.RunData;
import org.apache.turbine.util.Log;
// Jetspeed stuff
import org.apache.jetspeed.portal.Portlet;
import org.apache.jetspeed.portal.PortletSet;
import org.apache.jetspeed.portal.PortletControl;
import org.apache.jetspeed.services.rundata.JetspeedRunData;
import org.apache.jetspeed.om.profile.Profile;
import org.apache.jetspeed.om.profile.ProfileLocator;
import org.apache.jetspeed.services.Profiler;
import org.apache.jetspeed.services.statemanager.SessionState;
import org.apache.jetspeed.util.template.JetspeedLink;
import org.apache.jetspeed.util.template.JetspeedLinkFactory;
import org.apache.jetspeed.services.security.PortalResource;
import org.apache.jetspeed.services.JetspeedSecurity;
import org.apache.jetspeed.om.security.JetspeedUser;
import java.util.Enumeration;
import java.util.Stack;
/**
* Handle Customization requests for the current portal page
*
* @author <a href="mailto:raphael@apache.org">Rapha�l Luta</a>
* @author <a href="mailto:paulsp@apache.org">Paul Spencer</a>
* @author <a href="mailto:ggolden@apache.org">Glenn R. Golden</a>
*/
public class Customize extends Action
{
/**
* @param rundata The RunData object for the current request
*/
public void doPerform( RunData rundata ) throws Exception
{
JetspeedRunData jdata = (JetspeedRunData)rundata;
if (jdata.getUser() == null)
{
return;
}
// read some parameters
String editMediaType = jdata.getParameters().getString ("mtype");
String resetStack = jdata.getParameters().getString ("reset");
String peid = jdata.getParameters().getString("js_peid");
// get the customization state for this page
SessionState customizationState = jdata.getPageSessionState();
// this will be the profile we are editing
Profile profile = null;
// the "reset" parameter's presence signals the start of customization
if ( (resetStack != null)
&& ((resetStack.equalsIgnoreCase("on")) || (resetStack.equalsIgnoreCase("1"))))
{
// clear out any prior customization state
jdata.cleanupFromCustomization();
}
// if we have not yet setup for customization, do so now
if (jdata.getCustomizedProfile() == null)
{
ProfileLocator locator = (ProfileLocator)jdata.getProfile().clone();
if (editMediaType != null)
{
locator.setMediaType(editMediaType);
}
// get a profile to edit
profile = (Profile) Profiler.getProfile(locator).clone();
jdata.setCustomizedProfile(profile);
}
// we are continuing an on-going customization
else
{
// get the profile we are working on
profile = jdata.getCustomizedProfile();
}
// Get js_peid parmameter.
// If it does not exist, we will customize the root of the profile
if ( peid == null )
{
// use the id of the root set of the profile
peid = profile.getRootSet().getID();
jdata.setJs_peid(peid);
}
// find the portlet within the profile with this peid %%% isn't there a better way to do this? -ggolden
Portlet found = null;
Stack sets = new Stack();
sets.push(profile.getRootSet());
while ((found==null) && (sets.size() > 0))
{
PortletSet set = (PortletSet)sets.pop();
if (set.getID().equals(peid))
{
found = set;
}
else
{
Enumeration en = set.getPortlets();
while((found==null) && en.hasMoreElements())
{
Portlet p = (Portlet)en.nextElement();
// unstack the controls to find the real PortletSets
Portlet real = p;
while (real instanceof PortletControl)
{
real = ((PortletControl)p).getPortlet();
}
if (real instanceof PortletSet)
{
if (real.getID().equals(peid))
{
found=real;
}
else
{
// we'll explore this set afterwards
sets.push(real);
}
}
else if (p.getID().equals(peid))
{
found = p;
}
}
}
}
if (found!=null)
{
PortalResource portalResource = new PortalResource(found);
try
{
JetspeedLink jsLink = JetspeedLinkFactory.getInstance(rundata);
portalResource.setOwner(jsLink.getUserName());
JetspeedLinkFactory.putInstance(jsLink);
}
catch (Exception e)
{
Log.warn(e.toString());
portalResource.setOwner(null);
}
if(!JetspeedSecurity.checkPermission((JetspeedUser) jdata.getUser(),
portalResource,
JetspeedSecurity.PERMISSION_CUSTOMIZE))
{
Log.warn("User " + jdata.getUser().getUserName() + " has no customize permission for portlet with id " + peid);
jdata.setMessage("Sorry, you have no customize permission for this portlet");
return;
}
jdata.setCustomized(found);
jdata.setScreenTemplate("Customize");
}
}
/**
* Save the current customization
* Used by any other customizer to get this done right!
*
* @deprecated. The customizers should handle the save themselves
*/
public static void save(RunData data)
{
try
{
Profile profile = ((JetspeedRunData) data).getCustomizedProfile();
profile.store();
}
catch (Exception e)
{
Log.error("Error while saving profile", e);
}
} // save
/**
* Exit the customizer.
* @deprecated. Exec the controls.EndCustomize action instead
*/
public static void exit(RunData data)
{
JetspeedLink jsLink = null;
((JetspeedRunData) data).cleanupFromCustomization();
// bring logged on user to homepage via HTTP redirect
try
{
jsLink = JetspeedLinkFactory.getInstance(data);
String mtype = data.getParameters().getString("mtype");
if (mtype != null)
{
jsLink.setMediaType(mtype);
jsLink.addQueryData("mtype", mtype);
}
}
catch (Exception e)
{
Log.error(e);
}
data.setRedirectURI(jsLink.toString());
JetspeedLinkFactory.putInstance(jsLink);
jsLink = null;
} // exit
}