Java tutorial
/* * Licensed to The Apereo Foundation under one or more contributor license * agreements. See the NOTICE file distributed with this work for * additional information regarding copyright ownership. * * The Apereo Foundation licenses this file to you 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://opensource.org/licenses/ecl2.txt * * 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.signup.tool.jsf.attachment; import java.io.Serializable; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.sakaiproject.authz.api.Role; import org.sakaiproject.content.api.ContentResource; import org.sakaiproject.content.api.FilePickerHelper; import org.sakaiproject.entity.api.Reference; import org.sakaiproject.entity.api.ResourceProperties; import org.sakaiproject.entity.cover.EntityManager; import org.sakaiproject.exception.IdUnusedException; import org.sakaiproject.exception.InUseException; import org.sakaiproject.exception.PermissionException; import org.sakaiproject.exception.TypeException; import org.sakaiproject.signup.logic.SakaiFacade; import org.sakaiproject.signup.logic.SignupMeetingService; import org.sakaiproject.signup.model.SignupAttachment; import org.sakaiproject.signup.model.SignupMeeting; import org.sakaiproject.signup.model.SignupSite; import org.sakaiproject.site.api.Site; import org.sakaiproject.tool.api.ToolSession; import org.sakaiproject.tool.cover.SessionManager; /* * <p> This class will provides add/remove attachment functionality for sign-up tool. * </P> */ public class AttachmentHandler implements Serializable { private static Log log = LogFactory.getLog(AttachmentHandler.class); private List<SignupAttachment> attachments; private SakaiFacade sakaiFacade; private SignupMeetingService signupMeetingService; /** * default constructor */ public AttachmentHandler() { } /** * Constructor * * @param sakaiFacade * -SakaiFacade object * @param signupMeetingService * -SignupMeetingService object */ public AttachmentHandler(SakaiFacade sakaiFacade, SignupMeetingService signupMeetingService) { this.sakaiFacade = sakaiFacade; this.signupMeetingService = signupMeetingService; } public void clear() { this.attachments = null; } /** * Redirect the add/remove attachment to Sakai's help page. * * @param attachList - * a list of attachment objects * @param sMeeting - * SignupMeeting object * @param isOrganizer - * a boolean value * @return null value */ public String processAddAttachRedirect(List attachList, SignupMeeting sMeeting, boolean isOrganizer) { this.attachments = attachList; try { List filePickerList = prepareReferenceList(attachments, sMeeting, isOrganizer); ToolSession currentToolSession = SessionManager.getCurrentToolSession(); currentToolSession.setAttribute(FilePickerHelper.FILE_PICKER_ATTACHMENTS, filePickerList); ExternalContext context = FacesContext.getCurrentInstance().getExternalContext(); context.redirect("sakai.filepicker.helper/tool"); } catch (Exception e) { log.error("fail to redirect to attachment page: " + e.getMessage()); } return null; } private List prepareReferenceList(List attachmentList, SignupMeeting sMeeting, boolean isOrganizer) { List list = new ArrayList(); if (attachmentList == null) { return list; } for (int i = 0; i < attachmentList.size(); i++) { ContentResource cr = null; SignupAttachment attach = (SignupAttachment) attachmentList.get(i); try { cr = getSakaiFacade().getContentHostingService().getResource(attach.getResourceId()); } catch (PermissionException e) { log.warn("ContentHostingService.getResource() throws PermissionException=" + e.getMessage()); } catch (IdUnusedException e) { log.warn("ContentHostingService.getResource() throws IdUnusedException=" + e.getMessage()); /* * If the attachment somehow get removed from CHS and it's a * broken link */ RemoveAttachment removeAttach = new RemoveAttachment(signupMeetingService, sakaiFacade.getCurrentUserId(), sakaiFacade.getCurrentLocationId(), isOrganizer); removeAttach.removeAttachment(sMeeting, attach); } catch (TypeException e) { log.warn("ContentHostingService.getResource() throws TypeException=" + e.getMessage()); } catch (Exception e) { log.warn("Exception: " + e.getMessage()); } if (cr != null) { Reference ref = EntityManager.newReference(cr.getReference()); if (ref != null) list.add(ref); } } return list; } /** * Called by SamigoJsfTool.java on exit from file picker */ public void setAttachmentItems() { /* * they share the same attachments pointer with JSF bean and via this to * pass updated list */ processItemAttachment(); } private void processItemAttachment() { ToolSession session = SessionManager.getCurrentToolSession(); if (session.getAttribute(FilePickerHelper.FILE_PICKER_ATTACHMENTS) != null) { HashMap map = getResourceIdHash(this.attachments); ArrayList newAttachmentList = new ArrayList(); String protocol = getSakaiFacade().getServerConfigurationService().getServerUrl(); List refs = (List) session.getAttribute(FilePickerHelper.FILE_PICKER_ATTACHMENTS); if (refs != null && refs.size() > 0) { Reference ref; for (int i = 0; i < refs.size(); i++) { ref = (Reference) refs.get(i); String resourceId = ref.getId(); if (map.get(resourceId) == null) { // new attachment, add SignupAttachment newAttach = createSignupAttachment(ref.getId(), ref.getProperties().getProperty(ref.getProperties().getNamePropDisplayName()), protocol); newAttachmentList.add(newAttach); } else { // attachment already exist, let's add it to new list // and // check it off from map newAttachmentList.add((SignupAttachment) map.get(resourceId)); map.remove(resourceId); } } } session.removeAttribute(FilePickerHelper.FILE_PICKER_ATTACHMENTS); session.removeAttribute(FilePickerHelper.FILE_PICKER_CANCEL); this.attachments.clear(); this.attachments.addAll(newAttachmentList); } } private HashMap<String, SignupAttachment> getResourceIdHash(List<SignupAttachment> attachList) { HashMap<String, SignupAttachment> map = new HashMap<String, SignupAttachment>(); if (attachList != null) { for (SignupAttachment attach : attachList) { map.put(attach.getResourceId(), attach); } } return map; } /** * Create a new copy of the attachment * * @param sMeeting * -SignupMeeting object * @param isOrganizer - * a boolean value * @param attach * -SignupAttachment object * @param folderId - * a foldId string object * @return - a SignupAttachment object */ public SignupAttachment copySignupAttachment(SignupMeeting sMeeting, boolean isOrganizer, SignupAttachment attach, String folderId) { SignupAttachment newAttach = null; ContentResource cr = null; ContentResource newCr = null; if (attach == null || attach.getResourceId().trim().length() < 1) return null; String newResourceId = attach.getResourceId(); int index = attach.getResourceId().lastIndexOf("/"); if (index > -1) { newResourceId = newResourceId.substring(0, index + 1) + folderId + "/" + newResourceId.substring(index + 1, newResourceId.length()); } try { cr = getSakaiFacade().getContentHostingService().getResource(attach.getResourceId()); if (cr != null) { String protocol = getSakaiFacade().getServerConfigurationService().getServerUrl(); newResourceId = getSakaiFacade().getContentHostingService().copy(attach.getResourceId(), newResourceId); newCr = getSakaiFacade().getContentHostingService().getResource(newResourceId); Reference ref = EntityManager.newReference(newCr.getReference()); if (ref != null) { newAttach = createSignupAttachment(ref.getId(), ref.getProperties().getProperty(ref.getProperties().getNamePropDisplayName()), protocol); /* Case: for cross-sites, make it to public view */ determineAndAssignPublicView(sMeeting, newAttach); } } } catch (PermissionException e) { log.warn("ContentHostingService.getResource() throws PermissionException=" + e.getMessage()); } catch (IdUnusedException e) { log.warn("ContentHostingService.getResource() throws IdUnusedException=" + e.getMessage()); /* * If the attachment somehow get removed from CHS and it's a broken * link */ RemoveAttachment removeAttach = new RemoveAttachment(signupMeetingService, sakaiFacade.getCurrentUserId(), sakaiFacade.getCurrentLocationId(), isOrganizer); removeAttach.removeAttachment(sMeeting, attach); } catch (TypeException e) { log.warn("ContentHostingService.getResource() throws TypeException=" + e.getMessage()); } catch (Exception e) { log.warn("ContentHostingService.getResource() throws Exception=" + e.getMessage()); } return newAttach; } public void removeAttachmentInContentHost(SignupAttachment attach) { if (attach == null || attach.getResourceId() == null) return; try { getSakaiFacade().getContentHostingService().removeResource(attach.getResourceId()); } catch (PermissionException e) { log.warn("ContentHostingService.getResource() throws PermissionException=" + e.getMessage()); } catch (IdUnusedException e) { log.warn("ContentHostingService.getResource() throws IdUnusedException=" + e.getMessage()); } catch (TypeException e) { log.warn("ContentHostingService.getResource() throws TypeException=" + e.getMessage()); } catch (InUseException e) { log.warn("ContentHostingService.getResource() throws InUseException=" + e.getMessage()); } catch (Exception e) { log.warn("ContentHostingService.getResource() throws Exception=" + e.getMessage()); } } public SakaiFacade getSakaiFacade() { return sakaiFacade; } public void setSakaiFacade(SakaiFacade sakaiFacade) { this.sakaiFacade = sakaiFacade; } public SignupMeetingService getSignupMeetingService() { return signupMeetingService; } public void setSignupMeetingService(SignupMeetingService signupMeetingService) { this.signupMeetingService = signupMeetingService; } public List<SignupAttachment> getAttachments() { return this.attachments; } public void setAttachments(List<SignupAttachment> attachments) { this.attachments = attachments; } protected SignupAttachment createSignupAttachment(String resourceId, String filename, String protocol) { SignupAttachment attach = new SignupAttachment(); Boolean isLink = Boolean.FALSE; try { ContentResource cr = getSakaiFacade().getContentHostingService().getResource(resourceId); if (cr != null) { ResourceProperties p = cr.getProperties(); attach = new SignupAttachment(); attach.setResourceId(resourceId); attach.setMimeType(cr.getContentType()); // we want to display kb, so divide by 1000 and round the result attach.setFileSize(new Long("" + fileSizeInKB((int) cr.getContentLength())));//2Gb?? if (cr.getContentType().lastIndexOf("url") > -1) { isLink = Boolean.TRUE; if (!filename.toLowerCase().startsWith("http")) { String adjustedFilename = "http://" + filename; attach.setFilename(adjustedFilename); } else { attach.setFilename(filename); } } else { attach.setFilename(filename); } attach.setIsLink(isLink); attach.setCreatedBy(p.getProperty(p.getNamePropCreator())); attach.setCreatedDate(new Date()); attach.setLastModifiedBy(p.getProperty(p.getNamePropModifiedBy())); attach.setLastModifiedDate(new Date()); attach.setLocation(getRelativePath(cr.getUrl(), protocol)); } } catch (PermissionException pe) { log.warn("PermissionException: " + pe.getMessage()); } catch (IdUnusedException ie) { log.warn("IdUnusedException: " + ie.getMessage()); } catch (TypeException te) { log.warn("TypeException: " + te.getMessage()); } return attach; } private String fileSizeInKB(int fileSize) { String fileSizeString = "1"; int size = Math.round((float) fileSize / 1024.0f); if (size > 0) { fileSizeString = size + ""; } return fileSizeString; } public String getRelativePath(String url, String protocol) { // replace whitespace with %20 url = replaceSpace(url); int index = url.lastIndexOf(protocol); if (index == 0) { url = url.substring(protocol.length()); } return url; } public void setPublicView(String resourceId, boolean pubview) { getSakaiFacade().getContentHostingService().setPubView(resourceId, pubview); } private String replaceSpace(String tempString) { String newString = ""; char[] oneChar = new char[1]; for (int i = 0; i < tempString.length(); i++) { if (tempString.charAt(i) != ' ') { oneChar[0] = tempString.charAt(i); String concatString = new String(oneChar); newString = newString.concat(concatString); } else { newString = newString.concat("%20"); } } return newString; } /** * If it's a cross sites or for other site, the attachment will be set to * public view in ContentHostingService * * @param sMeeting - * a SignupMeeting object * @param attach - * a SignupAttachment object */ public void determineAndAssignPublicView(SignupMeeting sMeeting, SignupAttachment attach) { if (attach == null) return; /* Case 1: multiple sites - set to public view */ if (sMeeting.getSignupSites() != null && sMeeting.getSignupSites().size() > 1) { getSakaiFacade().getContentHostingService().setPubView(attach.getResourceId(), true); return; } Site site = null; if (sMeeting.getSignupSites() == null || sMeeting.getSignupSites().isEmpty()) return; SignupSite signupSite = sMeeting.getSignupSites().get(0); try { site = getSakaiFacade().getSiteService().getSite(signupSite.getSiteId()); } catch (IdUnusedException e) { log.error(e.getMessage(), e); } if (site == null) return; /* Case 2: publish the event for other site only - set to public view */ if (!site.getId().equals(sakaiFacade.getCurrentLocationId())) { getSakaiFacade().getContentHostingService().setPubView(attach.getResourceId(), true); return; } /* * case 3: If site has roleId '.auth', any logged-in user should see it - * set to public view */ Set siteRoles = site.getRoles(); if (siteRoles != null) { for (Iterator iter = siteRoles.iterator(); iter.hasNext();) { Role role = (Role) iter.next(); /* '.auth' roleId */ if (SakaiFacade.REALM_ID_FOR_LOGIN_REQUIRED_ONLY.equals(role.getId())) { getSakaiFacade().getContentHostingService().setPubView(attach.getResourceId(), true); break; } } } } }