/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/kernel/trunk/kernel-impl/src/main/java/org/sakaiproject/content/impl/CollectionAccessFormatter.java $
* $Id: CollectionAccessFormatter.java 122028 2013-04-01 19:49:35Z azeckoski@unicon.net $
***********************************************************************************
*
* Copyright (c) 2006, 2007, 2008, 2009 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.impl;
import java.io.PrintWriter;
import java.net.URI;
import java.util.Collections;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.component.cover.ServerConfigurationService;
import org.sakaiproject.content.api.ContentCollection;
import org.sakaiproject.content.api.ContentEntity;
import org.sakaiproject.content.api.ContentHostingService;
import org.sakaiproject.entity.api.Entity;
import org.sakaiproject.entity.api.Reference;
import org.sakaiproject.entity.api.ResourceProperties;
import org.sakaiproject.exception.IdUnusedException;
import org.sakaiproject.site.api.Site;
import org.sakaiproject.site.api.SiteService;
import org.sakaiproject.user.api.User;
import org.sakaiproject.user.api.UserNotDefinedException;
import org.sakaiproject.util.ResourceLoader;
import org.sakaiproject.util.Validator;
/**
* <p>
* CollectionAccessFormatter is formatter for collection access.
* </p>
*/
@SuppressWarnings("deprecation")
public class CollectionAccessFormatter
{
private static final Log M_log = LogFactory.getLog(CollectionAccessFormatter.class);
/**
* Format the collection as an HTML display.
*/
@SuppressWarnings({ "unchecked" })
public static void format(ContentCollection x, Reference ref, HttpServletRequest req, HttpServletResponse res, ResourceLoader rb,
String accessPointTrue, String accessPointFalse, ContentHostingService contentHostingService, SiteService siteService)
{
// do not allow directory listings for /attachments and its subfolders
if (contentHostingService.isAttachmentResource(x.getId()))
{
try
{
res.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
catch ( java.io.IOException e )
{
return;
}
}
PrintWriter out = null;
// don't set the writer until we verify that
// getallresources is going to work.
boolean printedHeader = false;
boolean printedDiv = false;
try
{
res.setContentType("text/html; charset=UTF-8");
out = res.getWriter();
ResourceProperties pl = x.getProperties();
String webappRoot = ServerConfigurationService.getServerUrl();
String skinRepo = ServerConfigurationService.getString("skin.repo", "/library/skin");
String skinName = "default";
String[] parts= StringUtils.split(x.getId(), Entity.SEPARATOR);
// Is this a site folder (Resources or Dropbox)? If so, get the site skin
if (x.getId().startsWith(org.sakaiproject.content.api.ContentHostingService.COLLECTION_SITE) ||
x.getId().startsWith(org.sakaiproject.content.api.ContentHostingService.COLLECTION_DROPBOX)) {
if (parts.length > 1) {
String siteId = parts[1];
try {
Site site = siteService.getSite(siteId);
if (site.getSkin() != null) {
skinName = site.getSkin();
}
} catch (IdUnusedException e) {
// Cannot get site - ignore it
}
}
}
// Output the headers
out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">");
out.println("<html><head>");
out.println("<title>" + rb.getFormattedMessage("colformat.pagetitle",
new Object[]{ Validator.escapeHtml(pl.getProperty(ResourceProperties.PROP_DISPLAY_NAME))}) + "</title>");
out.println("<link href=\"" + webappRoot + skinRepo+ "/" + skinName +
"/access.css\" type=\"text/css\" rel=\"stylesheet\" media=\"screen\">");
out.println("<script src=\"" + webappRoot
+ "/library/js/jquery.js\" type=\"text/javascript\">");
out.println("</script>");
out.println("</head><body class=\"specialLink\">");
out.println("<script type=\"text/javascript\" src=\"/library/js/access.js\"></script>");
out.println("<div class=\"directoryIndex\">");
// for content listing it's best to use a real title
out.println("<h3>" + Validator.escapeHtml(pl.getProperty(ResourceProperties.PROP_DISPLAY_NAME)) + "</h3>");
out.println("<p id=\"toggle\"><a id=\"toggler\" href=\"#\">" + rb.getString("colformat.showhide") + "</a></p>");
String folderdesc = pl.getProperty(ResourceProperties.PROP_DESCRIPTION);
if (folderdesc != null && !folderdesc.equals("")) out.println("<div class=\"textPanel\">" + folderdesc + "</div>");
out.println("<ul>");
out.println("<li style=\"display:none\">");
out.println("</li>");
printedHeader = true;
printedDiv = true;
if (parts.length > 2)
{
// go up a level
out.println("<li class=\"upfolder\"><a href=\"../\"><img src=\"/library/image/sakai/folder-up.gif\" alt=\"" + rb.getString("colformat.uplevel.alttext") + "\"/>" + rb.getString("colformat.uplevel") + "</a></li>");
}
// Sort the collection items
List<ContentEntity> members = x.getMemberResources();
boolean hasCustomSort = false;
try {
hasCustomSort = x.getProperties().getBooleanProperty(ResourceProperties.PROP_HAS_CUSTOM_SORT);
} catch (Exception e) {
// use false that's already there
}
if (hasCustomSort)
Collections.sort(members, new ContentHostingComparator(ResourceProperties.PROP_CONTENT_PRIORITY, true));
else
Collections.sort(members, new ContentHostingComparator(ResourceProperties.PROP_DISPLAY_NAME, true));
// Iterate through content items
URI baseUri = new URI(x.getUrl());
for (ContentEntity content : members) {
ResourceProperties properties = content.getProperties();
boolean isCollection = content.isCollection();
String xs = content.getId();
String contentUrl = content.getUrl();
// These both perform the same check in the implementation but we should observe the API.
// This also checks to see if a resource is hidden or time limited.
if ( isCollection) {
if (!contentHostingService.allowGetCollection(xs)) {
continue;
}
} else {
if (!contentHostingService.allowGetResource(xs)) {
continue;
}
}
if (isCollection)
{
xs = xs.substring(0, xs.length() - 1);
xs = xs.substring(xs.lastIndexOf('/') + 1) + '/';
}
else
{
xs = xs.substring(xs.lastIndexOf('/') + 1);
}
try
{
// Relativize the URL (canonical item URL relative to canonical collection URL).
// Inter alias this will preserve alternate access paths via aliases, e.g. /web/
URI contentUri = new URI(contentUrl);
URI relativeUri = baseUri.relativize(contentUri);
contentUrl = relativeUri.toString();
if (isCollection)
{
// Folder
String desc = properties.getProperty(ResourceProperties.PROP_DESCRIPTION);
if ((desc == null) || desc.equals(""))
desc = "";
else
desc = "<div class=\"textPanel\">" + desc + "</div>";
out.println("<li class=\"folder\"><a href=\"" + contentUrl + "\">"
+ Validator.escapeHtml(properties.getProperty(ResourceProperties.PROP_DISPLAY_NAME))
+ "</a>" + desc + "</li>");
}
else
{
// File
/*
String createdBy = getUserProperty(properties, ResourceProperties.PROP_CREATOR).getDisplayName();
Time modTime = properties.getTimeProperty(ResourceProperties.PROP_MODIFIED_DATE);
String modifiedTime = modTime.toStringLocalShortDate() + " " + modTime.toStringLocalShort();
ContentResource contentResource = (ContentResource) content;
long filesize = ((contentResource.getContentLength() - 1) / 1024) + 1;
String filetype = contentResource.getContentType();
*/
String desc = properties.getProperty(ResourceProperties.PROP_DESCRIPTION);
if ((desc == null) || desc.equals(""))
desc = "";
else
desc = "<div class=\"textPanel\">" + Validator.escapeHtml(desc) + "</div>";
String resourceType = content.getResourceType().replace('.', '_');
out.println("<li class=\"file\"><a href=\"" + contentUrl + "\" target=_blank class=\""
+ resourceType+"\">"
+ Validator.escapeHtml(properties.getProperty(ResourceProperties.PROP_DISPLAY_NAME))
+ "</a>" + desc + "</li>");
}
}
catch (Exception ignore)
{
// TODO - what types of failures are being caught here?
out.println("<li class=\"file\"><a href=\"" + contentUrl + "\" target=_blank>" + Validator.escapeHtml(xs)
+ "</a></li>");
}
}
}
catch (Exception e)
{
M_log.warn("Problem formatting HTML for collection: "+ x.getId(), e);
}
if (out != null && printedHeader)
{
out.println("</ul>");
if (printedDiv) out.println("</div>");
out.println("</body></html>");
}
}
/**
* @deprecated - no references to this method found
*/
protected static User getUserProperty(ResourceProperties props, String name)
{
// String id = props.getProperty(name);
// if (id != null)
// {
// try
// {
// return UserDirectoryService.getUser(id);
// }
// catch (UserNotDefinedException e)
// {
// }
// }
return null;
}
}