001/* 002 * Copyright 2017 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.workspaces.project.notification; 017 018import java.util.HashMap; 019import java.util.LinkedList; 020import java.util.Map; 021 022import org.apache.avalon.framework.activity.Initializable; 023import org.apache.avalon.framework.component.Component; 024import org.apache.avalon.framework.service.ServiceException; 025import org.apache.avalon.framework.service.ServiceManager; 026import org.apache.avalon.framework.service.Serviceable; 027 028import org.ametys.core.user.CurrentUserProvider; 029 030/** 031 * Notification helper for the Webdav actions 032 */ 033public class ResourceNotifierHelper implements Serviceable, Component, Initializable 034{ 035 /** Avalon role. */ 036 public static final String ROLE = ResourceNotifierHelper.class.getName(); 037 038 /** Time of expiration of a log (5 minutes) */ 039 private static final long __HISTORY_EXPIRATION_TIME = 5 * 60 * 1000; 040 /** Time duration between 2 cleansing of logs queue (10 seconds) */ 041 private static final long __TIME_DURATION_BEFORE_NEXT_CLEAN = 10 * 1000; 042 043 /** The current user provider */ 044 protected CurrentUserProvider _currentUserProvider; 045 046 private LinkedList<Map<String, Object>> _sentHistory; 047 048 private long _lastCleanTime; 049 050 public void service(ServiceManager manager) throws ServiceException 051 { 052 _currentUserProvider = (CurrentUserProvider) manager.lookup(CurrentUserProvider.ROLE); 053 } 054 055 public void initialize() throws Exception 056 { 057 _sentHistory = new LinkedList<>(); 058 } 059 060 /** 061 * Notify the observation manager when a resource is updated 062 * @param resourceId The resource updated 063 * @return True if the resource was recently modified 064 */ 065 public boolean resourceRecentlyModified(String resourceId) 066 { 067 if (resourceId == null) 068 { 069 return false; 070 } 071 072 long now = System.currentTimeMillis(); 073 synchronized (_sentHistory) 074 { 075 _cleanupHistory(); 076 077 for (Map<String, Object> map : _sentHistory) 078 { 079 if (map.get("resourceId").equals(resourceId)) 080 { 081 return true; 082 } 083 } 084 085 Map<String, Object> history = new HashMap<>(); 086 history.put("time", now); 087 history.put("resourceId", resourceId); 088 _sentHistory.addLast(history); 089 } 090 091 return false; 092 } 093 094 private void _cleanupHistory() 095 { 096 if (_lastCleanTime != 0 && _lastCleanTime + __TIME_DURATION_BEFORE_NEXT_CLEAN > System.currentTimeMillis()) 097 { 098 // The time between 2 cleansing has not yet expired, do nothing 099 return; 100 } 101 102 long from = System.currentTimeMillis() - __HISTORY_EXPIRATION_TIME; 103 // Remove history before 'from' 104 Map<String, Object> oldHistory = _sentHistory.peek(); 105 while (oldHistory != null && (long) oldHistory.get("time") < from) 106 { 107 _sentHistory.remove(); 108 oldHistory = _sentHistory.peek(); 109 } 110 111 _lastCleanTime = System.currentTimeMillis(); 112 } 113 114 115}