/**********************************************************************************
* $URL: $
* $Id: $
***********************************************************************************
*
* Copyright (c) 2006, 2007, 2008, 2009 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.content.tool;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.ComponentManager;
import org.sakaiproject.component.cover.ServerConfigurationService;
import org.sakaiproject.content.api.*;
import org.sakaiproject.content.api.GroupAwareEntity.AccessMode;
import org.sakaiproject.content.cover.ContentHostingService;
import org.sakaiproject.content.util.ZipContentUtil;
import org.sakaiproject.entity.api.Entity;
import org.sakaiproject.entity.api.ResourceProperties;
import org.sakaiproject.entity.api.ResourcePropertiesEdit;
import org.sakaiproject.entity.cover.EntityManager;
import org.sakaiproject.event.api.SessionState;
import org.sakaiproject.event.cover.NotificationService;
import org.sakaiproject.exception.IdUnusedException;
import org.sakaiproject.exception.OverQuotaException;
import org.sakaiproject.exception.PermissionException;
import org.sakaiproject.site.api.Site;
import org.sakaiproject.site.api.SitePage;
import org.sakaiproject.site.api.ToolConfiguration;
import org.sakaiproject.site.cover.SiteService;
import org.sakaiproject.time.api.Time;
import org.sakaiproject.time.cover.TimeService;
import org.sakaiproject.tool.api.Placement;
import org.sakaiproject.tool.api.Tool;
import org.sakaiproject.tool.api.ToolException;
import org.sakaiproject.tool.api.ToolSession;
import org.sakaiproject.tool.cover.SessionManager;
import org.sakaiproject.tool.cover.ToolManager;
import org.sakaiproject.util.FileItem;
import org.sakaiproject.util.FormattedText;
import org.sakaiproject.util.ParameterParser;
import org.sakaiproject.util.ResourceLoader;
import org.sakaiproject.util.Validator;
public class ResourcesHelperAction extends VelocityPortletPaneledAction
{
/** the logger for this class */
private static final Log logger = LogFactory.getLog(ResourcesHelperAction.class);
private static final ResourceConditionsHelper conditionsHelper = new ResourceConditionsHelper();
/** Resource bundle using current language locale */
private static ResourceLoader rb = new ResourceLoader("types");
private static ResourceLoader contentResourceBundle = new ResourceLoader("content");
protected static final String ACCESS_HTML_TEMPLATE = "resources/sakai_access_html";
protected static final String ACCESS_TEXT_TEMPLATE = "resources/sakai_access_text";
protected static final String ACCESS_UPLOAD_TEMPLATE = "resources/sakai_access_upload";
protected static final String ACCESS_URL_TEMPLATE = "resources/sakai_access_url";
/** copyright path -- MUST have same value as AccessServlet.COPYRIGHT_PATH */
public static final String COPYRIGHT_PATH = Entity.SEPARATOR + "copyright";
private static final String COPYRIGHT_ALERT_URL = ServerConfigurationService.getAccessUrl() + COPYRIGHT_PATH;
protected static final String CREATE_FOLDERS_TEMPLATE = "resources/sakai_create_folders";
protected static final String CREATE_HTML_TEMPLATE = "resources/sakai_create_html";
protected static final String CREATE_TEXT_TEMPLATE = "resources/sakai_create_text";
protected static final String CREATE_UPLOAD_TEMPLATE = "resources/sakai_create_upload";
protected static final String CREATE_UPLOADS_TEMPLATE = "resources/sakai_create_uploads";
protected static final String CREATE_URL_TEMPLATE = "resources/sakai_create_url";
protected static final String CREATE_URLS_TEMPLATE = "resources/sakai_create_urls";
public static final String MODE_MAIN = "main";
protected static final String PREFIX = "ResourceTypeHelper.";
protected static final String REVISE_HTML_TEMPLATE = "resources/sakai_revise_html";
protected static final String REVISE_TEXT_TEMPLATE = "resources/sakai_revise_text";
protected static final String REVISE_UPLOAD_TEMPLATE = "resources/sakai_revise_upload";
protected static final String REVISE_URL_TEMPLATE = "resources/sakai_revise_url";
protected static final String REPLACE_CONTENT_TEMPLATE = "resources/sakai_replace_file";
protected static final String MAKE_SITE_PAGE_TEMPLATE = "resources/sakai_make_site_page";
protected static final String ERROR_PAGE_TEMPLATE = "resources/sakai_error_page";
/** The content type image lookup service in the State. */
private static final String STATE_CONTENT_TYPE_IMAGE_SERVICE = PREFIX + "content_type_image_service";
private static final String STATE_COPYRIGHT_FAIRUSE_URL = PREFIX + "copyright_fairuse_url";
private static final String STATE_COPYRIGHT_NEW_COPYRIGHT = PREFIX + "new_copyright";
/** copyright related info */
private static final String STATE_COPYRIGHT_TYPES = PREFIX + "copyright_types";
private static final String STATE_DEFAULT_COPYRIGHT = PREFIX + "default_copyright";
private static final String STATE_DEFAULT_COPYRIGHT_ALERT = PREFIX + "default_copyright_alert";
/** state attribute for the maximum size for file upload */
static final String STATE_FILE_UPLOAD_MAX_SIZE = PREFIX + "file_upload_max_size";
/** The user copyright string */
private static final String STATE_MY_COPYRIGHT = PREFIX + "mycopyright";
private static final String STATE_NEW_COPYRIGHT_INPUT = PREFIX + "new_copyright_input";
/** state attribute indicating whether users in current site should be denied option of making resources public */
private static final String STATE_PREVENT_PUBLIC_DISPLAY = PREFIX + "prevent_public_display";
/** state attribute indicating whether we're using the Creative Commons dialog instead of the "old" copyright dialog */
protected static final String STATE_USING_CREATIVE_COMMONS = PREFIX + "usingCreativeCommons";
/** name of state attribute for the default retract time */
protected static final String STATE_DEFAULT_RETRACT_TIME = PREFIX + "default_retract_time";
/** The title of the new page to be created in the site */
protected static final String STATE_PAGE_TITLE = PREFIX + "page_title";
public String buildAccessContext(VelocityPortlet portlet,
Context context,
RunData data,
SessionState state)
{
logger.debug(this + ".buildAccessContext()");
String template = ACCESS_TEXT_TEMPLATE;
return template;
}
public String buildCreateContext(VelocityPortlet portlet,
Context context,
RunData data,
SessionState state)
{
logger.debug(this + ".buildCreateContext()");
String template = CREATE_UPLOAD_TEMPLATE;
ToolSession toolSession = SessionManager.getCurrentToolSession();
ResourceToolActionPipe pipe = (ResourceToolActionPipe) toolSession.getAttribute(ResourceToolAction.ACTION_PIPE);
context.put(ResourcesAction.PIPE_INIT_ID, pipe.getInitializationId());
//Reference reference = (Reference) toolSession.getAttribute(ResourceToolAction.COLLECTION_REFERENCE);
String typeId = pipe.getAction().getTypeId();
ListItem parent = new ListItem(pipe.getContentEntity());
if(parent.isDropbox)
{
String dropboxNotificationsProperty = getDropboxNotificationsProperty();
context.put("dropboxNotificationAllowed", Boolean.valueOf(ResourcesAction.DROPBOX_NOTIFICATIONS_ALLOW.equals(dropboxNotificationsProperty)));
}
if(ResourceType.TYPE_TEXT.equals(typeId))
{
template = CREATE_TEXT_TEMPLATE;
}
else if(ResourceType.TYPE_HTML.equals(typeId))
{
template = CREATE_HTML_TEMPLATE;
}
else if(ResourceType.TYPE_URL.equals(typeId))
{
template = CREATE_URL_TEMPLATE;
}
else // assume ResourceType.TYPE_UPLOAD
{
template = CREATE_UPLOAD_TEMPLATE;
}
int requestStateId = ResourcesAction.preserveRequestState(state, new String[]{ResourcesAction.PREFIX + ResourcesAction.REQUEST});
context.put("requestStateId", requestStateId);
return template;
}
public String buildMainPanelContext(VelocityPortlet portlet,
Context context,
RunData data,
SessionState state)
{
logger.debug(this + ".buildMainPanelContext()");
// context.put("sysout", System.out);
context.put("tlang", rb);
context.put("validator", new Validator());
context.put("copyright_alert_url", COPYRIGHT_ALERT_URL);
context.put("DOT", ListItem.DOT);
context.put("calendarMap", new HashMap());
String ezproxy = ServerConfigurationService.getString("content.ezproxy.prefix", "");
if (ezproxy != null && ezproxy != "") {
context.put("ezproxyPrefix", ezproxy);
} else {
context.put("ezproxyPrefix", false);
}
context.put("dateFormat", getDateFormatString());
String mode = (String) state.getAttribute(ResourceToolAction.STATE_MODE);
if (mode == null)
{
initHelper(portlet, context, data, state);
}
if(state.getAttribute(ResourcesAction.STATE_MESSAGE) != null)
{
context.put("itemAlertMessage", state.getAttribute(ResourcesAction.STATE_MESSAGE));
state.removeAttribute(ResourcesAction.STATE_MESSAGE);
}
ContentTypeImageService contentTypeImageService = (ContentTypeImageService) state.getAttribute(STATE_CONTENT_TYPE_IMAGE_SERVICE);
context.put("contentTypeImageService", contentTypeImageService);
ToolSession toolSession = SessionManager.getCurrentToolSession();
ResourceToolActionPipe pipe = (ResourceToolActionPipe) toolSession.getAttribute(ResourceToolAction.ACTION_PIPE);
if(pipe == null)
{
String attributes = "ResourcesHelperAction.buildMainPanelContext() SAK-8449 dump of state.attributes:\n";
List<String> attrNames = state.getAttributeNames();
for(String attrName : attrNames)
{
Object val = state.getAttribute(attrName);
if(val instanceof Collection)
{
int i = 0;
for(Object obj : (Collection) val)
{
attributes += "\t" + attrName + "[" + i + "] ==> " + obj + "\n";
i++;
}
}
else
{
attributes += "\t" + attrName + " ==> " + val + "\n";
}
}
attributes += "ResourcesHelperAction.buildMainPanelContext() SAK-8449 dump of toolSession.attributes:\n";
Enumeration toolNames = toolSession.getAttributeNames();
while(toolNames.hasMoreElements())
{
String name = (String) toolNames.nextElement();
Object val = toolSession.getAttribute(name);
if(val instanceof Collection)
{
int i = 0;
for(Object obj : (Collection) val)
{
attributes += "\t" + name + "[" + i + "] ==> " + obj + "\n";
i++;
}
}
else
{
attributes += "\t" + name + " ==> " + val + "\n";
}
}
logger.debug(attributes, new Throwable());
return ERROR_PAGE_TEMPLATE;
}
if(pipe.isActionCompleted())
{
return null;
}
context.put(ResourcesAction.PIPE_INIT_ID, pipe.getInitializationId());
String actionId = pipe.getAction().getId();
context.put("GROUP_ACCESS", AccessMode.GROUPED);
context.put("SITE_ACCESS", AccessMode.SITE);
context.put("INHERITED_ACCESS", AccessMode.INHERITED);
context.put("TYPE_FOLDER", ResourceType.TYPE_FOLDER);
context.put("TYPE_HTML", ResourceType.TYPE_HTML);
context.put("TYPE_TEXT", ResourceType.TYPE_TEXT);
context.put("TYPE_UPLOAD", ResourceType.TYPE_UPLOAD);
context.put("TYPE_URL", ResourceType.TYPE_URL);
String template = "";
switch(pipe.getAction().getActionType())
{
case CREATE:
template = buildCreateContext(portlet, context, data, state);
break;
case REVISE_CONTENT:
template = buildReviseContext(portlet, context, data, state);
break;
case REPLACE_CONTENT:
template = buildReplaceContext(portlet, context, data, state);
break;
case NEW_UPLOAD:
template = buildUploadFilesContext(portlet, context, data, state);
break;
case NEW_FOLDER:
template = buildNewFoldersContext(portlet, context, data, state);
break;
case NEW_URLS:
template = buildNewUrlsContext(portlet, context, data, state);
break;
case MAKE_SITE_PAGE:
template = buildMakeSitePageContext(portlet, context, data, state);
break;
default:
// hmmmm
logger.info(this + "hmmm");
template = buildMakeSitePageContext(portlet, context, data, state);
break;
}
return template;
}
public String buildMakeSitePageContext(VelocityPortlet portlet, Context context,
RunData data, SessionState state) {
logger.debug(this + ".buildMakeSitePage()");
int requestStateId = ResourcesAction.preserveRequestState(state, new String[]{ResourcesAction.PREFIX + ResourcesAction.REQUEST});
context.put("requestStateId", requestStateId);
context.put("page", state.getAttribute(STATE_PAGE_TITLE));
return MAKE_SITE_PAGE_TEMPLATE;
}
public void doMakeSitePage(RunData data) {
SessionState state = ((JetspeedRunData)data).getPortletSessionState (((JetspeedRunData)data).getJs_peid ());
ParameterParser params = data.getParameters ();
ToolSession toolSession = SessionManager.getCurrentToolSession();
ResourceToolActionPipe pipe = (ResourceToolActionPipe) toolSession.getAttribute(ResourceToolAction.ACTION_PIPE);
String url = pipe.getContentEntity().getUrl();
String title = params.getString("page");
if (title == null || title.trim().length() == 0)
{
addAlert(state, rb.getString("alert.page.empty"));
return;
}
state.setAttribute(STATE_PAGE_TITLE, title);
Placement placement = ToolManager.getCurrentPlacement();
String context = null;
if (placement != null)
{
context = placement.getContext();
try {
Tool tr = ToolManager.getTool("sakai.iframe");
Site site = SiteService.getSite(context);
for (SitePage page: (List<SitePage>)site.getPages()) {
if (title.equals(page.getTitle())) {
addAlert(state, rb.getString("alert.page.exists"));
return;
}
}
SitePage newPage = site.addPage();
newPage.setTitle(title);
ToolConfiguration tool = newPage.addTool();
tool.setTool("sakai.iframe", tr);
tool.setTitle(title);
tool.getPlacementConfig().setProperty("source", url);
SiteService.save(site);
scheduleTopRefresh();
toolSession.setAttribute(ResourceToolAction.DONE, Boolean.TRUE);
} catch (IdUnusedException e) {
logger.warn("Somehow we couldn't find the site.", e);
} catch (PermissionException e) {
logger.info("No permission to add page.", e);
addAlert(state, rb.getString("alert.page.permission"));
}
}
}
protected String buildNewUrlsContext(VelocityPortlet portlet, Context context, RunData data, SessionState state)
{
logger.debug(this + ".buildNewUrlsContext()");
ToolSession toolSession = SessionManager.getCurrentToolSession();
MultiFileUploadPipe pipe = (MultiFileUploadPipe) toolSession.getAttribute(ResourceToolAction.ACTION_PIPE);
context.put(ResourcesAction.PIPE_INIT_ID, pipe.getInitializationId());
List<ResourceToolActionPipe> pipes = pipe.getPipes();
Time defaultRetractDate = (Time) state.getAttribute(STATE_DEFAULT_RETRACT_TIME);
if(defaultRetractDate == null)
{
defaultRetractDate = TimeService.newTime();
state.setAttribute(STATE_DEFAULT_RETRACT_TIME, defaultRetractDate);
}
Boolean preventPublicDisplay = (Boolean) state.getAttribute(STATE_PREVENT_PUBLIC_DISPLAY);
if(preventPublicDisplay == null)
{
preventPublicDisplay = Boolean.FALSE;
state.setAttribute(STATE_PREVENT_PUBLIC_DISPLAY, preventPublicDisplay);
}
ListItem parent = new ListItem(pipe.getContentEntity());
parent.setPubviewPossible(! preventPublicDisplay);
ListItem model = new ListItem(pipe, parent, defaultRetractDate);
model.metadataGroupsIntoContext(context);
// model.setPubviewPossible(! preventPublicDisplay);
context.put("model", model);
context.put("type", model.getResourceTypeDef());
context.put("pipes", pipes);
if(ContentHostingService.isAvailabilityEnabled())
{
context.put("availability_is_enabled", Boolean.TRUE);
}
if(model.isDropbox)
{
String dropboxNotificationsProperty = getDropboxNotificationsProperty();
context.put("dropboxNotificationAllowed", Boolean.valueOf(ResourcesAction.DROPBOX_NOTIFICATIONS_ALLOW.equals(dropboxNotificationsProperty)));
}
String ezproxy = ServerConfigurationService.getString("content.ezproxy.prefix", "");
if (ezproxy != null && ezproxy != "") {
context.put("ezproxyPrefix", ezproxy);
} else {
context.put("ezproxyPrefix", false);
}
ResourcesAction.copyrightChoicesIntoContext(state, context);
ResourcesAction.publicDisplayChoicesIntoContext(state, context);
ResourceConditionsHelper.buildConditionContext(context, state);
int requestStateId = ResourcesAction.preserveRequestState(state, new String[]{ResourcesAction.PREFIX + ResourcesAction.REQUEST});
context.put("requestStateId", requestStateId);
return CREATE_URLS_TEMPLATE;
}
/**
* @param portlet
* @param context
* @param data
* @param state
* @return
*/
private String buildNewFoldersContext(VelocityPortlet portlet, Context context, RunData data, SessionState state)
{
logger.debug(this + ".buildNewFoldersContext()");
ToolSession toolSession = SessionManager.getCurrentToolSession();
MultiFileUploadPipe pipe = (MultiFileUploadPipe) toolSession.getAttribute(ResourceToolAction.ACTION_PIPE);
context.put(ResourcesAction.PIPE_INIT_ID, pipe.getInitializationId());
List<ResourceToolActionPipe> pipes = pipe.getPipes();
Time defaultRetractDate = (Time) state.getAttribute(STATE_DEFAULT_RETRACT_TIME);
if(defaultRetractDate == null)
{
defaultRetractDate = TimeService.newTime();
state.setAttribute(STATE_DEFAULT_RETRACT_TIME, defaultRetractDate);
}
Boolean preventPublicDisplay = (Boolean) state.getAttribute(STATE_PREVENT_PUBLIC_DISPLAY);
if(preventPublicDisplay == null)
{
preventPublicDisplay = Boolean.FALSE;
state.setAttribute(STATE_PREVENT_PUBLIC_DISPLAY, preventPublicDisplay);
}
ListItem parent = new ListItem(pipe.getContentEntity());
parent.setPubviewPossible(! preventPublicDisplay);
ListItem model = new ListItem(pipe, parent, defaultRetractDate);
model.metadataGroupsIntoContext(context);
// model.setPubviewPossible(! preventPublicDisplay);
context.put("model", model);
context.put("type", model.getResourceTypeDef());
context.put("pipes", pipes);
if(ContentHostingService.isAvailabilityEnabled())
{
context.put("availability_is_enabled", Boolean.TRUE);
}
ResourcesAction.publicDisplayChoicesIntoContext(state, context);
ResourceConditionsHelper.buildConditionContext(context, state);
int requestStateId = ResourcesAction.preserveRequestState(state, new String[]{ResourcesAction.PREFIX + ResourcesAction.REQUEST});
context.put("requestStateId", requestStateId);
return CREATE_FOLDERS_TEMPLATE;
}
/**
* @param portlet
* @param context
* @param data
* @param state
* @return
*/
protected String buildReplaceContext(VelocityPortlet portlet, Context context, RunData data, SessionState state)
{
logger.debug(this + ".buildReplaceContext()");
ToolSession toolSession = SessionManager.getCurrentToolSession();
ResourceToolActionPipe pipe = (ResourceToolActionPipe) toolSession.getAttribute(ResourceToolAction.ACTION_PIPE);
context.put(ResourcesAction.PIPE_INIT_ID, pipe.getInitializationId());
Boolean preventPublicDisplay = (Boolean) state.getAttribute(STATE_PREVENT_PUBLIC_DISPLAY);
if(preventPublicDisplay == null)
{
preventPublicDisplay = Boolean.FALSE;
state.setAttribute(STATE_PREVENT_PUBLIC_DISPLAY, preventPublicDisplay);
}
ListItem item = new ListItem(pipe.getContentEntity());
item.setPubviewPossible(! preventPublicDisplay);
if(item.isDropbox)
{
String dropboxNotificationsProperty = getDropboxNotificationsProperty();
context.put("dropboxNotificationAllowed", Boolean.valueOf(ResourcesAction.DROPBOX_NOTIFICATIONS_ALLOW.equals(dropboxNotificationsProperty)));
}
context.put("item", item);
int requestStateId = ResourcesAction.preserveRequestState(state, new String[]{ResourcesAction.PREFIX + ResourcesAction.REQUEST});
context.put("requestStateId", requestStateId);
return REPLACE_CONTENT_TEMPLATE;
}
public String buildReviseContext(VelocityPortlet portlet,
Context context,
RunData data,
SessionState state)
{
logger.debug(this + ".buildReviseContext()");
String template = REVISE_TEXT_TEMPLATE;
ToolSession toolSession = SessionManager.getCurrentToolSession();
ResourceToolActionPipe pipe = (ResourceToolActionPipe) toolSession.getAttribute(ResourceToolAction.ACTION_PIPE);
context.put(ResourcesAction.PIPE_INIT_ID, pipe.getInitializationId());
//Reference reference = (Reference) toolSession.getAttribute(ResourceToolAction.COLLECTION_REFERENCE);
String typeId = pipe.getAction().getTypeId();
String mimetype = pipe.getMimeType();
ListItem item = new ListItem(pipe.getContentEntity());
context.put("item", item);
// context.put("inDropbox", ContentHostingService.isInDropbox(pipe.getContentEntity().getId()));
ResourceTypeRegistry registry = (ResourceTypeRegistry) ComponentManager.get(ResourceTypeRegistry.class);
if(registry != null)
{
ResourceType typedef = registry.getType(typeId);
if(typedef != null)
{
context.put("hasNotificationDialog", typedef.hasNotificationDialog());
}
}
if(item.isDropbox)
{
String dropboxNotificationsProperty = getDropboxNotificationsProperty();
context.put("dropboxNotificationAllowed", Boolean.valueOf(ResourcesAction.DROPBOX_NOTIFICATIONS_ALLOW.equals(dropboxNotificationsProperty)));
}
context.put("pipe", pipe);
if(ResourceType.TYPE_TEXT.equals(typeId))
{
template = REVISE_TEXT_TEMPLATE;
}
else if(ResourceType.TYPE_HTML.equals(typeId))
{
template = REVISE_HTML_TEMPLATE;
}
else if(ResourceType.TYPE_URL.equals(typeId))
{
String decodedUrl = pipe.getContentstring();
try {
decodedUrl = URLDecoder.decode(pipe.getContentstring(), "UTF-8");
} catch (Exception e){
//cant decode, continue anyway with original string
}
context.put("decodedUrl", decodedUrl);
template = REVISE_URL_TEMPLATE;
}
else if(ResourceType.TYPE_UPLOAD.equals(typeId) && mimetype != null && ResourceType.MIME_TYPE_HTML.equals(mimetype))
{
template = REVISE_HTML_TEMPLATE;
}
else if(ResourceType.TYPE_UPLOAD.equals(typeId) && mimetype != null && ResourceType.MIME_TYPE_TEXT.equals(mimetype))
{
template = REVISE_TEXT_TEMPLATE;
}
else // assume ResourceType.TYPE_UPLOAD
{
template = REVISE_UPLOAD_TEMPLATE;
}
int requestStateId = ResourcesAction.preserveRequestState(state, new String[]{ResourcesAction.PREFIX + ResourcesAction.REQUEST});
context.put("requestStateId", requestStateId);
return template;
}
/**
* @param portlet
* @param context
* @param data
* @param state
* @return
*/
protected String buildUploadFilesContext(VelocityPortlet portlet, Context context, RunData data, SessionState state)
{
logger.debug(this + ".buildUploadFilesContext()");
ToolSession toolSession = SessionManager.getCurrentToolSession();
String max_file_size_mb = (String) state.getAttribute(STATE_FILE_UPLOAD_MAX_SIZE);
if(max_file_size_mb == null)
{
max_file_size_mb = "20";
}
String upload_limit = rb.getFormattedMessage("upload.limit", new String[]{ max_file_size_mb });
context.put("upload_limit", upload_limit);
String uploadMax = ServerConfigurationService.getString("content.upload.max");
String instr_uploads= rb.getFormattedMessage("instr.uploads", new String[]{ uploadMax});
context.put("instr_uploads", instr_uploads);
Boolean dragAndDrop = ServerConfigurationService.getBoolean("content.upload.dragndrop", false);
context.put("dragAndDrop", dragAndDrop);
// int max_bytes = 1024 * 1024;
// try
// {
// max_bytes = Integer.parseInt(max_file_size_mb) * 1024 * 1024;
// }
// catch(Exception e)
// {
// // if unable to parse an integer from the value
// // in the properties file, use 1 MB as a default
// max_file_size_mb = "1";
// max_bytes = 1024 * 1024;
// }
MultiFileUploadPipe pipe = (MultiFileUploadPipe) toolSession.getAttribute(ResourceToolAction.ACTION_PIPE);
context.put(ResourcesAction.PIPE_INIT_ID, pipe.getInitializationId());
List<ResourceToolActionPipe> pipes = pipe.getPipes();
Time defaultRetractDate = (Time) state.getAttribute(STATE_DEFAULT_RETRACT_TIME);
if(defaultRetractDate == null)
{
defaultRetractDate = TimeService.newTime();
state.setAttribute(STATE_DEFAULT_RETRACT_TIME, defaultRetractDate);
}
Boolean preventPublicDisplay = (Boolean) state.getAttribute(STATE_PREVENT_PUBLIC_DISPLAY);
if(preventPublicDisplay == null)
{
preventPublicDisplay = Boolean.FALSE;
state.setAttribute(STATE_PREVENT_PUBLIC_DISPLAY, preventPublicDisplay);
}
ListItem parent = new ListItem(pipe.getContentEntity());
parent.setPubviewPossible(! preventPublicDisplay);
ListItem model = new ListItem(pipe, parent, defaultRetractDate);
model.metadataGroupsIntoContext(context);
// model.setPubviewPossible(! preventPublicDisplay);
context.put("model", model);
context.put("type", model.getResourceTypeDef());
context.put("pipes", pipes);
if(ContentHostingService.isAvailabilityEnabled())
{
context.put("availability_is_enabled", Boolean.TRUE);
}
if(model.isDropbox)
{
String dropboxNotificationsProperty = getDropboxNotificationsProperty();
context.put("dropboxNotificationAllowed", Boolean.valueOf(ResourcesAction.DROPBOX_NOTIFICATIONS_ALLOW.equals(dropboxNotificationsProperty)));
}
ResourcesAction.copyrightChoicesIntoContext(state, context);
ResourcesAction.publicDisplayChoicesIntoContext(state, context);
String defaultCopyrightStatus = (String) state.getAttribute(STATE_DEFAULT_COPYRIGHT);
if(defaultCopyrightStatus == null || defaultCopyrightStatus.trim().equals(""))
{
defaultCopyrightStatus = ServerConfigurationService.getString("default.copyright");
state.setAttribute(STATE_DEFAULT_COPYRIGHT, defaultCopyrightStatus);
}
context.put("defaultCopyrightStatus", defaultCopyrightStatus);
ResourceConditionsHelper.buildConditionContext(context, state);
int requestStateId = ResourcesAction.preserveRequestState(state, new String[]{ResourcesAction.PREFIX + ResourcesAction.REQUEST});
context.put("requestStateId", requestStateId);
return CREATE_UPLOADS_TEMPLATE;
}
public void doCancel(RunData data)
{
logger.debug(this + ".doCancel()");
SessionState state = ((JetspeedRunData)data).getPortletSessionState (((JetspeedRunData)data).getJs_peid ());
ParameterParser params = data.getParameters ();
ToolSession toolSession = SessionManager.getCurrentToolSession();
int requestStateId = params.getInt("requestStateId", 0);
ResourcesAction.restoreRequestState(state, new String[]{ResourcesAction.PREFIX + ResourcesAction.REQUEST}, requestStateId);
//Tool tool = ToolManager.getCurrentTool();
//String url = (String) toolSession.getAttribute(tool.getId() + Tool.HELPER_DONE_URL);
//toolSession.removeAttribute(tool.getId() + Tool.HELPER_DONE_URL);
ResourceToolActionPipe pipe = (ResourceToolActionPipe) toolSession.getAttribute(ResourceToolAction.ACTION_PIPE);
if(pipe != null)
{
String pipe_init_id = pipe.getInitializationId();
String response_init_id = params.getString(ResourcesAction.PIPE_INIT_ID);
if(pipe_init_id == null || response_init_id == null || ! response_init_id.equalsIgnoreCase(pipe_init_id))
{
pipe.setErrorEncountered(true);
pipe.setActionCanceled(false);
}
else
{
pipe.setErrorEncountered(false);
pipe.setActionCanceled(true);
}
pipe.setActionCompleted(false);
toolSession.setAttribute(ResourceToolAction.DONE, Boolean.TRUE);
}
}
public void doContinue(RunData data)
{
logger.debug(this + ".doContinue()");
SessionState state = ((JetspeedRunData)data).getPortletSessionState (((JetspeedRunData)data).getJs_peid ());
ParameterParser params = data.getParameters ();
int requestStateId = params.getInt("requestStateId", 0);
ResourcesAction.restoreRequestState(state, new String[]{ResourcesAction.PREFIX + ResourcesAction.REQUEST}, requestStateId);
String content = params.getString("content");
if(content == null)
{
addAlert(state, rb.getString("text.notext"));
return;
}
ToolSession toolSession = SessionManager.getCurrentToolSession();
// Tool tool = ToolManager.getCurrentTool();
// String url = (String) toolSession.getAttribute(tool.getId() + Tool.HELPER_DONE_URL);
// toolSession.removeAttribute(tool.getId() + Tool.HELPER_DONE_URL);
ResourceToolActionPipe pipe = (ResourceToolActionPipe) toolSession.getAttribute(ResourceToolAction.ACTION_PIPE);
if(pipe == null)
{
return;
}
if(pipe != null)
{
String pipe_init_id = pipe.getInitializationId();
String response_init_id = params.getString(ResourcesAction.PIPE_INIT_ID);
if(pipe_init_id == null || response_init_id == null || ! response_init_id.equalsIgnoreCase(pipe_init_id))
{
// in this case, prevent upload to wrong folder
pipe.setErrorMessage(rb.getString("alert.try-again"));
pipe.setActionCanceled(false);
pipe.setErrorEncountered(true);
pipe.setActionCompleted(false);
return;
}
toolSession.setAttribute(ResourceToolAction.ACTION_PIPE, pipe);
}
String resourceType = pipe.getAction().getTypeId();
String mimetype = pipe.getMimeType();
ListItem item = new ListItem(pipe.getContentEntity());
// notification
int noti = determineNotificationPriority(params, item.isDropbox, item.userIsMaintainer());
pipe.setRevisedMimeType(pipe.getMimeType());
if(ResourceType.TYPE_TEXT.equals(resourceType) || ResourceType.MIME_TYPE_TEXT.equals(mimetype))
{
pipe.setRevisedMimeType(ResourceType.MIME_TYPE_TEXT);
pipe.setRevisedResourceProperty(ResourceProperties.PROP_CONTENT_ENCODING, ResourcesAction.UTF_8_ENCODING);
pipe.setNotification(noti);
}
else if(ResourceType.TYPE_HTML.equals(resourceType) || ResourceType.MIME_TYPE_HTML.equals(mimetype))
{
StringBuilder alertMsg = new StringBuilder();
content = FormattedText.processHtmlDocument(content, alertMsg);
pipe.setRevisedMimeType(ResourceType.MIME_TYPE_HTML);
pipe.setRevisedResourceProperty(ResourceProperties.PROP_CONTENT_ENCODING, ResourcesAction.UTF_8_ENCODING);
pipe.setNotification(noti);
if (alertMsg.length() > 0)
{
addAlert(state, alertMsg.toString());
return;
}
}
else if(ResourceType.TYPE_URL.equals(resourceType))
{
// SAK-23587 - properly escape the URL where required
try {
URL url = new URL(content);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
content = uri.toString();
} catch (Exception e) {
//ok to ignore, just use the original url
logger.debug("URL can not be encoded: " + e.getClass() + ":" + e.getCause());
}
pipe.setRevisedMimeType(ResourceType.MIME_TYPE_URL);
pipe.setNotification(noti);
}
else if(ResourceType.TYPE_FOLDER.equals(resourceType))
{
MultiFileUploadPipe mfp = (MultiFileUploadPipe) pipe;
int count = params.getInt("folderCount");
mfp.setFileCount(count);
List<ResourceToolActionPipe> pipes = mfp.getPipes();
for(int i = 0; i < pipes.size(); i++)
{
ResourceToolActionPipe fp = pipes.get(i);
String folderName = params.getString("folder" + (i + 1));
fp.setFileName(folderName);
fp.setNotification(noti);
}
}
try
{
pipe.setRevisedContent(content.getBytes(ResourcesAction.UTF_8_ENCODING));
pipe.setActionCanceled(false);
pipe.setErrorEncountered(false);
pipe.setActionCompleted(true);
}
catch (UnsupportedEncodingException e)
{
logger.warn( this + ": " + e.toString() );
addAlert(state, rb.getString("alert.utf8encoding"));
pipe.setActionCanceled(false);
pipe.setErrorEncountered(true);
pipe.setActionCompleted(false);
}
toolSession.setAttribute(ResourceToolAction.DONE, Boolean.TRUE);
}
public void doCreateFolders(RunData data)
{
logger.debug(this + ".doCreateFolders()");
SessionState state = ((JetspeedRunData)data).getPortletSessionState (((JetspeedRunData)data).getJs_peid ());
ParameterParser params = data.getParameters ();
ToolSession toolSession = SessionManager.getCurrentToolSession();
int requestStateId = params.getInt("requestStateId", 0);
ResourcesAction.restoreRequestState(state, new String[]{ResourcesAction.PREFIX + ResourcesAction.REQUEST}, requestStateId);
MultiFileUploadPipe pipe = (MultiFileUploadPipe) toolSession.getAttribute(ResourceToolAction.ACTION_PIPE);
if(pipe == null)
{
return;
}
String pipe_init_id = pipe.getInitializationId();
String response_init_id = params.getString(ResourcesAction.PIPE_INIT_ID);
if(pipe_init_id == null || response_init_id == null || ! response_init_id.equalsIgnoreCase(pipe_init_id))
{
// in this case, prevent upload to wrong folder
pipe.setErrorMessage(rb.getString("alert.try-again"));
pipe.setActionCanceled(false);
pipe.setErrorEncountered(true);
pipe.setActionCompleted(false);
return;
}
String resourceType = pipe.getAction().getTypeId();
int count = params.getInt("fileCount");
pipe.setFileCount(count);
int lastIndex = params.getInt("lastIndex");
ContentEntity entity = pipe.getContentEntity();
ListItem parent = null;
if(entity != null && entity instanceof ContentCollection)
{
ContentCollection containingCollection = (ContentCollection) entity;
Boolean preventPublicDisplay = (Boolean) state.getAttribute(STATE_PREVENT_PUBLIC_DISPLAY);
if(preventPublicDisplay == null)
{
preventPublicDisplay = Boolean.FALSE;
state.setAttribute(STATE_PREVENT_PUBLIC_DISPLAY, preventPublicDisplay);
}
parent = new ListItem(entity);
parent.setPubviewPossible(! preventPublicDisplay);
}
List<ResourceToolActionPipe> pipes = pipe.getPipes();
int actualCount = 0;
for(int i = 0; i <= lastIndex && actualCount < count; i++)
{
String exists = params.getString("exists" + ListItem.DOT + i);
if(exists == null || "".equals(exists))
{
continue;
}
ResourceToolActionPipe fp = pipes.get(actualCount);
String folderName = params.getString("content" + ListItem.DOT + i);
if(folderName == null || folderName.trim().equals(""))
{
continue;
}
fp.setFileName(folderName);
ListItem newFolder = (ListItem) fp.getRevisedListItem();
if(newFolder == null)
{
if(parent == null)
{
newFolder = new ListItem(folderName);
}
else
{
Time defaultRetractDate = (Time) state.getAttribute(STATE_DEFAULT_RETRACT_TIME);
if(defaultRetractDate == null)
{
defaultRetractDate = TimeService.newTime();
state.setAttribute(STATE_DEFAULT_RETRACT_TIME, defaultRetractDate);
}
newFolder = new ListItem(fp, parent, defaultRetractDate);
newFolder.setName(folderName);
newFolder.setId(folderName);
}
}
if(ListItem.isOptionalPropertiesEnabled())
{
newFolder.initMetadataGroups(null);
}
// capture properties
newFolder.captureProperties(params, ListItem.DOT + i);
if (newFolder.numberFieldIsInvalid) {
addAlert(state, rb.getString("conditions.invalid.condition.argument"));
return;
}
if (newFolder.numberFieldIsOutOfRange) {
addAlert(state, rb.getFormattedMessage("conditions.condition.argument.outofrange", new String[] { newFolder.getConditionAssignmentPoints() }));
return;
}
fp.setRevisedListItem(newFolder);
ResourceConditionsHelper.saveCondition(newFolder, params, state, i);
actualCount++;
}
if(actualCount > 0)
{
pipe.setActionCanceled(false);
pipe.setErrorEncountered(false);
pipe.setActionCompleted(true);
toolSession.setAttribute(ResourceToolAction.DONE, Boolean.TRUE);
}
else
{
addAlert(state, rb.getString("alert.nofldr"));
}
}
public void doReplace(RunData data)
{
logger.debug(this + ".doReplace()");
SessionState state = ((JetspeedRunData)data).getPortletSessionState (((JetspeedRunData)data).getJs_peid ());
ParameterParser params = data.getParameters ();
ToolSession toolSession = SessionManager.getCurrentToolSession();
int requestStateId = params.getInt("requestStateId", 0);
ResourcesAction.restoreRequestState(state, new String[]{ResourcesAction.PREFIX + ResourcesAction.REQUEST}, requestStateId);
ResourceToolActionPipe pipe = (ResourceToolActionPipe) toolSession.getAttribute(ResourceToolAction.ACTION_PIPE);
if(pipe == null)
{
return;
}
String pipe_init_id = pipe.getInitializationId();
String response_init_id = params.getString(ResourcesAction.PIPE_INIT_ID);
if(pipe_init_id == null || response_init_id == null || ! response_init_id.equalsIgnoreCase(pipe_init_id))
{
// in this case, prevent upload to wrong folder
pipe.setErrorMessage(rb.getString("alert.try-again"));
pipe.setActionCanceled(false);
pipe.setErrorEncountered(true);
pipe.setActionCompleted(false);
logger.debug(this + ".doReplace() setting error on pipe");
String uploadMax = ServerConfigurationService.getString("content.upload.max");
addAlert(state, rb.getFormattedMessage("alert.over-per-upload-quota", new Object[]{uploadMax}));
return;
}
FileItem fileitem = null;
try
{
fileitem = params.getFileItem("content");
}
catch(Exception e)
{
logger.warn("Exception ", e);
}
if(fileitem == null)
{
String max_file_size_mb = (String) state.getAttribute(STATE_FILE_UPLOAD_MAX_SIZE);
int max_bytes = 1024 * 1024;
try
{
max_bytes = Integer.parseInt(max_file_size_mb) * 1024 * 1024;
}
catch(Exception e)
{
// if unable to parse an integer from the value
// in the properties file, use 1 MB as a default
max_file_size_mb = "1";
max_bytes = 1024 * 1024;
}
String max_bytes_string = ResourcesAction.getFileSizeString(max_bytes, rb);
// "The user submitted a file to upload but it was too big!"
addAlert(state, rb.getFormattedMessage("size.exceeded", new Object[]{ max_bytes_string }));
//max_file_size_mb + "MB " + rb.getString("exceeded2"));
}
else if (fileitem.getFileName() == null || fileitem.getFileName().length() == 0)
{
addAlert(state, rb.getString("choosefile7"));
}
else if (fileitem.getFileName().length() > 0)
{
String filename = Validator.getFileName(fileitem.getFileName());
InputStream stream;
stream = fileitem.getInputStream();
if(stream == null)
{
byte[] bytes = fileitem.get();
pipe.setRevisedContent(bytes);
}
else
{
pipe.setRevisedContentStream(stream);
}
String contentType = fileitem.getContentType().replaceAll("\"", "");
//pipe.setRevisedContent(bytes);
pipe.setRevisedMimeType(contentType);
pipe.setFileName(filename);
if(ResourceType.MIME_TYPE_HTML.equals(contentType) || ResourceType.MIME_TYPE_TEXT.equals(contentType))
{
pipe.setRevisedResourceProperty(ResourceProperties.PROP_CONTENT_ENCODING, ResourcesAction.UTF_8_ENCODING);
}
else if(pipe.getPropertyValue(ResourceProperties.PROP_CONTENT_ENCODING) != null)
{
pipe.setRevisedResourceProperty(ResourceProperties.PROP_CONTENT_ENCODING, (String) pipe.getPropertyValue(ResourceProperties.PROP_CONTENT_ENCODING));
}
ListItem newFile = new ListItem(pipe.getContentEntity());
// notification
int noti = determineNotificationPriority(params, newFile.isDropbox, newFile.userIsMaintainer());
newFile.setNotification(noti);
pipe.setRevisedListItem(newFile);
pipe.setActionCanceled(false);
pipe.setErrorEncountered(false);
pipe.setActionCompleted(true);
toolSession.setAttribute(ResourceToolAction.DONE, Boolean.TRUE);
}
}
public void doAddUrls(RunData data)
{
logger.debug(this + ".soAddUrls()");
SessionState state = ((JetspeedRunData)data).getPortletSessionState (((JetspeedRunData)data).getJs_peid ());
ParameterParser params = data.getParameters ();
ToolSession toolSession = SessionManager.getCurrentToolSession();
int requestStateId = params.getInt("requestStateId", 0);
ResourcesAction.restoreRequestState(state, new String[]{ResourcesAction.PREFIX + ResourcesAction.REQUEST}, requestStateId);
MultiFileUploadPipe mfp = (MultiFileUploadPipe) toolSession.getAttribute(ResourceToolAction.ACTION_PIPE);
if(mfp == null)
{
return;
}
String pipe_init_id = mfp.getInitializationId();
String response_init_id = params.getString(ResourcesAction.PIPE_INIT_ID);
if(pipe_init_id == null || response_init_id == null || ! response_init_id.equalsIgnoreCase(pipe_init_id))
{
// in this case, prevent upload to wrong folder
mfp.setErrorMessage(rb.getString("alert.try-again"));
mfp.setActionCanceled(false);
mfp.setErrorEncountered(true);
mfp.setActionCompleted(false);
return;
}
int count = params.getInt("fileCount");
mfp.setFileCount(count);
int lastIndex = params.getInt("lastIndex");
ContentEntity entity = mfp.getContentEntity();
ListItem parent = null;
if(entity != null && entity instanceof ContentCollection)
{
ContentCollection containingCollection = (ContentCollection) entity;
Boolean preventPublicDisplay = (Boolean) state.getAttribute(STATE_PREVENT_PUBLIC_DISPLAY);
if(preventPublicDisplay == null)
{
preventPublicDisplay = Boolean.FALSE;
state.setAttribute(STATE_PREVENT_PUBLIC_DISPLAY, preventPublicDisplay);
}
parent = new ListItem(entity);
parent.setPubviewPossible(! preventPublicDisplay);
}
List<String> alerts = new ArrayList<String>();
List<ResourceToolActionPipe> pipes = mfp.getPipes();
int actualCount = 0;
for(int i = 0; i <= lastIndex && actualCount < count; i++)
{
String exists = params.getString("exists" + ListItem.DOT + i);
if(exists == null || "".equals(exists))
{
continue;
}
ResourceToolActionPipe pipe = pipes.get(actualCount);
String url = params.getString("content" + ListItem.DOT + i );
if(url == null)
{
continue;
}
else
{
try
{
url = ResourcesAction.validateURL(url);
}
catch (MalformedURLException e)
{
addAlert(state, rb.getFormattedMessage("url.invalid", new String[]{url}));
continue;
}
try {
pipe.setRevisedContent(url.getBytes(ResourcesAction.UTF_8_ENCODING));
} catch (UnsupportedEncodingException e) {
pipe.setRevisedContent(url.getBytes());
}
}
pipe.setFileName(Validator.escapeResourceName(url));
pipe.setRevisedMimeType(ResourceType.MIME_TYPE_URL);
ListItem newFile = (ListItem) pipe.getRevisedListItem();
if(newFile == null)
{
if(parent == null)
{
newFile = new ListItem(pipe.getFileName());
}
else
{
Time defaultRetractDate = (Time) state.getAttribute(STATE_DEFAULT_RETRACT_TIME);
if(defaultRetractDate == null)
{
defaultRetractDate = TimeService.newTime();
state.setAttribute(STATE_DEFAULT_RETRACT_TIME, defaultRetractDate);
}
newFile = new ListItem(mfp, parent, defaultRetractDate);
newFile.setName(new String(pipe.getRevisedContent()));
newFile.setId(pipe.getFileName());
}
}
if(ListItem.isOptionalPropertiesEnabled())
{
newFile.initMetadataGroups(null);
}
// capture properties
newFile.captureProperties(params, ListItem.DOT + i);
if (newFile.numberFieldIsInvalid) {
addAlert(state, rb.getString("conditions.invalid.condition.argument"));
return;
}
if (newFile.numberFieldIsOutOfRange) {
addAlert(state, rb.getFormattedMessage("conditions.condition.argument.outofrange", new String[] { newFile.getConditionAssignmentPoints() }));
return;
}
// notification
int noti = determineNotificationPriority(params, newFile.isDropbox, newFile.userIsMaintainer());
newFile.setNotification(noti);
//alerts.addAll(newFile.checkRequiredProperties());
pipe.setRevisedListItem(newFile);
// capture properties
newFile.captureProperties(params, ListItem.DOT + i);
if (newFile.numberFieldIsInvalid) {
addAlert(state, contentResourceBundle.getString("conditions.invalid.condition.argument"));
return;
}
if (newFile.numberFieldIsOutOfRange) {
addAlert(state, contentResourceBundle.getFormattedMessage("conditions.condition.argument.outofrange", new String[] { newFile.getConditionAssignmentPoints() }));
return;
}
ResourceConditionsHelper.saveCondition(newFile, params, state, i);
actualCount++;
}
if(! alerts.isEmpty())
{
for(String alert: alerts)
{
addAlert(state, alert);
}
}
if(actualCount < 1)
{
addAlert(state, rb.getString("url.noinput"));
return;
}
mfp.setActionCanceled(false);
mfp.setErrorEncountered(false);
mfp.setActionCompleted(true);
toolSession.setAttribute(ResourceToolAction.DONE, Boolean.TRUE);
}
/**
* @return
*/
protected String getDropboxNotificationsProperty()
{
Placement placement = ToolManager.getCurrentPlacement();
Properties props = placement.getPlacementConfig();
String dropboxNotifications = props.getProperty(ResourcesAction.DROPBOX_NOTIFICATIONS_PROPERTY);
if(dropboxNotifications == null)
{
dropboxNotifications = ResourcesAction.DROPBOX_NOTIFICATIONS_DEFAULT_VALUE;
}
logger.debug(this + ".getDropboxNotificationsProperty() dropboxNotifications == " + dropboxNotifications);
return dropboxNotifications;
}
/**
* @param params
* @param newFile
* @return
*/
protected int determineNotificationPriority(ParameterParser params, boolean contextIsDropbox, boolean userIsMaintainer)
{
int noti = NotificationService.NOTI_NONE;
// %%STATE_MODE_RESOURCES%%
if (contextIsDropbox)
{
boolean notification = false;
if(userIsMaintainer) // if the user is a site maintainer
{
notification = params.getBoolean("notify_dropbox");
if(notification)
{
noti = NotificationService.NOTI_REQUIRED;
}
}
else
{
String notifyDropbox = getDropboxNotificationsProperty();
if(ResourcesAction.DROPBOX_NOTIFICATIONS_ALWAYS.equals(notifyDropbox))
{
noti = NotificationService.NOTI_OPTIONAL;
}
else if(ResourcesAction.DROPBOX_NOTIFICATIONS_ALLOW.equals(notifyDropbox))
{
notification = params.getBoolean("notify_dropbox");
if(notification)
{
noti = NotificationService.NOTI_OPTIONAL;
}
}
}
logger.debug(this + ".doAddUrls() noti == " + noti);
}
else
{
// read the notification options
String notification = params.getString("notify");
if ("r".equals(notification))
{
noti = NotificationService.NOTI_REQUIRED;
}
else if ("o".equals(notification))
{
noti = NotificationService.NOTI_OPTIONAL;
}
}
return noti;
}
public void doUpload(RunData data)
{
logger.debug(this + ".doUpload()");
SessionState state = ((JetspeedRunData)data).getPortletSessionState (((JetspeedRunData)data).getJs_peid ());
ParameterParser params = data.getParameters ();
ToolSession toolSession = SessionManager.getCurrentToolSession();
int requestStateId = params.getInt("requestStateId", 0);
ResourcesAction.restoreRequestState(state, new String[]{ResourcesAction.PREFIX + ResourcesAction.REQUEST}, requestStateId);
MultiFileUploadPipe mfp = (MultiFileUploadPipe) toolSession.getAttribute(ResourceToolAction.ACTION_PIPE);
if(mfp == null)
{
logger.debug(this + ".doUpload() mfp is null");
return;
}
String pipe_init_id = mfp.getInitializationId();
String response_init_id = params.getString(ResourcesAction.PIPE_INIT_ID);
if(pipe_init_id == null || response_init_id == null || ! response_init_id.equalsIgnoreCase(pipe_init_id))
{
// in this case, prevent upload to wrong folder
mfp.setErrorMessage(rb.getString("alert.try-again"));
mfp.setActionCanceled(false);
mfp.setErrorEncountered(true);
mfp.setActionCompleted(false);
logger.debug(this + ".doUpload() setting error on pipe");
String uploadMax = ServerConfigurationService.getString("content.upload.max");
addAlert(state, rb.getFormattedMessage("alert.over-per-upload-quota", new Object[]{uploadMax}));
return;
}
logger.debug(" after doUpload() setting error on pipe");
int count = params.getInt("fileCount");
mfp.setFileCount(count);
if(count < 1)
{
mfp.setFileCount(1);
}
int lastIndex = params.getInt("lastIndex");
List<String> allAlerts = new ArrayList<String>();
ContentEntity entity = mfp.getContentEntity();
ListItem parent = null;
if(entity != null && entity instanceof ContentCollection)
{
ContentCollection containingCollection = (ContentCollection) entity;
Boolean preventPublicDisplay = (Boolean) state.getAttribute(STATE_PREVENT_PUBLIC_DISPLAY);
if(preventPublicDisplay == null)
{
preventPublicDisplay = Boolean.FALSE;
state.setAttribute(STATE_PREVENT_PUBLIC_DISPLAY, preventPublicDisplay);
}
parent = new ListItem(entity);
parent.setPubviewPossible(! preventPublicDisplay);
}
List<ResourceToolActionPipe> pipes = mfp.getPipes();
logger.debug(this + ".doUpload() iterating through pipes");
int uploadCount = 0;
for(int i = 0, c = 0; i <= lastIndex && c < count; i++)
{
String exists = params.getString("exists" + ListItem.DOT + i);
if(exists == null || "".equals(exists))
{
continue;
}
ResourceToolActionPipe pipe = pipes.get(c);
FileItem fileitem = null;
try
{
fileitem = params.getFileItem("content" + ListItem.DOT + i );
}
catch(Exception e)
{
logger.warn("Exception ", e);
}
if(fileitem == null)
{
String max_file_size_mb = (String) state.getAttribute(STATE_FILE_UPLOAD_MAX_SIZE);
int max_bytes = 1024 * 1024;
try
{
max_bytes = Integer.parseInt(max_file_size_mb) * 1024 * 1024;
}
catch(Exception e)
{
// if unable to parse an integer from the value
// in the properties file, use 1 MB as a default
max_file_size_mb = "1";
max_bytes = 1024 * 1024;
}
String max_bytes_string = ResourcesAction.getFileSizeString(max_bytes, rb);
// "The user submitted a file to upload but it was too big!"
addAlert(state, rb.getFormattedMessage("size.exceeded", new Object[]{ max_bytes_string }));
//max_file_size_mb + "MB " + rb.getString("exceeded2"));
}
else if (fileitem.getFileName() == null || fileitem.getFileName().length() == 0)
{
// no file selected -- skip this one
}
else if (fileitem.getFileName().length() > 0)
{
String filename = Validator.getFileName(fileitem.getFileName());
pipe.setRevisedContentStream( fileitem.getInputStream() );
String contentType = fileitem.getContentType().replaceAll("\"", "");
pipe.setRevisedMimeType(contentType);
// If no encoding specified, default to UTF-8 encoding
if ( (ResourceType.MIME_TYPE_HTML.equals(contentType) || ResourceType.MIME_TYPE_TEXT.equals(contentType)) &&
pipe.getPropertyValue(ResourceProperties.PROP_CONTENT_ENCODING) == null)
{
pipe.setRevisedResourceProperty(ResourceProperties.PROP_CONTENT_ENCODING, ResourcesAction.UTF_8_ENCODING);
}
pipe.setFileName(filename);
ListItem newFile = (ListItem) pipe.getRevisedListItem();
if(newFile == null)
{
if(parent == null)
{
newFile = new ListItem(filename);
}
else
{
Time defaultRetractDate = (Time) state.getAttribute(STATE_DEFAULT_RETRACT_TIME);
if(defaultRetractDate == null)
{
defaultRetractDate = TimeService.newTime();
state.setAttribute(STATE_DEFAULT_RETRACT_TIME, defaultRetractDate);
}
newFile = new ListItem(pipe, parent, defaultRetractDate);
newFile.setName(filename);
newFile.setId(filename);
}
}
if(ListItem.isOptionalPropertiesEnabled())
{
newFile.initMetadataGroups(null);
}
// capture properties
newFile.captureProperties(params, ListItem.DOT + i);
// notification
int noti = determineNotificationPriority(params, newFile.isDropbox, newFile.userIsMaintainer());
newFile.setNotification(noti);
// allAlerts.addAll(newFile.checkRequiredProperties());
pipe.setRevisedListItem(newFile);
// capture properties
newFile.captureProperties(params, ListItem.DOT + i);
if (newFile.numberFieldIsInvalid) {
addAlert(state, contentResourceBundle.getString("conditions.invalid.condition.argument"));
return;
}
if (newFile.numberFieldIsOutOfRange) {
addAlert(state, contentResourceBundle.getFormattedMessage("conditions.condition.argument.outofrange", new String[] { newFile.getConditionAssignmentPoints() }));
return;
}
ResourceConditionsHelper.saveCondition(newFile, params, state, i);
uploadCount++;
}
c++;
}
logger.debug(this + ".doUpload() checking upload count");
if(uploadCount < 1 && state.getAttribute(ResourcesAction.STATE_MESSAGE) == null)
{
logger.debug(this + ".doUpload() no files uploaded");
HttpServletRequest req = data.getRequest();
String status = (String) req.getAttribute("upload.status");
logger.debug("Printing out upload.status: " + status);
if(status == null)
{
logger.warn("No files uploaded; upload.status == null");
}
else if("ok".equals(status))
{
logger.warn("No files uploaded; upload.status == ok");
}
else if("size_limit_exceeded".equals(status))
{
String max_file_size_mb = (String) state.getAttribute(STATE_FILE_UPLOAD_MAX_SIZE);
int max_bytes = 1024 * 1024;
try
{
max_bytes = Integer.parseInt(max_file_size_mb) * 1024 * 1024;
}
catch(Exception e)
{
// if unable to parse an integer from the value
// in the properties file, use 1 MB as a default
max_file_size_mb = "1";
max_bytes = 1024 * 1024;
}
String max_bytes_string = ResourcesAction.getFileSizeString(max_bytes, rb);
addAlert(state, rb.getFormattedMessage("size.exceeded", new Object[]{ max_bytes_string }));
}
else if("exception".equals(status))
{
logger.warn("No files uploaded; upload.status == exception");
addAlert(state, rb.getString("choosefile7"));
}
}
logger.debug(this + ".doUpload() checking allAlerts");
if(! allAlerts.isEmpty())
{
for(String alert: allAlerts)
{
addAlert(state, alert);
}
}
logger.debug(this + ".doUpload() checking messages");
if(state.getAttribute(ResourcesAction.STATE_MESSAGE) == null)
{
mfp.setActionCanceled(false);
mfp.setErrorEncountered(false);
mfp.setActionCompleted(true);
logger.debug(this + ".doUpload() no error messages");
toolSession.setAttribute(ResourceToolAction.DONE, Boolean.TRUE);
}
}
protected void initHelper(VelocityPortlet portlet, Context context, RunData rundata, SessionState state)
{
logger.debug(this + ".initHelper()");
ToolSession toolSession = SessionManager.getCurrentToolSession();
//toolSession.setAttribute(ResourceToolAction.STARTED, Boolean.TRUE);
//state.setAttribute(ResourceToolAction.STATE_MODE, MODE_MAIN);
if(state.getAttribute(STATE_USING_CREATIVE_COMMONS) == null)
{
String usingCreativeCommons = ServerConfigurationService.getString("copyright.use_creative_commons");
if( usingCreativeCommons != null && usingCreativeCommons.equalsIgnoreCase(Boolean.TRUE.toString()))
{
state.setAttribute(STATE_USING_CREATIVE_COMMONS, Boolean.TRUE.toString());
}
else
{
state.setAttribute(STATE_USING_CREATIVE_COMMONS, Boolean.FALSE.toString());
}
}
if (state.getAttribute(STATE_COPYRIGHT_TYPES) == null)
{
if (ServerConfigurationService.getStrings("copyrighttype") != null)
{
state.setAttribute(STATE_COPYRIGHT_TYPES, new ArrayList(Arrays.asList(ServerConfigurationService.getStrings("copyrighttype"))));
}
}
if (state.getAttribute(STATE_DEFAULT_COPYRIGHT) == null)
{
if (ServerConfigurationService.getString("default.copyright") != null)
{
state.setAttribute(STATE_DEFAULT_COPYRIGHT, ServerConfigurationService.getString("default.copyright"));
}
}
if (state.getAttribute(STATE_DEFAULT_COPYRIGHT_ALERT) == null)
{
if (ServerConfigurationService.getString("default.copyright.alert") != null)
{
state.setAttribute(STATE_DEFAULT_COPYRIGHT_ALERT, ServerConfigurationService.getString("default.copyright.alert"));
}
}
if (state.getAttribute(STATE_NEW_COPYRIGHT_INPUT) == null)
{
if (ServerConfigurationService.getString("newcopyrightinput") != null)
{
state.setAttribute(STATE_NEW_COPYRIGHT_INPUT, ServerConfigurationService.getString("newcopyrightinput"));
}
}
if (state.getAttribute(STATE_COPYRIGHT_FAIRUSE_URL) == null)
{
if (ServerConfigurationService.getString("fairuse.url") != null)
{
state.setAttribute(STATE_COPYRIGHT_FAIRUSE_URL, ServerConfigurationService.getString("fairuse.url"));
}
}
if (state.getAttribute(STATE_COPYRIGHT_NEW_COPYRIGHT) == null)
{
if (ServerConfigurationService.getString("copyrighttype.new") != null)
{
state.setAttribute(STATE_COPYRIGHT_NEW_COPYRIGHT, ServerConfigurationService.getString("copyrighttype.new"));
}
}
if (state.getAttribute(STATE_FILE_UPLOAD_MAX_SIZE) == null)
{
String uploadMax = ServerConfigurationService.getString("content.upload.max");
String uploadCeiling = ServerConfigurationService.getString("content.upload.ceiling");
if(uploadMax == null && uploadCeiling == null)
{
state.setAttribute(STATE_FILE_UPLOAD_MAX_SIZE, "20");
}
else if(uploadCeiling == null)
{
state.setAttribute(STATE_FILE_UPLOAD_MAX_SIZE, uploadMax);
}
else if(uploadMax == null)
{
state.setAttribute(STATE_FILE_UPLOAD_MAX_SIZE, null);
}
else
{
int maxNum = Integer.MAX_VALUE;
int ceilingNum = Integer.MAX_VALUE;
try
{
maxNum = Integer.parseInt(uploadMax);
}
catch(Exception e)
{
}
try
{
ceilingNum = Integer.parseInt(uploadCeiling);
}
catch(Exception e)
{
}
if(ceilingNum < maxNum)
{
state.setAttribute(STATE_FILE_UPLOAD_MAX_SIZE, uploadCeiling);
}
else
{
state.setAttribute(STATE_FILE_UPLOAD_MAX_SIZE, uploadMax);
}
}
}
state.setAttribute(STATE_PREVENT_PUBLIC_DISPLAY, Boolean.FALSE);
String[] siteTypes = ServerConfigurationService.getStrings("prevent.public.resources");
String siteType = null;
Site site;
try
{
site = SiteService.getSite(ToolManager.getCurrentPlacement().getContext());
siteType = site.getType();
if(siteTypes != null)
{
for(int i = 0; i < siteTypes.length; i++)
{
if ((StringUtils.trimToNull(siteTypes[i])).equals(siteType))
{
state.setAttribute(STATE_PREVENT_PUBLIC_DISPLAY, Boolean.TRUE);
break;
}
}
}
}
catch (IdUnusedException e)
{
// allow public display
}
catch(NullPointerException e)
{
// allow public display
}
state.setAttribute (STATE_CONTENT_TYPE_IMAGE_SERVICE, org.sakaiproject.content.cover.ContentTypeImageService.getInstance());
state.removeAttribute(STATE_PAGE_TITLE);
}
protected void toolModeDispatch(String methodBase, String methodExt, HttpServletRequest req, HttpServletResponse res)
throws ToolException
{
logger.debug(this + ".toolModeDispatch()");
SessionState sstate = getState(req);
ToolSession toolSession = SessionManager.getCurrentToolSession();
//String mode = (String) sstate.getAttribute(ResourceToolAction.STATE_MODE);
//Object started = toolSession.getAttribute(ResourceToolAction.STARTED);
Object done = toolSession.getAttribute(ResourceToolAction.DONE);
if (done != null)
{
toolSession.removeAttribute(ResourceToolAction.STARTED);
sstate.removeAttribute(STATE_PAGE_TITLE);
Tool tool = ToolManager.getCurrentTool();
String url = (String) SessionManager.getCurrentToolSession().getAttribute(tool.getId() + Tool.HELPER_DONE_URL);
logger.debug(this + ".toolModeDispatch() url == " + url);
SessionManager.getCurrentToolSession().removeAttribute(tool.getId() + Tool.HELPER_DONE_URL);
try
{
res.sendRedirect(url);
}
catch (IOException e)
{
logger.warn(this + ".toolModeDispatch() IOException", e);
}
logger.debug(this + ".toolModeDispatch() returning");
return;
}
logger.debug(this + ".toolModeDispatch() calling super.toolModeDispatch(" + methodBase + ", " + "methodExt" + ", " + req + ", " + res+ ")");
super.toolModeDispatch(methodBase, methodExt, req, res);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException {
String dragDropFile = request.getHeader("x-file-name");
if(dragDropFile != null){
String uploadMax = ServerConfigurationService.getString("content.upload.max");
String siteQuota = ServerConfigurationService.getString("siteQuota@org.sakaiproject.content.api.ContentHostingService");
Long fileSize = Long.parseLong(request.getHeader("content-length"));
if((uploadMax != null && !"".equals(uploadMax)) && (fileSize /1024L / 1024L) > Long.parseLong(uploadMax)){
addAlert(getState(request), rb.getFormattedMessage("alert.over-per-upload-quota", new Object[]{uploadMax}));
} else if ((siteQuota != null && !"".equals(siteQuota)) && (fileSize /1024L / 1024L) > Long.parseLong(siteQuota)) {
addAlert(getState(request), rb.getFormattedMessage("alert.over-site-upload-quota", new Object[]{siteQuota}));
} else {
doDragDropUpload(request, response);
}
} else{
super.doPost(request, response);
}
}
private void doDragDropUpload(HttpServletRequest request, HttpServletResponse response) {
String uploadFileName = request.getHeader("x-file-name");
SessionState state = getState(request);
ToolSession toolSession = SessionManager.getCurrentToolSession();
if (uploadFileName != null && !uploadFileName.isEmpty()) {
InputStream is = null;
ContentResourceEdit resource = null;
try {
String resourceGroup = toolSession.getAttribute("resources.request.create_wizard_collection_id").toString();
String resourceName = getUniqueFileName(uploadFileName, resourceGroup);
resource = ContentHostingService.addResource(resourceGroup + resourceName);
if (resource != null) {
ResourcePropertiesEdit resourceProps = resource.getPropertiesEdit();
resourceProps.addProperty(ResourcePropertiesEdit.PROP_DISPLAY_NAME, resourceName);
DiskFileItem uploadFile = (DiskFileItem) request.getAttribute("file");
if(uploadFile != null){
resource.setContent(uploadFile.getInputStream());
ContentHostingService.commitResource(resource, NotificationService.NOTI_NONE);
}
if (uploadFileName.contains(".zip")) {
ZipContentUtil zipContentUtil = new ZipContentUtil();
zipContentUtil.extractArchive(EntityManager.newReference(resource.getReference()));
}
}
} catch (OverQuotaException e) {
addAlert(state, rb.getString("alert.over-site-upload-quota"));
logger.warn("Drag and drop upload failed: " + e, e);
} catch (Exception e) {
logger.warn("Drag and drop upload failed: " + e, e);
} finally {
try {
if (is != null) {
is.close();
}
if (uploadFileName.contains(".zip")) {
//remove the zip file after unpacking it
try {
ContentHostingService.removeResource(resource.getId());
} catch (Exception e) {
logger.warn("Unable to remove zip file: " + e, e);
}
}
} catch (IOException e) {
logger.warn("Caught exception: " + e, e);
}
}
}
}
private String getUniqueFileName(String uploadFileName, String resourceGroup) throws org.sakaiproject.exception.PermissionException, org.sakaiproject.exception.TypeException {
String resourceId = "";
boolean isNameUnique = false;
String fileName = uploadFileName;
int attempt = 0;
while (!isNameUnique) {
try {
resourceId = resourceGroup + fileName;
ContentResource tempEdit = ContentHostingService.getResource(resourceId);
if(tempEdit != null){
attempt++;
StringBuffer fileNameBuffer = new StringBuffer();
if(attempt > 1){
fileNameBuffer.append(fileName.substring(0, fileName.lastIndexOf("-")));
} else{
fileNameBuffer.append(fileName.substring(0, fileName.lastIndexOf(".")));
}
fileNameBuffer.append("-");
fileNameBuffer.append(attempt);
fileNameBuffer.append(fileName.substring(fileName.lastIndexOf("."), fileName.length()));
fileName = fileNameBuffer.toString();
}
} catch (IdUnusedException e) {
isNameUnique = true;
}
}
return fileName;
}
}