/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/rwiki/trunk/rwiki-tool/tool/src/java/uk/ac/cam/caret/sakai/rwiki/tool/command/AddAttachmentReturnCommand.java $
* $Id: AddAttachmentReturnCommand.java 58934 2009-03-20 23:04:39Z s.swinsburg@lancaster.ac.uk $
***********************************************************************************
*
* Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation.
*
* Licensed under the Educational Community License, Version 1.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/ecl1.php
*
* 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 uk.ac.cam.caret.sakai.rwiki.tool.command;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
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.component.api.ComponentManager;
import org.sakaiproject.content.api.FilePickerHelper;
import org.sakaiproject.entity.api.Reference;
import org.sakaiproject.entity.api.ResourceProperties;
import org.sakaiproject.tool.api.SessionManager;
import org.sakaiproject.tool.api.Tool;
import org.sakaiproject.tool.api.ToolSession;
import org.sakaiproject.tool.cover.ToolManager;
import uk.ac.cam.caret.sakai.rwiki.tool.RequestScopeSuperBean;
import uk.ac.cam.caret.sakai.rwiki.tool.api.HttpCommand;
import uk.ac.cam.caret.sakai.rwiki.tool.bean.EditBean;
import uk.ac.cam.caret.sakai.rwiki.tool.bean.ErrorBean;
import uk.ac.cam.caret.sakai.rwiki.tool.bean.ResourceLoaderBean;
import uk.ac.cam.caret.sakai.rwiki.tool.bean.SearchBean;
import uk.ac.cam.caret.sakai.rwiki.tool.bean.ViewBean;
import uk.ac.cam.caret.sakai.rwiki.tool.bean.helper.ViewParamsHelperBean;
/**
* @author andrew
*/
public class AddAttachmentReturnCommand implements HttpCommand
{
private static Log log = LogFactory.getLog(AddAttachmentReturnCommand.class);
private static final String MULTIPLE_ATTACHMENT_HEADER_START = "";
private static final String MULTIPLE_ATTACHMENT_HEADER_BODY = "";
private static final String MULTIPLE_ATTACHMENT_HEADER_END = "";
private static final String MULTIPLE_ATTACHMENT_ITEM = "\n ";
private static final String MULTIPLE_ATTACHMENT_ITEMS_END = "\n";
private SessionManager sessionManager;
private Map wikiMarkupTemplates;
private String editPath;
public void init()
{
ComponentManager cm = org.sakaiproject.component.cover.ComponentManager
.getInstance();
sessionManager = (SessionManager) load(cm, SessionManager.class
.getName());
}
private Object load(ComponentManager cm, String name)
{
Object o = cm.get(name);
if (o == null)
{
log.error("Cant find Spring component named " + name);
}
return o;
}
/*
* (non-Javadoc)
*
* @see uk.ac.cam.caret.sakai.rwiki.tool.api.HttpCommand#execute(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse)
*/
public void execute(Dispatcher dispatcher,HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
RequestScopeSuperBean rssb = RequestScopeSuperBean
.getFromRequest(request);
ToolSession session = sessionManager.getCurrentToolSession();
// TODO EEK! constantise this
Map storedParameters = (Map) session.getAttribute("STORED_PARAMETERS");
String content = retrieveString(storedParameters
.get(EditBean.CONTENT_PARAM));
content = content.replaceAll("\r\n?", "\n");
String caretPosition = retrieveString(storedParameters
.get(EditBean.STORED_CARET_POSITION));
String pageName = retrieveString(storedParameters
.get(ViewBean.PAGE_NAME_PARAM));
List refs = (List) session
.getAttribute(FilePickerHelper.FILE_PICKER_ATTACHMENTS);
if (session.getAttribute(FilePickerHelper.FILE_PICKER_CANCEL) == null
&& refs != null && refs.size() > 0)
{
// File Picking was successful.
content = generateNewContent(refs, content, caretPosition);
}
else
{
ErrorBean errorBean = rssb.getErrorBean();
ResourceLoaderBean rlb = rssb.getResourceLoaderBean();
errorBean.addError(rlb.getString("addattacheret.cancel_add_attach","Cancelled add attachment"));
}
// Eek! I think we need a better way of doing this...
ViewParamsHelperBean vphb = rssb.getNameHelperBean();
vphb.setContent(content);
vphb.setGlobalName(pageName);
vphb.setLocalSpace(retrieveString(storedParameters
.get(SearchBean.REALM_PARAM)));
vphb.setSaveType(vphb.getSaveTypeFromParameters(storedParameters));
vphb.setWithBreadcrumbs(retrieveString(storedParameters
.get(ViewBean.PARAM_BREADCRUMB_NAME)));
vphb.setSubmittedVersion(retrieveString(storedParameters
.get(EditBean.VERSION_PARAM)));
vphb.setSubmittedContent(retrieveString(storedParameters
.get(EditBean.SUBMITTED_CONTENT_PARAM)));
// FIXME sort out caretPosition
session.removeAttribute(Tool.HELPER_DONE_URL);
session.removeAttribute(FilePickerHelper.FILE_PICKER_CANCEL);
session.removeAttribute(FilePickerHelper.FILE_PICKER_ATTACHMENTS);
// finally dispatch to edit
dispatcher.dispatch(editPath, request, response);
}
private String generateNewContent(List refs, String content,
String caretPosition)
{
char[] charContent = content.toCharArray();
int startPos = charContent.length;
int endPos = charContent.length;
if (caretPosition == null)
{
caretPosition = "";
}
String[] caretPositions = caretPosition.split(":");
if (caretPositions.length > 0)
{
try
{
startPos = Integer.parseInt(caretPositions[0]);
}
catch (NumberFormatException e)
{
startPos = charContent.length;
}
}
if (caretPositions.length > 1)
{
try
{
endPos = Integer.parseInt(caretPositions[1]);
}
catch (NumberFormatException e)
{
endPos = startPos;
}
}
else
{
endPos = startPos;
}
if (startPos > charContent.length || startPos < 0)
{
startPos = charContent.length;
}
if (endPos > charContent.length || endPos < 0)
{
endPos = charContent.length;
}
if (endPos < startPos)
{
// I did have the XOR trick here, but I'm sure that's the JIT's job.
int temp = startPos;
startPos = endPos;
endPos = temp;
}
if (refs.size() > 1)
{
return multipleRefsContent(charContent, startPos, endPos, refs);
}
else
{
return singleRefContent(charContent, startPos, endPos,
(Reference) refs.get(0));
}
}
private String retrieveString(Object fromMap)
{
if (fromMap == null)
{
return null;
}
if (fromMap instanceof String[])
{
String[] array = (String[]) fromMap;
return array[0];
}
return fromMap.toString();
}
private String singleRefContent(char[] charContent, int startPos,
int endPos, Reference ref)
{
ResourceProperties refProps = ref.getProperties();
String contentType = refProps.getProperty(refProps
.getNamePropContentType());
String template = getTemplate(contentType);
Object[] args = getTemplateArgs(ref);
if (startPos != endPos)
{
// We have to use a different name for the "link"
args[2] = new String(charContent, startPos, endPos - startPos);
}
// Work out length properly
StringBuffer newContent = new StringBuffer(charContent.length
+ template.length());
newContent.append(charContent, 0, startPos);
(new MessageFormat(template)).format(args, newContent, null);
if (endPos < charContent.length)
{
newContent.append(charContent, endPos, charContent.length - endPos);
}
return newContent.toString();
}
private String multipleRefsContent(char[] charContent, int startPos,
int endPos, List refs)
{
StringBuffer newContent = new StringBuffer(charContent.length);
newContent.append(charContent, 0, startPos);
newContent.append(MULTIPLE_ATTACHMENT_HEADER_START);
if (startPos != endPos)
{
newContent.append(charContent, startPos, endPos - startPos);
}
else
{
newContent.append(MULTIPLE_ATTACHMENT_HEADER_BODY);
}
newContent.append(MULTIPLE_ATTACHMENT_HEADER_END);
for (Iterator it = refs.iterator(); it.hasNext();)
{
Reference ref = (Reference) it.next();
ResourceProperties refProps = ref.getProperties();
String contentType = refProps.getProperty(refProps
.getNamePropContentType());
String template = getTemplate(contentType);
Object[] args = getTemplateArgs(ref);
newContent.append(MULTIPLE_ATTACHMENT_ITEM);
(new MessageFormat(template)).format(args, newContent, null);
}
newContent.append(MULTIPLE_ATTACHMENT_ITEMS_END);
if (endPos < charContent.length)
{
newContent.append(charContent, endPos, charContent.length - endPos);
}
return newContent.toString();
}
private Object[] getTemplateArgs(Reference ref)
{
ResourceProperties refProps = ref.getProperties();
String name = refProps.getProperty(refProps.getNamePropDisplayName());
String contentType = refProps.getProperty(refProps
.getNamePropContentType());
String referenceString = ref.getReference();
String url = ref.getUrl();
Object[] templateArguments = new Object[5];
templateArguments[0] = url;
templateArguments[2] = name;
templateArguments[3] = contentType;
templateArguments[4] = referenceString;
// Interpret url as either worksite:/ or sakai:/ or http:/
String currentSiteId = ToolManager.getCurrentPlacement().getContext();
if (referenceString.startsWith("/content/group/"))
{
url = referenceString.substring("/content/group/".length());
if (url.startsWith(currentSiteId))
{
url = "worksite:/" + url.substring(currentSiteId.length()+1);
}
else
{
url = "sakai:/" + url;
}
}
else if (referenceString.startsWith("/content/group-user/"))
{
url = referenceString.substring("/content/group-user/".length());
if (url.startsWith(currentSiteId))
{
url = "dropbox:/" + url.substring(currentSiteId.length()+1);
}
else
{
url = "sakai-dropbox:/" + url;
}
}
else if (referenceString.startsWith("/content/user/"))
{
url = referenceString.substring("/content/user/".length());
if ( url.startsWith("~") ) {
url = url.substring(1);
}
if ( currentSiteId.startsWith("~") ) {
currentSiteId = currentSiteId.substring(1);
}
if (url.startsWith(currentSiteId))
{
url = "worksite:/" + url.substring(currentSiteId.length()+1);
}
else
{
url = "sakai:/~" + url;
}
}
templateArguments[1] = url;
return templateArguments;
}
public String getTemplate(String contentType)
{
if (wikiMarkupTemplates.containsKey(contentType))
{
return (String) wikiMarkupTemplates.get(contentType);
}
int slash = contentType.indexOf('/');
if (slash > -1)
{
String key = contentType.substring(0, slash) + "/*";
if (wikiMarkupTemplates.containsKey(key))
{
return (String) wikiMarkupTemplates.get(key);
}
}
return (String) wikiMarkupTemplates.get("*/*");
}
public Map getWikiMarkupTemplates()
{
return wikiMarkupTemplates;
}
public void setWikiMarkupTemplates(Map wikiMarkupTemplates)
{
this.wikiMarkupTemplates = wikiMarkupTemplates;
}
public String getEditPath()
{
return editPath;
}
public void setEditPath(String editPath)
{
this.editPath = editPath;
}
}