parent
370089f3e1
commit
cc0ac2e4d2
@ -1,161 +0,0 @@ |
|||||||
/* |
|
||||||
This file is part of Libresonic. |
|
||||||
|
|
||||||
Libresonic is free software: you can redistribute it and/or modify |
|
||||||
it under the terms of the GNU General Public License as published by |
|
||||||
the Free Software Foundation, either version 3 of the License, or |
|
||||||
(at your option) any later version. |
|
||||||
|
|
||||||
Libresonic is distributed in the hope that it will be useful, |
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
GNU General Public License for more details. |
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License |
|
||||||
along with Libresonic. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Copyright 2016 (C) Libresonic Authors |
|
||||||
Based upon Subsonic, Copyright 2009 (C) Sindre Mehus |
|
||||||
*/ |
|
||||||
package org.libresonic.player.ajax; |
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils; |
|
||||||
import org.directwebremoting.WebContext; |
|
||||||
import org.directwebremoting.WebContextFactory; |
|
||||||
import org.libresonic.player.Logger; |
|
||||||
import org.libresonic.player.service.SecurityService; |
|
||||||
import org.libresonic.player.util.BoundedList; |
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest; |
|
||||||
|
|
||||||
import java.io.Serializable; |
|
||||||
import java.util.*; |
|
||||||
import java.util.concurrent.Executors; |
|
||||||
import java.util.concurrent.ScheduledExecutorService; |
|
||||||
import java.util.concurrent.TimeUnit; |
|
||||||
|
|
||||||
/** |
|
||||||
* Provides AJAX-enabled services for the chatting. |
|
||||||
* This class is used by the DWR framework (http://getahead.ltd.uk/dwr/).
|
|
||||||
* |
|
||||||
* @author Sindre Mehus |
|
||||||
*/ |
|
||||||
public class ChatService { |
|
||||||
|
|
||||||
private static final Logger LOG = Logger.getLogger(ChatService.class); |
|
||||||
private static final String CACHE_KEY = "1"; |
|
||||||
private static final int MAX_MESSAGES = 10; |
|
||||||
private static final long TTL_MILLIS = 3L * 24L * 60L * 60L * 1000L; // 3 days.
|
|
||||||
|
|
||||||
private final LinkedList<Message> messages = new BoundedList<Message>(MAX_MESSAGES); |
|
||||||
private SecurityService securityService; |
|
||||||
|
|
||||||
private long revision = System.identityHashCode(this); |
|
||||||
|
|
||||||
/** |
|
||||||
* Invoked by Spring. |
|
||||||
*/ |
|
||||||
public void init() { |
|
||||||
// Delete old messages every hour.
|
|
||||||
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); |
|
||||||
Runnable runnable = new Runnable() { |
|
||||||
public void run() { |
|
||||||
removeOldMessages(); |
|
||||||
} |
|
||||||
}; |
|
||||||
executor.scheduleWithFixedDelay(runnable, 0L, 3600L, TimeUnit.SECONDS); |
|
||||||
} |
|
||||||
|
|
||||||
private synchronized void removeOldMessages() { |
|
||||||
long now = System.currentTimeMillis(); |
|
||||||
for (Iterator<Message> iterator = messages.iterator(); iterator.hasNext();) { |
|
||||||
Message message = iterator.next(); |
|
||||||
if (now - message.getDate().getTime() > TTL_MILLIS) { |
|
||||||
iterator.remove(); |
|
||||||
revision++; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public synchronized void addMessage(String message) { |
|
||||||
WebContext webContext = WebContextFactory.get(); |
|
||||||
doAddMessage(message, webContext.getHttpServletRequest()); |
|
||||||
} |
|
||||||
|
|
||||||
public synchronized void doAddMessage(String message, HttpServletRequest request) { |
|
||||||
|
|
||||||
String user = securityService.getCurrentUsername(request); |
|
||||||
message = StringUtils.trimToNull(message); |
|
||||||
if (message != null && user != null) { |
|
||||||
messages.addFirst(new Message(message, user, new Date())); |
|
||||||
revision++; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public synchronized void clearMessages() { |
|
||||||
messages.clear(); |
|
||||||
revision++; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns all messages, but only if the given revision is different from the |
|
||||||
* current revision. |
|
||||||
*/ |
|
||||||
public synchronized Messages getMessages(long revision) { |
|
||||||
if (this.revision != revision) { |
|
||||||
return new Messages(new ArrayList<Message>(messages), this.revision); |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
public void setSecurityService(SecurityService securityService) { |
|
||||||
this.securityService = securityService; |
|
||||||
} |
|
||||||
|
|
||||||
public static class Messages implements Serializable { |
|
||||||
|
|
||||||
private static final long serialVersionUID = -752602719879818165L; |
|
||||||
private final List<Message> messages; |
|
||||||
private final long revision; |
|
||||||
|
|
||||||
public Messages(List<Message> messages, long revision) { |
|
||||||
this.messages = messages; |
|
||||||
this.revision = revision; |
|
||||||
} |
|
||||||
|
|
||||||
public List<Message> getMessages() { |
|
||||||
return messages; |
|
||||||
} |
|
||||||
|
|
||||||
public long getRevision() { |
|
||||||
return revision; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static class Message implements Serializable { |
|
||||||
|
|
||||||
private static final long serialVersionUID = -1907101191518133712L; |
|
||||||
private final String content; |
|
||||||
private final String username; |
|
||||||
private final Date date; |
|
||||||
|
|
||||||
public Message(String content, String username, Date date) { |
|
||||||
this.content = content; |
|
||||||
this.username = username; |
|
||||||
this.date = date; |
|
||||||
} |
|
||||||
|
|
||||||
public String getContent() { |
|
||||||
return content; |
|
||||||
} |
|
||||||
|
|
||||||
public String getUsername() { |
|
||||||
return username; |
|
||||||
} |
|
||||||
|
|
||||||
public Date getDate() { |
|
||||||
return date; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,6 @@ |
|||||||
|
<databaseChangeLog |
||||||
|
xmlns="http://www.liquibase.org/xml/ns/dbchangelog" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd"> |
||||||
|
<include file="remove-show-chat.xml" relativeToChangelogFile="true"/> |
||||||
|
</databaseChangeLog> |
@ -0,0 +1,12 @@ |
|||||||
|
<databaseChangeLog |
||||||
|
xmlns="http://www.liquibase.org/xml/ns/dbchangelog" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd"> |
||||||
|
<changeSet id="remove-show-chat_001" author="muff1nman"> |
||||||
|
<preConditions onFail="MARK_RAN"> |
||||||
|
<columnExists tableName="user_settings" columnName="show_chat" /> |
||||||
|
</preConditions> |
||||||
|
<dropColumn tableName="user_settings" columnName="show_chat" /> |
||||||
|
<rollback changeSetId="schema38_003" changeSetPath="classpath:liquibase/legacy/schema38.xml" changeSetAuthor="muff1nman"/> |
||||||
|
</changeSet> |
||||||
|
</databaseChangeLog> |
Loading…
Reference in new issue