Skip to content

Commit

Permalink
LSNBLDR-542: New Lessons component: Add Resources Folder (sakaiprojec…
Browse files Browse the repository at this point in the history
…t#3622)

LSNBLDR-542: Resolve conflicts
  • Loading branch information
nicholaswilson100 authored and adrianfish committed Mar 13, 2017
1 parent 580231b commit 4c8573c
Show file tree
Hide file tree
Showing 25 changed files with 1,489 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package org.sakaiproject.content.entityproviders;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.net.URI;
import java.util.ArrayList;
import java.util.Comparator;
Expand All @@ -13,6 +17,8 @@
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.authz.api.SecurityService;
import org.sakaiproject.component.cover.ComponentManager;
import org.sakaiproject.content.api.ContentCollection;
Expand All @@ -21,27 +27,31 @@
import org.sakaiproject.content.api.ContentResource;
import org.sakaiproject.content.api.ResourceTypeRegistry;
import org.sakaiproject.content.tool.ListItem;
import org.sakaiproject.entity.api.EntityManager;
import org.sakaiproject.entity.api.EntityPermissionException;
import org.sakaiproject.entity.api.Reference;
import org.sakaiproject.entity.api.ResourceProperties;
import org.sakaiproject.entitybroker.EntityView;
import org.sakaiproject.entitybroker.entityprovider.EntityProvider;
import org.sakaiproject.entitybroker.entityprovider.annotations.EntityCustomAction;
import org.sakaiproject.entitybroker.entityprovider.annotations.EntityId;
import org.sakaiproject.entitybroker.entityprovider.annotations.EntityOwner;
import org.sakaiproject.entitybroker.entityprovider.annotations.EntityTitle;
import org.sakaiproject.entitybroker.entityprovider.capabilities.ActionsExecutable;
import org.sakaiproject.entitybroker.entityprovider.capabilities.AutoRegisterEntityProvider;
import org.sakaiproject.entitybroker.entityprovider.capabilities.Describeable;
import org.sakaiproject.entitybroker.entityprovider.capabilities.Outputable;
import org.sakaiproject.entitybroker.entityprovider.extension.Formats;
import org.sakaiproject.entitybroker.exception.EntityNotFoundException;
import org.sakaiproject.entitybroker.util.AbstractEntityProvider;
import org.sakaiproject.entitybroker.util.EntityDataUtils;
import org.sakaiproject.entitybroker.util.model.EntityContent;
import org.sakaiproject.exception.IdUnusedException;
import org.sakaiproject.exception.PermissionException;
import org.sakaiproject.exception.ServerOverloadException;
import org.sakaiproject.exception.TypeException;
import org.sakaiproject.site.api.Site;
import org.sakaiproject.site.api.SiteService;
import org.sakaiproject.site.api.ToolConfiguration;
import org.sakaiproject.time.api.Time;
import org.sakaiproject.time.cover.TimeService;
import org.sakaiproject.tool.api.ToolManager;
import org.sakaiproject.tool.api.Session;
import org.sakaiproject.tool.cover.SessionManager;
Expand All @@ -59,6 +69,9 @@ public class ContentEntityProvider extends AbstractEntityProvider implements Ent
public static final String PREFIX = "resources.";
public static final String SYS = "sys.";
private static final String STATE_RESOURCES_TYPE_REGISTRY = PREFIX + SYS + "type_registry";
private static Log log = LogFactory.getLog(ContentEntityProvider.class);
private static final String PARAMETER_DEPTH = "depth";
private static final String PARAMETER_TIMESTAMP = "timestamp";

@Override
public String getEntityPrefix() {
Expand Down Expand Up @@ -152,7 +165,183 @@ public List<ContentItem> getContentCollectionForSite(EntityView view) {
return getSiteListItems(siteId);

}
@EntityCustomAction(action="resources", viewKey=EntityView.VIEW_LIST)
public List<EntityContent> getResources(EntityView view, Map<String, Object> params)
throws EntityPermissionException {
String userId = developerHelperService.getCurrentUserId();
if (userId == null) {
throw new SecurityException(
"This action is not accessible to anon and there is no current user.");
}

Map<String, Object> parameters = getQueryMap((String)params.get("queryString"));
Time timeStamp = getTime((String)parameters.get(PARAMETER_TIMESTAMP));

int requestedDepth = 1;
int currentDepth = 0;
if (parameters.containsKey(PARAMETER_DEPTH)) {
if ("all".equals((String)parameters.get(PARAMETER_DEPTH))) {
requestedDepth = Integer.MAX_VALUE;
} else {
requestedDepth = Integer.parseInt((String)parameters.get(PARAMETER_DEPTH));
}
}

String[] segments = view.getPathSegments();

StringBuffer resourceId = new StringBuffer();
for (int i=2; i<segments.length; i++) {
resourceId.append("/"+segments[i]);
}
resourceId.append("/");

Reference reference = entityManager.newReference(
ContentHostingService.REFERENCE_ROOT+resourceId.toString());

// We could have used contentHostingService.getAllEntities(id) bit it doesn't do
// permission checks on any contained resources (documentation wrong).
// contentHostingService.getAllResources(String id) does do permission checks
// but it doesn't include collections in it's returned list.
// Also doing the recursion ourselves means that we don't loads lots of entities
// when the depth of recursion is low.
ContentCollection collection= null;
try {
collection = contentHostingService.getCollection(reference.getId());

} catch (IdUnusedException e) {
throw new IllegalArgumentException("IdUnusedException in Resource Entity Provider");

} catch (TypeException e) {
throw new IllegalArgumentException("TypeException in Resource Entity Provider");

} catch (PermissionException e) {
throw new SecurityException("PermissionException in Resource Entity Provider");
}

List<EntityContent> resourceDetails = new ArrayList<EntityContent>();
if (collection!=null) {
EntityContent resourceDetail = getResourceDetails(collection, currentDepth, requestedDepth, timeStamp);
if (resourceDetail != null) {
resourceDetails.add(resourceDetail);
} else {
log.error("Initial permission check passed but subsequent permission check failed on "+ reference.getId());
}
}
return resourceDetails;
}

/**
*
* @param entity The entity to load details of.
* @param currentDepth How many collections we have already processed
* @param requestedDepth The maximum number depth of the tree to scan.
* @param timeStamp All returned details must be newer than this timestamp.
* @return EntityContent containing details of all resources the user can access.
* <code>null</code> is returned if the current user isn't allowed to access the resource.
*/
private EntityContent getResourceDetails(
ContentEntity entity, int currentDepth, int requestedDepth, Time timeStamp) {
boolean allowed = (entity.isCollection()) ?
contentHostingService.allowGetCollection(entity.getId()) :
contentHostingService.allowGetResource(entity.getId());
if (!allowed) {
// If the user isn't allowed to see this we return null.
return null;
}
EntityContent tempRd = EntityDataUtils.getResourceDetails(entity);

// If it's a collection recurse down into it.
if ((requestedDepth > currentDepth) && entity.isCollection()) {

ContentCollection collection = (ContentCollection)entity;
// This is all members, no permission check has been done yet.
List<ContentEntity> contents = collection.getMemberResources();

Comparator comparator = getComparator(entity);
if (null != comparator) {
Collections.sort(contents, comparator);
}

for (Iterator<ContentEntity> i = contents.iterator(); i.hasNext();) {
ContentEntity content = i.next();
EntityContent resource = getResourceDetails(content, currentDepth+1, requestedDepth, timeStamp);

if (resource != null && resource.after(timeStamp)) {
tempRd.addResourceChild(resource);
}
}
}

return tempRd;
}

/**
*
* @param entity
* @return
*/
private Comparator getComparator(ContentEntity entity) {

boolean hasCustomSort = false;
try {
hasCustomSort = entity.getProperties().getBooleanProperty(
ResourceProperties.PROP_HAS_CUSTOM_SORT);

} catch(Exception e) {
// ignore -- let value of hasCustomSort stay false
}

if(hasCustomSort) {
return contentHostingService.newContentHostingComparator(
ResourceProperties.PROP_CONTENT_PRIORITY, true);
} else {
return contentHostingService.newContentHostingComparator(
ResourceProperties.PROP_DISPLAY_NAME, true);
}
}

/**
*
* @param queryString
* @return
*/
private Map<String, Object> getQueryMap(String queryString) {

Map<String, Object> params = new HashMap<String, Object>();
if (null != queryString && !queryString.isEmpty()) {
String[] strings = queryString.split("&");
for (int i=0; i<strings.length; i++) {
String parameter = strings[i];
int j = parameter.indexOf("=");
params.put(parameter.substring(0, j), parameter.substring(j+1));
}
}
return params;
}

/**
*
* @param timestamp use formatter A: yyyyMMddHHmmssSSS
* @return
*/
private Time getTime(String timestamp) {

try {

if (null != timestamp) {
DateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");
Date date = format.parse(timestamp);
Calendar c = Calendar.getInstance();
c.setTime(date);

return TimeService.newTimeGmt(format.format(date));
}

} catch (ParseException e) {
return TimeService.newTimeGmt("20201231235959999");
}
return null;
}
private List<ContentItem> getSiteListItems(String siteId) {
List<ContentItem> rv = new ArrayList<ContentItem>();
String wsCollectionId = contentHostingService.getSiteCollection(siteId);
Expand Down Expand Up @@ -525,6 +714,8 @@ public String[] getHandledOutputFormats() {
@Setter
private UserDirectoryService userDirectoryService;

@Setter
private EntityManager entityManager;



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<property name="toolManager" ref="org.sakaiproject.tool.api.ToolManager"/>
<property name="securityService" ref="org.sakaiproject.authz.api.SecurityService"/>
<property name="userDirectoryService" ref="org.sakaiproject.user.api.UserDirectoryService"/>
<property name="entityManager" ref="org.sakaiproject.entity.api.EntityManager" />
</bean>

</beans>
4 changes: 4 additions & 0 deletions entitybroker/rest/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
<groupId>org.sakaiproject.entitybroker</groupId>
<artifactId>entitybroker-utils</artifactId>
</dependency>
<dependency>
<groupId>org.sakaiproject.kernel</groupId>
<artifactId>sakai-kernel-api</artifactId>
</dependency>
<!-- internal testing -->
<dependency>
<groupId>org.sakaiproject.entitybroker</groupId>
Expand Down
4 changes: 4 additions & 0 deletions entitybroker/utils/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
<groupId>org.sakaiproject.kernel</groupId>
<artifactId>sakai-component-manager</artifactId>
</dependency>
<dependency>
<groupId>org.sakaiproject.kernel</groupId>
<artifactId>sakai-kernel-api</artifactId>
</dependency>
<!-- required for bean cloning and reflection -->
<dependency>
<groupId>org.azeckoski</groupId>
Expand Down
Loading

0 comments on commit 4c8573c

Please sign in to comment.