/** * $URL: https://source.sakaiproject.org/svn/sitestats/trunk/sitestats-impl/src/java/org/sakaiproject/sitestats/impl/event/EventRegistryServiceImpl.java $ * $Id: EventRegistryServiceImpl.java 116373 2012-11-14 18:40:48Z matthew.buckett@it.ox.ac.uk $ * * Copyright (c) 2006-2009 The 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.sitestats.impl.event; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Observable; import java.util.Observer; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.sakaiproject.component.api.ServerConfigurationService; import org.sakaiproject.memory.api.Cache; import org.sakaiproject.memory.api.MemoryService; import org.sakaiproject.site.api.SiteService; import org.sakaiproject.sitestats.api.StatsManager; import org.sakaiproject.sitestats.api.event.EventInfo; import org.sakaiproject.sitestats.api.event.EventRegistry; import org.sakaiproject.sitestats.api.event.EventRegistryService; import org.sakaiproject.sitestats.api.event.ToolInfo; import org.sakaiproject.sitestats.api.parser.EventFactory; import org.sakaiproject.sitestats.api.parser.ToolFactory; import org.sakaiproject.sitestats.api.report.ReportManager; import org.sakaiproject.sitestats.impl.parser.EventFactoryImpl; import org.sakaiproject.sitestats.impl.parser.ToolFactoryImpl; import org.sakaiproject.tool.api.ToolManager; import org.sakaiproject.util.ResourceLoader; public class EventRegistryServiceImpl implements EventRegistry, EventRegistryService, Observer { /** Static fields */ private static Log LOG = LogFactory.getLog(EventRegistryServiceImpl.class); private static final String CACHENAME = EventRegistryServiceImpl.class.getName(); private static final String CACHENAME_EVENTREGISTRY = "eventRegistry"; private static ResourceLoader msgs = new ResourceLoader("Messages"); /** Event Registry members */ private Set<String> toolEventIds = null; private Set<String> anonymousToolEventIds = null; private Map<String, ToolInfo> eventIdToolMap = null; private Map<String, String> toolIdIconMap = null; private boolean checkLocalEventNamesFirst = false; /** Event Registries */ private FileEventRegistry fileEventRegistry = null; private EntityBrokerEventRegistry entityBrokerEventRegistry = null; private List<String> serverEventIds = new ArrayList<String>(); /** Caching */ private Cache eventRegistryCache = null; /** Sakai services */ private StatsManager M_sm; private SiteService M_ss; private ToolManager M_tm; private MemoryService M_ms; private ServerConfigurationService M_scs; // ################################################################ // Spring methods // ################################################################ public void setStatsManager(StatsManager m_sm) { M_sm = m_sm; } public void setSiteService(SiteService siteService) { this.M_ss = siteService; } public void setToolManager(ToolManager toolManager) { this.M_tm = toolManager; } public void setMemoryService(MemoryService memoryService) { this.M_ms = memoryService; } public void setServerConfigurationService(ServerConfigurationService serverConfigurationService) { this.M_scs = serverConfigurationService; } public void setFileEventRegistry(FileEventRegistry fileEventRegistry) { this.fileEventRegistry = fileEventRegistry; } public void setEntityBrokerEventRegistry(EntityBrokerEventRegistry ebEventRegistry) { this.entityBrokerEventRegistry = ebEventRegistry; this.entityBrokerEventRegistry.addObserver(this); } public void setCheckLocalEventNamesFirst(boolean checkLocalEventNamesFirst) { this.checkLocalEventNamesFirst = checkLocalEventNamesFirst; } public void init() { String willCheckLocalEventNamesFirst = checkLocalEventNamesFirst ? "Local event names in sitestats-bundles will be checked first" : "Tool specified event names (Statisticable interface) will be checked first"; LOG.info("init(): " + willCheckLocalEventNamesFirst); // configure cache eventRegistryCache = M_ms.newCache(CACHENAME); } // ################################################################ // Event Registry // ################################################################ /* (non-Javadoc) * @see org.sakaiproject.sitestats.impl.event.EventRegistryService#getEventIds() */ public Set<String> getEventIds() { if(toolEventIds == null){ toolEventIds = new HashSet<String>(); toolEventIds.addAll(getEventIdToolMap().keySet()); // Add on the presence events if we're interested. toolEventIds.add(StatsManager.SITEVISIT_EVENTID); if(M_sm.isEnableSitePresences()) { toolEventIds.add(StatsManager.SITEVISITEND_EVENTID); } toolEventIds = Collections.unmodifiableSet(toolEventIds); } return toolEventIds; } /* (non-Javadoc) * @see org.sakaiproject.sitestats.impl.event.EventRegistryService#getAnonymousEventIds() */ public Set<String> getAnonymousEventIds() { if(anonymousToolEventIds == null){ anonymousToolEventIds = new HashSet<String>(); for(ToolInfo ti : getEventRegistry()){ for(EventInfo ei : ti.getEvents()){ if(ei.isAnonymous()){ anonymousToolEventIds.add(ei.getEventId()); } } } anonymousToolEventIds = Collections.unmodifiableSet(anonymousToolEventIds); } return anonymousToolEventIds; } /* (non-Javadoc) * @see org.sakaiproject.sitestats.impl.event.EventRegistryService#getEventRegistry() */ public List<ToolInfo> getEventRegistry() { return getEventRegistry(null, false); } /* (non-Javadoc) * @see org.sakaiproject.sitestats.impl.event.EventRegistryService#getEventRegistry(java.lang.String, boolean) */ public List<ToolInfo> getEventRegistry(String siteId, boolean onlyAvailableInSite) { if(siteId == null) { // return the full event registry return getMergedEventRegistry(); }else if(onlyAvailableInSite) { // return the event registry with only tools available in site return EventUtil.getIntersectionWithAvailableToolsInSite(M_ss, getMergedEventRegistry(), siteId); }else{ // return the event registry with only tools available in (whole) Sakai return EventUtil.getIntersectionWithAvailableToolsInSakaiInstallation(M_tm, getMergedEventRegistry()); } } /* (non-Javadoc) * @see org.sakaiproject.sitestats.api.event.EventRegistry#isEventRegistryExpired() */ public boolean isEventRegistryExpired() { // In this specific class, this has no effect return true; } /* (non-Javadoc) * @see org.sakaiproject.sitestats.impl.event.EventRegistryService#getEventName(java.lang.String) */ public String getEventName(String eventId) { if(eventId == null || eventId.trim().equals("")) return ""; String eventName = null; EventRegistry firstEr = null; EventRegistry secondEr = null; if(checkLocalEventNamesFirst) { firstEr = fileEventRegistry; secondEr = entityBrokerEventRegistry; }else{ firstEr = entityBrokerEventRegistry; secondEr = fileEventRegistry; } eventName = firstEr.getEventName(eventId); if(eventName == null) { eventName = secondEr.getEventName(eventId); } if(eventName == null) { LOG.warn("Missing resource bundle for event id: "+eventId); eventName = eventId; } return eventName; } /* (non-Javadoc) * @see org.sakaiproject.sitestats.impl.event.EventRegistryService#getToolName(java.lang.String) */ public String getToolName(String toolId) { if(ReportManager.WHAT_EVENTS_ALLTOOLS.equals(toolId)) { return msgs.getString("all"); }else{ String toolName; try{ toolName = M_tm.getTool(toolId).getTitle(); }catch(Exception e){ try{ LOG.debug("No sakai tool found for toolId: " + toolId + " (tool undeployed?). Using bundle (if supplied) in sitestats/sitestats-impl/impl/src/bundle/org/sakaiproject/sitestats/impl/bundle/ for tool name."); toolName = msgs.getString(toolId, toolId); }catch(Exception e1){ LOG.debug("No translation found for toolId: " + toolId + " - using toolId as tool name. Please specify it in sitestats/sitestats-impl/impl/src/bundle/org/sakaiproject/sitestats/impl/bundle/"); toolName = toolId; } } return toolName; } } /* (non-Javadoc) * @see org.sakaiproject.sitestats.api.event.EventRegistryService#getToolIcon(java.lang.String) */ public String getToolIcon(String toolId) { if(toolIdIconMap == null) { toolIdIconMap = new HashMap<String, String>(); // Defaults: standard tools toolIdIconMap.put("osp.evaluation", StatsManager.SILK_ICONS_DIR + "thumb_up.png"); toolIdIconMap.put("osp.glossary", StatsManager.SILK_ICONS_DIR + "text_list_bullets.png"); toolIdIconMap.put("osp.matrix", StatsManager.SILK_ICONS_DIR + "table.png"); toolIdIconMap.put("osp.presentation", StatsManager.SILK_ICONS_DIR + "briefcase.png"); toolIdIconMap.put("osp.presLayout", StatsManager.SILK_ICONS_DIR + "layout_content.png"); toolIdIconMap.put("osp.presTemplate", StatsManager.SILK_ICONS_DIR + "application_view_tile.png"); toolIdIconMap.put("osp.style", StatsManager.SILK_ICONS_DIR + "style.png"); toolIdIconMap.put("osp.wizard", StatsManager.SILK_ICONS_DIR + "wand.png"); toolIdIconMap.put("sakai.announcements", StatsManager.SILK_ICONS_DIR + "flag_blue.png"); toolIdIconMap.put("sakai.chat", StatsManager.SILK_ICONS_DIR + "user_comment.png"); toolIdIconMap.put("sakai.datapoint", StatsManager.SILK_ICONS_DIR + "chart_line.png"); toolIdIconMap.put("sakai.discussion", StatsManager.SILK_ICONS_DIR + "comments.png"); toolIdIconMap.put("sakai.dropbox", StatsManager.SILK_ICONS_DIR + "folder_page.png"); toolIdIconMap.put("sakai.gmt", StatsManager.SILK_ICONS_DIR + "award_star_gold_3.png"); toolIdIconMap.put("sakai.help", StatsManager.SILK_ICONS_DIR + "help.png"); toolIdIconMap.put("sakai.iframe", StatsManager.SILK_ICONS_DIR + "page_world.png"); toolIdIconMap.put("sakai.iframe.site", StatsManager.SILK_ICONS_DIR + "house.png"); toolIdIconMap.put("sakai.mailbox", StatsManager.SILK_ICONS_DIR + "email.png"); toolIdIconMap.put("sakai.messages", StatsManager.SILK_ICONS_DIR + "comment.png"); toolIdIconMap.put("sakai.metaobj", StatsManager.SILK_ICONS_DIR + "application_form.png"); toolIdIconMap.put("sakai.membership", StatsManager.SILK_ICONS_DIR + "group.png"); toolIdIconMap.put("sakai.news", StatsManager.SILK_ICONS_DIR + "rss.png"); toolIdIconMap.put("sakai.podcasts", StatsManager.SILK_ICONS_DIR + "ipod_cast.png"); toolIdIconMap.put("sakai.postem", StatsManager.SILK_ICONS_DIR + "database_table.png"); toolIdIconMap.put("sakai.preferences", StatsManager.SILK_ICONS_DIR + "cog.png"); toolIdIconMap.put("sakai.rutgers.linktool", StatsManager.SILK_ICONS_DIR + "application.png"); toolIdIconMap.put("sakai.sections", StatsManager.SILK_ICONS_DIR + "group_gear.png"); toolIdIconMap.put("sakai.singleuser", StatsManager.SILK_ICONS_DIR + "user.png"); toolIdIconMap.put("sakai.syllabus", StatsManager.SILK_ICONS_DIR + "script.png"); toolIdIconMap.put("blogger", StatsManager.SILK_ICONS_DIR + "book_edit.png"); toolIdIconMap.put("sakai.assignment.grades", StatsManager.SILK_ICONS_DIR + "page_edit.png"); toolIdIconMap.put("sakai.forums", StatsManager.SILK_ICONS_DIR + "comments.png"); toolIdIconMap.put("sakai.gradebook.tool", StatsManager.SILK_ICONS_DIR + "report.png"); toolIdIconMap.put("sakai.mailtool", StatsManager.SILK_ICONS_DIR + "email_go.png"); toolIdIconMap.put("sakai.poll", StatsManager.SILK_ICONS_DIR + "chart_bar.png"); toolIdIconMap.put("sakai.sitestats", StatsManager.SILK_ICONS_DIR + "chart_bar.png"); toolIdIconMap.put("sakai.presentation", StatsManager.SILK_ICONS_DIR + "monitor.png"); toolIdIconMap.put("sakai.profile", StatsManager.SILK_ICONS_DIR + "vcard_edit.png"); toolIdIconMap.put("sakai.reports", StatsManager.SILK_ICONS_DIR + "report_magnify.png"); toolIdIconMap.put("sakai.resetpass", StatsManager.SILK_ICONS_DIR + "key.png"); toolIdIconMap.put("sakai.resources", StatsManager.SILK_ICONS_DIR + "folder.png"); toolIdIconMap.put("sakai.rwiki", StatsManager.SILK_ICONS_DIR + "page_white_edit.png"); toolIdIconMap.put("sakai.samigo", StatsManager.SILK_ICONS_DIR + "pencil.png"); toolIdIconMap.put("sakai.schedule", StatsManager.SILK_ICONS_DIR + "calendar.png"); toolIdIconMap.put("sakai.search", StatsManager.SILK_ICONS_DIR + "find.png"); toolIdIconMap.put("sakai.siteinfo", StatsManager.SILK_ICONS_DIR + "application_lightning.png"); toolIdIconMap.put("sakai.sitesetup", StatsManager.SILK_ICONS_DIR + "application_lightning.png"); toolIdIconMap.put("sakai.site.roster", StatsManager.SILK_ICONS_DIR + "vcard.png"); toolIdIconMap.put("sakai.synoptic.messagecenter", StatsManager.SILK_ICONS_DIR + "comment.png"); toolIdIconMap.put("sakai.conferencing", StatsManager.SILK_ICONS_DIR + "webcam.png"); toolIdIconMap.put("sakai.feeds", StatsManager.SILK_ICONS_DIR + "rss.png"); toolIdIconMap.put("sakai.blog", StatsManager.SILK_ICONS_DIR + "book_edit.png"); toolIdIconMap.put("sakai.blogwow", StatsManager.SILK_ICONS_DIR + "book_edit.png"); toolIdIconMap.put("sakai.yaft", StatsManager.SILK_ICONS_DIR + "book_edit.png"); toolIdIconMap.put("sakai.mneme", StatsManager.SITESTATS_WEBAPP + "/images/extra-tool-icons/mneme.png"); toolIdIconMap.put("sakai.jforum.tool", StatsManager.SITESTATS_WEBAPP + "/images/extra-tool-icons/jforum.png"); toolIdIconMap.put("sakai.melete", StatsManager.SITESTATS_WEBAPP + "/images/extra-tool-icons/modules.png"); toolIdIconMap.put("sakai.tasklist", StatsManager.SILK_ICONS_DIR + "note.png"); toolIdIconMap.put("sakai.todolist", StatsManager.SILK_ICONS_DIR + "note.png"); toolIdIconMap.put("sakai.markup", StatsManager.SILK_ICONS_DIR + "layout_edit.png"); toolIdIconMap.put("sakai.bbb", StatsManager.SILK_ICONS_DIR + "webcam.png"); toolIdIconMap.put("sakai.basiclti", StatsManager.SILK_ICONS_DIR + "application_go.png"); // Defaults: admin tools toolIdIconMap.put("sakai.users", StatsManager.SILK_ICONS_DIR + "folder_user.png"); toolIdIconMap.put("sakai.aliases", StatsManager.SILK_ICONS_DIR + "tag_blue.png"); toolIdIconMap.put("sakai.sites", StatsManager.SILK_ICONS_DIR + "application_cascade.png"); toolIdIconMap.put("sakai.realms", StatsManager.SILK_ICONS_DIR + "sitemap_color.png"); toolIdIconMap.put("sakai.online", StatsManager.SILK_ICONS_DIR + "report_user.png"); toolIdIconMap.put("sakai.memory", StatsManager.SILK_ICONS_DIR + "server_chart.png"); toolIdIconMap.put("sakai.archive", StatsManager.SILK_ICONS_DIR + "page_white_compressed.png"); toolIdIconMap.put("sakai.scheduler", StatsManager.SILK_ICONS_DIR + "clock.png"); toolIdIconMap.put("sakai.su", StatsManager.SILK_ICONS_DIR + "user_go.png"); toolIdIconMap.put("sakai.usermembership", StatsManager.SILK_ICONS_DIR + "drive_user.png"); toolIdIconMap.put("sakai.motd", StatsManager.SILK_ICONS_DIR + "house.png"); toolIdIconMap.put("sakai-sitebrowser", StatsManager.SILK_ICONS_DIR + "world.png"); toolIdIconMap.put("sakai-createuser", StatsManager.SILK_ICONS_DIR + "user_add.png"); // User-specified: process additions and overwrites from sakai.properties (STAT-232) String[] tools = M_scs.getStrings("sitestats.toolicons.tools"); String[] icons = M_scs.getStrings("sitestats.toolicons.icons"); if(tools != null && icons != null) { int count = tools.length; if(tools.length != icons.length) { LOG.warn("Number of values for property 'sitestats.toolicons.tools' doesn't match number of values in 'sitestats.toolicons.icons'! Using smaller number."); if(icons.length < count) { count = icons.length; } } for(int i=0; i<count; i++) { toolIdIconMap.put(tools[i], icons[i]); } }else if((tools != null && icons == null) || (tools == null && icons != null)) { LOG.warn("Both 'sitestats.toolicons.tools' and 'sitestats.toolicons.icons' properties are required!"); } } return toolIdIconMap.get(toolId); } /* (non-Javadoc) * @see org.sakaiproject.sitestats.impl.event.EventRegistryService#getEventIdToolMap() */ public Map<String, ToolInfo> getEventIdToolMap() { if(eventIdToolMap == null){ eventIdToolMap = new HashMap<String, ToolInfo>(); Iterator<ToolInfo> i = getMergedEventRegistry().iterator(); while (i.hasNext()){ ToolInfo t = i.next(); Iterator<EventInfo> iE = t.getEvents().iterator(); while(iE.hasNext()){ EventInfo e = iE.next(); eventIdToolMap.put(e.getEventId(), t); } } } return eventIdToolMap; } /* (non-Javadoc) * @see org.sakaiproject.sitestats.api.event.EventRegistryService#getToolFactory() */ public ToolFactory getToolFactory() { return new ToolFactoryImpl(); } /* (non-Javadoc) * @see org.sakaiproject.sitestats.api.event.EventRegistryService#getEventFactory() */ public EventFactory getEventFactory() { return new EventFactoryImpl(); } // ################################################################ // Utility Methods // ################################################################ /** Get the merged Event Registry. */ @SuppressWarnings("unchecked") private List<ToolInfo> getMergedEventRegistry() { if(eventRegistryCache.containsKey(CACHENAME_EVENTREGISTRY)) { return (List<ToolInfo>) eventRegistryCache.get(CACHENAME_EVENTREGISTRY); }else{ // First: use file Event Registry List<ToolInfo> eventRegistry = fileEventRegistry.getEventRegistry(); // Second: add EntityBroker Event Registry, // replacing events for tools found on this Registry // (but keeping the anonymous flag for events in both Registries) eventRegistry = EventUtil.addToEventRegistry(entityBrokerEventRegistry.getEventRegistry(), true, eventRegistry); // Cache Event Registry eventRegistryCache.put(CACHENAME_EVENTREGISTRY, eventRegistry); LOG.debug("Cached EventRegistry."); return eventRegistry; } } /** Process event registry expired notifications */ public void update(Observable obs, Object obj) { if(NOTIF_EVENT_REGISTRY_EXPIRED.equals(obj)) { eventRegistryCache.remove(CACHENAME_EVENTREGISTRY); eventIdToolMap = null; toolEventIds = null; anonymousToolEventIds = null; LOG.debug("EventRegistry expired. Reloading..."); } } public List<String> getServerEventIds() { return serverEventIds; } public void setServerEventIds(List<String> eventIds) { this.serverEventIds=eventIds; } }