package com.idega.presentation.file; import java.net.URLDecoder; import java.text.Collator; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.TreeMap; import java.util.logging.Level; import java.util.logging.Logger; import javax.ejb.FinderException; import javax.faces.component.UIComponent; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.context.support.WebApplicationContextUtils; import com.idega.builder.bean.AdvancedProperty; import com.idega.business.file.FileStatisticsProvider; import com.idega.core.accesscontrol.data.LoginRecord; import com.idega.core.accesscontrol.data.LoginRecordHome; import com.idega.core.business.GeneralCompanyBusiness; import com.idega.core.company.bean.GeneralCompany; import com.idega.core.contact.data.Email; import com.idega.core.file.data.ICFile; import com.idega.core.file.data.ICFileHome; import com.idega.data.IDOLookup; import com.idega.data.IDOLookupException; import com.idega.idegaweb.IWResourceBundle; import com.idega.presentation.Block; import com.idega.presentation.IWContext; import com.idega.presentation.Layer; import com.idega.presentation.Table2; import com.idega.presentation.TableBodyRowGroup; import com.idega.presentation.TableHeaderRowGroup; import com.idega.presentation.TableRow; import com.idega.presentation.text.Break; import com.idega.presentation.text.Heading1; import com.idega.presentation.text.Heading3; import com.idega.presentation.text.Link; import com.idega.presentation.text.Text; import com.idega.presentation.ui.GenericButton; import com.idega.user.data.User; import com.idega.util.CoreConstants; import com.idega.util.IWTimestamp; import com.idega.util.ListUtil; import com.idega.util.StringUtil; import com.idega.util.expression.ELUtil; public abstract class FileDownloadStatisticsViewer extends Block { public static final String PARAMETER_FILE_ID = "fileId"; public static final String PARAMETER_FILE_HASH = "fileHash"; public static final String SHOW_COMPANY = "show-company"; public static final String SHOW_LAST_LOGIN_DATE = "show-lld"; private AdvancedProperty file; private ICFile realFile; private String fileHolderIdentifier; private Boolean showCompany = null; private Boolean showLastLoginDate = null; @Autowired(required = false) private GeneralCompanyBusiness generalCompanyBusiness; private GeneralCompanyBusiness getGeneralCompanyBusiness() { if (generalCompanyBusiness == null) { try { generalCompanyBusiness = ELUtil.getInstance().getBean(GeneralCompanyBusiness.BEAN_NAME); } catch (Exception e) { getLogger().warning("There is no implementation for " + GeneralCompanyBusiness.class.getName()); } } return generalCompanyBusiness; } @Override public void main(IWContext iwc) throws Exception { ELUtil.getInstance().autowire(this); IWResourceBundle iwrb = getResourceBundle(iwc); boolean showCompany = isShowCompany(iwc); boolean showLastLoginDate = isShowLastLoginDate(iwc); Layer container = new Layer(); add(container); container.setStyleClass("fileDownloadStatisticsViewerStyle"); if (!hasRights(iwc)) { container.add(new Heading1(iwrb.getLocalizedString("download_stats.no_rights", "Sorry, you do not have rights to view statistics"))); return; } AdvancedProperty file = getFile(iwc); ICFile realFile = getRealFile(iwc); Collection<User> downloaders = realFile == null ? null : realFile.getDownloadedBy(); if(!ListUtil.isEmpty(downloaders)){ final Locale locale = iwc.getCurrentLocale(); Comparator<User> comparator = new Comparator<User>() { private Collator collator = Collator.getInstance(locale); @Override public int compare(User user1, User user2) { String user1Name = user1.getName().toUpperCase(); String user2Name = user2.getName().toUpperCase(); //ascending order return collator.compare(user1Name, user2Name); } }; List<User> userList = (List<User>) (downloaders instanceof List ? downloaders : new ArrayList<User>(downloaders)); TreeMap<String, User> userMap = new TreeMap<String, User>(); Collections.sort(userList,comparator); downloaders = userList; } Locale locale = iwc.getCurrentLocale(); if (file != null) { container.add(new Heading3(new StringBuilder(iwrb.getLocalizedString("download_stats.downloads_statistics_for", "Download statistics for")) .append(": ").append(URLDecoder.decode(file.getValue(), CoreConstants.ENCODING_UTF8)).toString())); container.add(new Break()); } if (!ListUtil.isEmpty(downloaders)) { Table2 table = new Table2(); container.add(table); TableHeaderRowGroup headerRows = table.createHeaderRowGroup(); TableRow row = headerRows.createRow(); row.createCell().add(new Text(iwrb.getLocalizedString("download_stats.nr", "Nr"))); row.createCell().add(new Text(iwrb.getLocalizedString("download_stats.name", "Name"))); row.createCell().add(new Text(iwrb.getLocalizedString("download_stats.personal_id", "Personal ID"))); row.createCell().add(new Text(iwrb.getLocalizedString("download_stats.email", "E-mail"))); if(showCompany){ row.createCell().add(new Text(iwrb.getLocalizedString("download_stats.company", "Company"))); } if(showLastLoginDate){ row.createCell().add(new Text(iwrb.getLocalizedString("download_stats.last_login", "Last login"))); } int index = 0; TableBodyRowGroup bodyRows = table.createBodyRowGroup(); LoginRecordHome loginrecorshoHome = null; if(showLastLoginDate){ try { loginrecorshoHome = (LoginRecordHome) IDOLookup.getHome(LoginRecord.class); } catch (IDOLookupException e) { getLogger().log(Level.WARNING, "Failed getting loginrecordhome", e); } } for (User downloader: downloaders) { row = bodyRows.createRow(); row.createCell().add(new Text(new StringBuilder().append(index + 1).append(CoreConstants.DOT).toString())); row.createCell().add(new Text(downloader.getName())); row.createCell().add(new Text(downloader.getPersonalID())); String emailAddress = getEmailAddress(iwc, downloader); row.createCell().add(StringUtil.isEmpty(emailAddress) ? new Text(CoreConstants.MINUS) : new Link(emailAddress, new StringBuilder("mailto:").append(emailAddress).toString())); if (showCompany && getGeneralCompanyBusiness() != null) { Collection<GeneralCompany> companies = getGeneralCompanyBusiness().getCompaniesForUser(downloader); String companyName; if(ListUtil.isEmpty(companies)){ companyName = CoreConstants.MINUS; }else{ companyName = companies.iterator().next().getName(); if(StringUtil.isEmpty(companyName)){ companyName = CoreConstants.MINUS; } } row.createCell().add(new Text(companyName)); } if(showLastLoginDate){ try { LoginRecord loginRecord = loginrecorshoHome.findLastLoginRecord(downloader); String date = new IWTimestamp(loginRecord.getLogInStamp()).getLocaleDateAndTime(locale); row.createCell().add(new Text(date)); } catch (FinderException e) { getLogger().log(Level.WARNING, "Failed getting login record of user "+downloader.getId(), e); } } index++; } } addNotifier(iwc, container, file, downloaders); } @SuppressWarnings("unchecked") public Collection<User> getPotentialDownloaders(IWContext iwc) { Map<String, ? extends FileStatisticsProvider> beans = WebApplicationContextUtils.getWebApplicationContext(iwc.getServletContext()) .getBeansOfType(FileStatisticsProvider.class); if (beans == null || beans.isEmpty()) { return null; } Collection<User> allDownloaders = new ArrayList<User>(); for (FileStatisticsProvider statisticsProvider: beans.values()) { Collection<User> downloaders = statisticsProvider.getPotentialDownloaders(getFileHolderIdentifier()); if (!ListUtil.isEmpty(downloaders)) { for (User downloader: downloaders) { if (!allDownloaders.contains(downloader)) { allDownloaders.add(downloader); } } } } return allDownloaders; } public void addNotifier(IWContext iwc, Layer container, AdvancedProperty file, Collection<User> downloaders) { Collection<User> usersToInform = getUsersToInform(iwc, downloaders); if (ListUtil.isEmpty(usersToInform) && ListUtil.isEmpty(downloaders)) { Layer noReaders = new Layer(); container.add(noReaders); noReaders.add(new Heading3(getMessageNobodyIsInterested(iwc))); return; } if (!ListUtil.isEmpty(usersToInform)) { container.add(getNotifierButton(iwc, file, usersToInform)); } } public abstract String getMessageNobodyIsInterested(IWContext iwc); protected UIComponent getNotifierButton(IWContext iwc, AdvancedProperty file, Collection<User> usersToInform) { Layer notificationContainer = new Layer(); notificationContainer.setStyleClass("fileDownloadStatisticsNotificationContainer"); GenericButton notify = new GenericButton("sendNotifications", getResourceBundle(iwc).getLocalizedString("download_stats.send_remind", "Remind readers to download this document")); String action = getNotifierAction(iwc, file, usersToInform); if (StringUtil.isEmpty(action)) { return notificationContainer; } notificationContainer.add(notify); notify.setOnClick(action); return notificationContainer; } public abstract String getNotifierAction(IWContext iwc, AdvancedProperty file, Collection<User> usersToInform); public Collection<User> getUsersToInform(IWContext iwc, Collection<User> downloaders) { Collection<User> potentialDownloaders = getPotentialDownloaders(iwc); if (ListUtil.isEmpty(potentialDownloaders)) { return null; } Collection<User> usersToInform = null; if (ListUtil.isEmpty(downloaders)) { usersToInform = potentialDownloaders; } else { usersToInform = new ArrayList<User>(); for (User reader: potentialDownloaders) { if (!downloaders.contains(reader)) { usersToInform.add(reader); } } } return usersToInform; } private String getEmailAddress(IWContext iwc, User user) { Collection<Email> mails = user.getEmails(); if (ListUtil.isEmpty(mails)) { return null; } return mails.iterator().next().getEmailAddress(); } protected ICFile getRealFile(IWContext iwc) { ICFile file = getRealFile(); if (file != null) { return file; } ICFileHome fileHome = null; try { fileHome = (ICFileHome) IDOLookup.getHome(ICFile.class); } catch(Exception e) { e.printStackTrace(); } if (fileHome == null) { return null; } if (iwc.isParameterSet(PARAMETER_FILE_ID)) { try { file = fileHome.findByPrimaryKey(iwc.getParameter(PARAMETER_FILE_ID)); } catch(FinderException e) { Logger.getLogger(FileDownloadStatisticsViewer.class.getName()).warning("File was not found by id: " + iwc.getParameter(PARAMETER_FILE_ID)); } } if (file == null && iwc.isParameterSet(PARAMETER_FILE_HASH)) { try { file = fileHome.findByHash(Integer.valueOf(iwc.getParameter(PARAMETER_FILE_HASH))); } catch(FinderException e) { Logger.getLogger(FileDownloadStatisticsViewer.class.getName()).warning("File was not found by hash: " + iwc.getParameter(PARAMETER_FILE_HASH)); } } if (file != null) { setRealFile(file); } return file; } protected AdvancedProperty getFile(IWContext iwc) { ICFile icFile = getRealFile(iwc); if (icFile == null) { return null; } AdvancedProperty file = new AdvancedProperty(icFile.getId(), icFile.getName()); setFile(file); return file; } public AdvancedProperty getFile() { return file; } public void setFile(AdvancedProperty file) { this.file = file; } public abstract boolean hasRights(IWContext iwc); @Override public String getBundleIdentifier() { return CoreConstants.CORE_IW_BUNDLE_IDENTIFIER; } public String getFileHolderIdentifier() { return fileHolderIdentifier; } public void setFileHolderIdentifier(String fileHolderIdentifier) { this.fileHolderIdentifier = fileHolderIdentifier; } public ICFile getRealFile() { return realFile; } public void setRealFile(ICFile realFile) { this.realFile = realFile; } public boolean isShowCompany(IWContext iwc) { if(showCompany == null){ showCompany = "y".equals(iwc.getParameter(SHOW_COMPANY)); } return showCompany; } public void setShowCompany(boolean showCompany) { this.showCompany = showCompany; } public boolean isShowLastLoginDate(IWContext iwc) { if(showLastLoginDate == null){ showLastLoginDate = "y".equals(iwc.getParameter(SHOW_LAST_LOGIN_DATE)); } return showLastLoginDate; } public void setShowLastLoginDate(Boolean showLastLoginDate) { this.showLastLoginDate = showLastLoginDate; } }