/********************************************************************************** * $URL: https://source.sakaiproject.org/svn/site-manage/trunk/site-manage-link-helper/src/java/org/sakaiproject/site/tool/LinkAction.java $ * $Id: LinkAction.java 105080 2012-02-24 23:10:31Z ottenhoff@longsight.com $ *********************************************************************************** * * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008 The Sakai Foundation * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.opensource.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **********************************************************************************/ package org.sakaiproject.site.tool; import java.io.IOException; import java.util.Properties; import java.util.Iterator; import java.util.List; import java.util.ArrayList; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.sakaiproject.authz.api.AuthzGroup; import org.sakaiproject.authz.api.GroupNotDefinedException; import org.sakaiproject.authz.api.Role; import org.sakaiproject.authz.cover.AuthzGroupService; import org.sakaiproject.cheftool.Context; import org.sakaiproject.cheftool.JetspeedRunData; import org.sakaiproject.cheftool.RunData; import org.sakaiproject.cheftool.VelocityPortlet; import org.sakaiproject.cheftool.VelocityPortletPaneledAction; import org.sakaiproject.component.cover.ServerConfigurationService; import org.sakaiproject.entity.api.Reference; import org.sakaiproject.entity.cover.EntityManager; import org.sakaiproject.entity.api.ResourcePropertiesEdit; import org.sakaiproject.event.api.SessionState; import org.sakaiproject.exception.IdUnusedException; import org.sakaiproject.site.api.Site; import org.sakaiproject.site.api.SitePage; import org.sakaiproject.site.api.SiteService.SortType; import org.sakaiproject.site.api.ToolConfiguration; import org.sakaiproject.site.cover.SiteService; import org.sakaiproject.tool.api.Tool; import org.sakaiproject.tool.api.ToolException; import org.sakaiproject.tool.api.ToolSession; import org.sakaiproject.tool.api.Placement; import org.sakaiproject.tool.api.Session; import org.sakaiproject.tool.api.ToolSession; import org.sakaiproject.tool.cover.SessionManager; import org.sakaiproject.tool.cover.ToolManager; import org.sakaiproject.util.ResourceLoader; import org.sakaiproject.util.StringUtil; import org.sakaiproject.util.ParameterParser; import org.sakaiproject.user.api.User; import org.sakaiproject.user.api.UserNotDefinedException; import org.sakaiproject.user.cover.UserDirectoryService; /** * <p> * LinkAction allows site owners to link a site to a parent. * </p> */ public class LinkAction extends VelocityPortletPaneledAction { /** Resource bundle using current language locale */ protected static ResourceLoader rb = new ResourceLoader("link"); /** Name of state attribute for Site instance id */ private static final String STATE_SITE_INSTANCE_ID = "site.instance.id"; private static final Log logger = LogFactory.getLog(LinkAction.class); /** * Get the current site page our current tool is placed on. * * @return The site page id on which our tool is placed. */ protected String getCurrentSitePageId() { ToolSession ts = SessionManager.getCurrentToolSession(); if (ts != null) { ToolConfiguration tool = SiteService.findTool(ts.getPlacementId()); if (tool != null) { return tool.getPageId(); } } return null; } /** * Get the current site id * @param state SessionState * @throws SessionDataException * @return Site id (GUID) */ private String getSiteId(SessionState state) throws SessionDataException { // Check if it is state (i.e. we are a helper in site.info) String retval = (String) state.getAttribute(STATE_SITE_INSTANCE_ID); if ( retval != null ) return retval; // If it is not in state, we must be stand alone Placement placement = ToolManager.getCurrentPlacement(); if (placement == null) { throw new SessionDataException("No current tool placement"); } return placement.getContext(); } /** * Setup the velocity context and choose the template for the response. */ public String buildMainPanelContext(VelocityPortlet portlet, Context context, RunData rundata, SessionState state) { // set the resource bundle with our strings context.put("tlang", rb); context.put("doSave", BUTTON + "doSave"); context.put("doCancel", BUTTON + "doCancel"); context.put("doRemove", BUTTON + "doRemove"); try { Site site; String siteId = getSiteId(state); site = SiteService.getSite(siteId); String parentId = site.getProperties().getProperty("sakai:parent-id"); context.put("currentSite", site); if ( parentId != null ) { // Make sure parent site exists before we show it. // If the parent site does not exist, clear the property try { Site parentSite = SiteService.getSite(parentId); context.put("parentId", parentId); context.put("parentTitle", parentSite.getTitle()); return "sakai_link"; } catch (Exception e) { addAlert(state,rb.getFormattedMessage("alert.parent.removed", new Object[]{parentId})); ResourcePropertiesEdit rpe = site.getPropertiesEdit(); rpe.removeProperty("sakai:parent-id"); SiteService.save(site); } } // Give the user a list of sites to select as parent List<Site> sites = SiteService.getSites( org.sakaiproject.site.api.SiteService.SelectionType.UPDATE, null, null, null, SortType.TITLE_ASC, null); List<Site> goodSites = new ArrayList<Site> (); // Do not include any sites which point to us as a parent // Do not include ourself in the candidate list for (Iterator i = sites.iterator(); i.hasNext(); ) { Site thisSite = (Site) i.next(); String pid = thisSite.getProperties().getProperty("sakai:parent-id"); if ( siteId.equals(pid) ) continue; if ( siteId.equals(thisSite.getId()) ) continue; goodSites.add(thisSite); } if ( goodSites.size() > 0 ) context.put("sites", goodSites); } catch (Exception e) { addAlert(state,rb.getString("error.cannot.access")); } return "sakai_link"; } /** * Handle the configure context's update button */ public void doSave(RunData data, Context context) { // TODO: if we do limit the initState() calls, we need to make sure we get a new one after this call -ggolden String peid = ((JetspeedRunData) data).getJs_peid(); SessionState state = ((JetspeedRunData) data).getPortletSessionState(peid); ParameterParser params = data.getParameters(); String parentId = params.getString("parentSite"); if ( ! SiteService.allowUpdateSite(parentId) ) { addAlert(state,rb.getString("error.cannot.update")); return; } try { Site site; site = SiteService.getSite(getSiteId(state)); ResourcePropertiesEdit rpe = site.getPropertiesEdit(); rpe.addProperty("sakai:parent-id", parentId); SiteService.save(site); SessionManager.getCurrentToolSession().setAttribute(HELPER_LINK_MODE, HELPER_MODE_DONE); } catch (Exception e) { addAlert(state,rb.getString("error.cannot.update")); } } /** * doRemove - Clear the parent id value */ public void doRemove(RunData data, Context context) { // access the portlet element id to find our state String peid = ((JetspeedRunData) data).getJs_peid(); SessionState state = ((JetspeedRunData) data).getPortletSessionState(peid); try { Site site; site = SiteService.getSite(getSiteId(state)); ResourcePropertiesEdit rpe = site.getPropertiesEdit(); rpe.removeProperty("sakai:parent-id"); SiteService.save(site); SessionManager.getCurrentToolSession().setAttribute(HELPER_LINK_MODE, HELPER_MODE_DONE); } catch (Exception e) { addAlert(state,rb.getString("error.cannot.remove")); } } /** * doCancel called for form input tags type="submit" named="eventSubmit_doCancel" cancel the options process */ public void doCancel(RunData data, Context context) { // access the portlet element id to find our state String peid = ((JetspeedRunData) data).getJs_peid(); SessionState state = ((JetspeedRunData) data).getPortletSessionState(peid); SessionManager.getCurrentToolSession().setAttribute(HELPER_LINK_MODE, HELPER_MODE_DONE); } /** * Note a "local" problem (we failed to get session or site data) */ private static class SessionDataException extends Exception { public SessionDataException(String text) { super(text); } } }