r1807 - in trunk/src: main/java/cc/kune/common/public main/java/cc/kune/core/public main/java/cc/kune/core/server main/java/cc/kune/core/server/content main/java/cc/kune/core/server/manager/impl main/java/cc/kune/core/server/persist main/java/cc/kune/core/server/rpc main/java/cc/kune/core/server/scheduler main/java/cc/kune/core/server/state main/java/cc/kune/domain main/java/cc/kune/events/client/actions main/java/cc/kune/events/client/viewer main/java/cc/kune/events/server main/java/cc/kune/
Author: vjrj_ Date: 2012-03-30 13:26:03 +0200 (Fri, 30 Mar 2012) New Revision: 1807 Added: trunk/src/main/java/cc/kune/core/server/manager/impl/SocialNetworkCache.java trunk/src/main/java/cc/kune/core/server/manager/impl/SocialNetworkCacheClearDailyJob.java trunk/src/main/java/cc/kune/core/server/persist/CachedCollection.java trunk/src/main/java/cc/kune/core/server/persist/CachedCollectionTest.java trunk/src/main/java/cc/kune/core/server/persist/ClearCacheDailyJob.java trunk/src/main/java/cc/kune/events/client/actions/NewEventBtn.java trunk/src/main/java/cc/kune/events/server/utils/EventsCache.java trunk/src/main/java/cc/kune/events/server/utils/EventsCacheClearDailyJob.java trunk/src/test/java/cc/kune/core/server/manager/impl/SocialNetworkCacheTest.java trunk/src/test/java/cc/kune/events/server/utils/EventsCacheTest.java Removed: trunk/src/main/java/cc/kune/events/client/actions/NewMeetingBtn.java Modified: trunk/src/main/java/cc/kune/common/public/kune-common.css trunk/src/main/java/cc/kune/core/public/ws.css trunk/src/main/java/cc/kune/core/server/LoggerMethodInterceptor.java trunk/src/main/java/cc/kune/core/server/content/ContentManagerDefault.java trunk/src/main/java/cc/kune/core/server/manager/impl/SocialNetworkManagerDefault.java trunk/src/main/java/cc/kune/core/server/rpc/ContentRPC.java trunk/src/main/java/cc/kune/core/server/rpc/RPC.java trunk/src/main/java/cc/kune/core/server/scheduler/CronServerTasksManager.java trunk/src/main/java/cc/kune/core/server/state/StateServiceDefault.java trunk/src/main/java/cc/kune/domain/Container.java trunk/src/main/java/cc/kune/domain/Content.java trunk/src/main/java/cc/kune/events/client/actions/EventsClientActions.java trunk/src/main/java/cc/kune/events/client/viewer/CalendarViewerPanel.java trunk/src/main/java/cc/kune/events/server/EventsServerTool.java trunk/src/main/java/cc/kune/events/server/EventsServlet.java trunk/src/main/java/cc/kune/events/server/utils/EventsServerConversionUtil.java trunk/src/main/java/cc/kune/wave/client/WaveStatusIndicator.java Log: CLOSED - # 228: Add more caches to server side objects http://kune.ourproject.org/issues/ticket/228 Modified: trunk/src/main/java/cc/kune/common/public/kune-common.css =================================================================== --- trunk/src/main/java/cc/kune/common/public/kune-common.css 2012-03-29 01:36:02 UTC (rev 1806) +++ trunk/src/main/java/cc/kune/common/public/kune-common.css 2012-03-30 11:26:03 UTC (rev 1807) @@ -536,7 +536,7 @@ /* tooltips, adaptation of http://jonrohan.me/guide/css/creating-triangles-in-css/ */ .k-tooltip { background-color: #FEFFF1; - border: 2px solid #666666; + border: 1px solid #666666; line-height: 1.3em; padding: 5px; } Modified: trunk/src/main/java/cc/kune/core/public/ws.css =================================================================== --- trunk/src/main/java/cc/kune/core/public/ws.css 2012-03-29 01:36:02 UTC (rev 1806) +++ trunk/src/main/java/cc/kune/core/public/ws.css 2012-03-30 11:26:03 UTC (rev 1807) @@ -1,18 +1,22 @@ -GCHARSET "UTF-8 "; body { +GCHARSET "UTF-8 "; body + { background-color: transparent; color: black; - font-family: "Ubuntu Beta",UbuntuBeta,Ubuntu,"Bitstream Vera Sans","DejaVu Sans",Tahoma,sans-serif; + font-family: "Ubuntu Beta", UbuntuBeta, Ubuntu, "Bitstream Vera Sans", + "DejaVu Sans", Tahoma, sans-serif; font-size: small; margin: 5px; overflow: hidden; } * { - font-family: "Ubuntu Beta",UbuntuBeta,Ubuntu,"Bitstream Vera Sans","DejaVu Sans",Tahoma,sans-serif; + font-family: "Ubuntu Beta", UbuntuBeta, Ubuntu, "Bitstream Vera Sans", + "DejaVu Sans", Tahoma, sans-serif; } body.fontface { - font-family: "Ubuntu Beta",UbuntuBeta,Ubuntu,"Bitstream Vera Sans","DejaVu Sans",Tahoma,sans-serif; + font-family: "Ubuntu Beta", UbuntuBeta, Ubuntu, "Bitstream Vera Sans", + "DejaVu Sans", Tahoma, sans-serif; } div,span { @@ -58,7 +62,7 @@ } .gwt-Tree { - + } .gwt-Tree .gwt-TreeItem { @@ -85,7 +89,7 @@ } .gwt-StackPanel .gwt-StackPanelItem-selected { - + } .gwt-PushButton-up { @@ -267,7 +271,7 @@ } .gwt-SplitLayoutPanel { - + } .gwt-SplitLayoutPanel .gwt-SplitLayoutPanel-HDragger,.gwt-SplitLayoutPanel-HDragger @@ -351,7 +355,7 @@ } .x-btn button,button { /* font: 18px/27px 'Ubuntu', arial; */ - + } .x-panel-mc { @@ -376,11 +380,11 @@ } div div.siteBar table.k-sitebar img.k-iconlabel-left { - margin: 0px !important; + margin: 0px !important; } div div.siteBar table.k-sitebar div.k-iconlabel-left { - margin: 0px !important; + margin: 0px !important; } .k-sitebar-wave-status { @@ -394,7 +398,7 @@ } .k-sitebar-wave-status { - + } .k-sitebar-wave-status-online { @@ -415,7 +419,7 @@ } .k-sitebar { /* margin-top: -30px; */ - + } .k-link { @@ -702,7 +706,7 @@ -moz-opacity: 0.68 !important; -khtml-opacity: 0.68 !important; opacity: 0.68 !important;*/ - + } .k-publicspace-panel { @@ -792,7 +796,8 @@ .x-fieldset-header-text,.x-form-group-label,.x-form-cb-label { font-size: 14px; - font-family: "Ubuntu Beta",UbuntuBeta,Ubuntu,"Bitstream Vera Sans","DejaVu Sans",Tahoma,sans-serif; + font-family: "Ubuntu Beta", UbuntuBeta, Ubuntu, "Bitstream Vera Sans", + "DejaVu Sans", Tahoma, sans-serif; } .k-form-intro { @@ -851,7 +856,7 @@ } .k-sn-adminslabel { - + } .k-sn-mainpanel .k-basic-thumb { @@ -871,6 +876,7 @@ cursor: pointer; margin: 0; text-decoration: none; + background: url("images/hborder.png") repeat-x 0px -27px; background-color: #F2F2F2; color: #A05A2C; -webkit-border-radius: 5px; @@ -883,10 +889,10 @@ width: 50px; min-width: 40px; height: 26px; + text-shadow: 1px 1px 1px #FFFFFF; } -button.k-button -{ +button.k-button { padding: 0 2px; } @@ -894,7 +900,6 @@ { border: 1px orange solid; outline: 0 none; - /* background: #f0f0f0; */ } .k-sn-mainpanel .x-btn button:hover span,.k-sn-mainpanel button:hover span,button.k-button:hover span @@ -961,8 +966,8 @@ color: gray !important; border-color: #CCCCCC !important; background: inherits !important; - kfilter: alpha(opacity = - 50) !important; + kfilter: alpha(opacity = + 50) !important; -moz-opacity: 0.50 !important; -khtml-opacity: 0.50 !important; opacity: 0.50 !important; @@ -976,12 +981,13 @@ } /* end buttons */ + .k-sn-collabslabel { - + } .k-sn-pendingslabel { - + } .k-sn-orphan-label { @@ -999,15 +1005,15 @@ } .k-sn-2nd-spanel { - + } .k-sn-3rd-panel { - + } .k-sn-adminsscroll,.k-sn-collabsscroll,.k-sn-pendingsscroll { - + } .k-sn-adminsflow,.k-sn-collabsflow,.k-sn-pendingsflow { @@ -1015,15 +1021,15 @@ } .k-sn-adminsscroll { - + } .k-sn-collabsscroll { - + } .k-sn-pendingsscroll { - + } .k-userconfirm-label { @@ -1032,7 +1038,7 @@ } .k-sn-deck { - + } .k-sn-bottomPanel { @@ -1183,7 +1189,7 @@ } .k-tool-panel { - + } .k-tool-item { @@ -1193,19 +1199,19 @@ } .k-tool-item-focus { - + } .k-tool-item-nofocus { - + } .k-tool-item-selected { - + } .k-tool-item-notselected { - + } .k-def-docbtn span { @@ -1254,8 +1260,8 @@ -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; border-bottom-left-radius: 5px; - kfilter: alpha(opacity = - 90); + kfilter: alpha(opacity = + 90); -moz-opacity: 0.90; -khtml-opacity: 0.90; opacity: 0.90; @@ -1310,7 +1316,7 @@ /* Decorated tabbar */ .gwt-DecoratedTabBar { - + } .gwt-DecoratedTabBar .gwt-TabBarFirst { @@ -1318,7 +1324,7 @@ } .gwt-DecoratedTabBar .gwt-TabBarRest { - + } .gwt-DecoratedTabBar .gwt-TabBarItem { @@ -1586,6 +1592,4 @@ right: 0 !important; top: 0 !important; width: auto !important; -} - - +} \ No newline at end of file Modified: trunk/src/main/java/cc/kune/core/server/LoggerMethodInterceptor.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/LoggerMethodInterceptor.java 2012-03-29 01:36:02 UTC (rev 1806) +++ trunk/src/main/java/cc/kune/core/server/LoggerMethodInterceptor.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -19,6 +19,8 @@ */ package cc.kune.core.server; +import java.util.Date; + import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.logging.Log; @@ -26,99 +28,103 @@ public class LoggerMethodInterceptor implements MethodInterceptor { - private static final Log LOG = LogFactory.getLog(LoggerMethodInterceptor.class); - private final boolean simplifyNames; + private static final Log LOG = LogFactory.getLog(LoggerMethodInterceptor.class); + private final boolean simplifyNames; - public LoggerMethodInterceptor() { - this(true); - } + public LoggerMethodInterceptor() { + this(true); + } - public LoggerMethodInterceptor(final boolean simplifyNames) { - this.simplifyNames = simplifyNames; - } + public LoggerMethodInterceptor(final boolean simplifyNames) { + this.simplifyNames = simplifyNames; + } - private void addMethodName(final MethodInvocation invocation, final StringBuffer buffer) { - buffer.append("."); - buffer.append(invocation.getMethod().getName()); - } + private void addMethodName(final MethodInvocation invocation, final StringBuffer buffer) { + buffer.append("."); + buffer.append(invocation.getMethod().getName()); + } - private void addMethodParameters(final MethodInvocation invocation, final StringBuffer buffer) { - buffer.append("("); - final Object[] arguments = invocation.getArguments(); - for (final Object arg : arguments) { - buffer.append(getValue(arg)).append(", "); - } - buffer.append(")"); + private void addMethodParameters(final MethodInvocation invocation, final StringBuffer buffer) { + buffer.append("("); + final Object[] arguments = invocation.getArguments(); + for (final Object arg : arguments) { + buffer.append(getValue(arg)).append(", "); } + buffer.append(")"); + } - private void addTargetClassName(final MethodInvocation invocation, final StringBuffer buffer) { - buffer.append(getSimpleName(invocation.getThis().getClass())); - } + private void addTargetClassName(final MethodInvocation invocation, final StringBuffer buffer) { + buffer.append(getSimpleName(invocation.getThis().getClass())); + } - private StringBuffer createBuffer(final MethodInvocation invocation) { - final StringBuffer buffer = new StringBuffer(); - addTargetClassName(invocation, buffer); - return buffer; - } + private StringBuffer createBuffer(final MethodInvocation invocation) { + final StringBuffer buffer = new StringBuffer(); + addTargetClassName(invocation, buffer); + return buffer; + } - private String getSimpleName(final Class<? extends Object> type) { - String simpleName = type.getSimpleName(); - if (simplifyNames == true) { - final int index = simpleName.indexOf('$'); - if (index > 0) { - simpleName = simpleName.substring(0, index); - } - } - return simpleName; + private String getSimpleName(final Class<? extends Object> type) { + String simpleName = type.getSimpleName(); + if (simplifyNames == true) { + final int index = simpleName.indexOf('$'); + if (index > 0) { + simpleName = simpleName.substring(0, index); + } } + return simpleName; + } - private String getValue(final Object result) { - if (result == null) { - return "null"; - } else { - return result.toString(); - } + private String getValue(final Object result) { + if (result == null) { + return "null"; + } else { + return result.toString(); } + } - @Override - public Object invoke(final MethodInvocation invocation) throws Throwable { - logInvocation(invocation); - try { - final Object result = invocation.proceed(); - logResult(invocation, result); - return result; - } catch (final Exception e) { - logException(invocation, e); - throw e; - } + @Override + public Object invoke(final MethodInvocation invocation) throws Throwable { + final Date start = new Date(); + logInvocation(invocation); + try { + final Object result = invocation.proceed(); + logResult(invocation, result, (new Date()).getTime() - start.getTime()); + return result; + } catch (final Exception e) { + logException(invocation, e); + throw e; } + } - protected void log(final String output) { - LOG.debug(output); - } + protected void log(final String output) { + LOG.debug(output); + } - protected void logException(final MethodInvocation invocation, final Throwable e) { - final StringBuffer buffer = createBuffer(invocation); - addMethodName(invocation, buffer); - buffer.append(" EXCEPTION => ").append(e.getClass()).append(": ").append( - e.getCause() != null ? e.getCause() : "").append(e.getMessage() != null ? e.getMessage() : ""); - log(buffer.toString()); - } + protected void logException(final MethodInvocation invocation, final Throwable e) { + final StringBuffer buffer = createBuffer(invocation); + addMethodName(invocation, buffer); + buffer.append(" EXCEPTION => ").append(e.getClass()).append(": ").append( + e.getCause() != null ? e.getCause() : "").append(e.getMessage() != null ? e.getMessage() : ""); + log(buffer.toString()); + } - protected void logInvocation(final MethodInvocation invocation) { - final StringBuffer buffer = createBuffer(invocation); - addMethodName(invocation, buffer); - addMethodParameters(invocation, buffer); - log(buffer.toString()); - } + protected void logInvocation(final MethodInvocation invocation) { + final StringBuffer buffer = createBuffer(invocation); + addMethodName(invocation, buffer); + addMethodParameters(invocation, buffer); + log(buffer.toString()); + } - protected void logResult(final MethodInvocation invocation, final Object result) { - final StringBuffer buffer = createBuffer(invocation); - addMethodName(invocation, buffer); - if (invocation.getMethod().getReturnType() != null) { - buffer.append(" => "); - buffer.append(getValue(result)); - } - log(buffer.toString()); + protected void logResult(final MethodInvocation invocation, final Object result, final long mill) { + final StringBuffer buffer = createBuffer(invocation); + addMethodName(invocation, buffer); + if (invocation.getMethod().getReturnType() != null) { + buffer.append(" => "); + buffer.append(getValue(result)); + buffer.append(", time consumed: "); + buffer.append(mill); + buffer.append("ms"); } + log(buffer.toString()); + } } Modified: trunk/src/main/java/cc/kune/core/server/content/ContentManagerDefault.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/content/ContentManagerDefault.java 2012-03-29 01:36:02 UTC (rev 1806) +++ trunk/src/main/java/cc/kune/core/server/content/ContentManagerDefault.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -60,6 +60,7 @@ import cc.kune.core.server.utils.FilenameUtils; import cc.kune.core.shared.domain.ContentStatus; import cc.kune.core.shared.domain.RateResult; +import cc.kune.core.shared.domain.utils.StateToken; import cc.kune.core.shared.dto.SocialNetworkSubGroup; import cc.kune.domain.Container; import cc.kune.domain.Content; @@ -72,6 +73,8 @@ import cc.kune.domain.finders.ContentFinder; import cc.kune.domain.finders.I18nLanguageFinder; import cc.kune.domain.finders.UserFinder; +import cc.kune.events.server.utils.EventsCache; +import cc.kune.events.shared.EventsToolConstants; import cc.kune.wave.server.KuneWaveServerUtils; import cc.kune.wave.server.ParticipantUtils; import cc.kune.wave.server.kspecific.KuneWaveService; @@ -84,6 +87,7 @@ public class ContentManagerDefault extends DefaultManager<Content, Long> implements ContentManager { private final ContainerFinder containerFinder; private final ContentFinder contentFinder; + private final EventsCache eventsCache; private final FinderService finder; private final I18nTranslationService i18n; private final KuneWaveService kuneWaveManager; @@ -101,7 +105,8 @@ final FinderService finder, final UserFinder userFinder, final I18nLanguageFinder languageFinder, final TagUserContentManager tagManager, final KuneWaveService kuneWaveManager, final ParticipantUtils participantUtils, final ServerToolRegistry tools, - final XMLActionReader xmlActionReader, final I18nTranslationService i18n) { + final XMLActionReader xmlActionReader, final I18nTranslationService i18n, + final EventsCache eventsCache) { super(provider, Content.class); this.contentFinder = contentFinder; this.containerFinder = containerFinder; @@ -114,6 +119,7 @@ this.tools = tools; this.xmlActionReader = xmlActionReader; this.i18n = i18n; + this.eventsCache = eventsCache; } @Override @@ -176,6 +182,16 @@ return addParticipants(user, content, members.toArray(new String[members.size()])); } + private void clearEventsCacheIfNecessary(final Container previousParent) { + if (previousParent.getToolName().equals(EventsToolConstants.NAME)) { + eventsCache.remove(previousParent); + } + } + + private void clearEventsCacheIfNecessary(final StateToken token) { + clearEventsCacheIfNecessary(finder.getContainer(token.getFolder())); + } + @Override public Content copyContent(final User user, final Container destination, final Content contentToCopy) { try { @@ -304,6 +320,7 @@ oldContainer.removeContent(content); newContainer.addContent(content); content.setContainer(newContainer); + clearEventsCacheIfNecessary(oldContainer); return persist(content); } @@ -351,6 +368,7 @@ getContentAuthor(content)); } setModifiedTime(content); + clearEventsCacheIfNecessary(content.getContainer()); return content; } @@ -413,6 +431,9 @@ public void setGadgetProperties(final User user, final Content content, final String gadgetName, final Map<String, String> properties) { final URL gadgetUrl = getGadgetUrl(gadgetName); + if (gadgetName.equals(EventsToolConstants.TYPE_MEETING_DEF_GADGETNAME)) { + eventsCache.remove(content.getContainer()); + } kuneWaveManager.setGadgetProperty(KuneWaveServerUtils.getWaveRef(content), getContentAuthor(content), gadgetUrl, properties); } Added: trunk/src/main/java/cc/kune/core/server/manager/impl/SocialNetworkCache.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/manager/impl/SocialNetworkCache.java (rev 0) +++ trunk/src/main/java/cc/kune/core/server/manager/impl/SocialNetworkCache.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -0,0 +1,99 @@ +/* + * + * Copyright (C) 2007-2012 The kune development team (see CREDITS for details) + * This file is part of kune. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package cc.kune.core.server.manager.impl; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import cc.kune.common.shared.utils.Pair; +import cc.kune.core.server.LogThis; +import cc.kune.core.server.persist.CachedCollection; +import cc.kune.domain.Group; +import cc.kune.domain.SocialNetworkData; +import cc.kune.domain.User; + +import com.google.inject.Singleton; + +/** + * The Class SocialNetworkCache create a cache for maker faster the retrieve of + * the SN of a user + */ +@LogThis +@Singleton +public class SocialNetworkCache extends CachedCollection<Pair<User, Group>, SocialNetworkData> { + public static final Log LOG = LogFactory.getLog(SocialNetworkCache.class); + + /** The expired groups. */ + private final Set<Group> expiredGroups; + + /** + * Instantiates a new social network cache. + */ + public SocialNetworkCache() { + super(100); + expiredGroups = Collections.synchronizedSet(new HashSet<Group>()); + } + + /** + * Adds a group which SN is modified, so we should not use the cache for that. + * + * @param group + * the group + */ + public void expire(final Group group) { + expiredGroups.add(group); + } + + /** + * Gets the SN of some user/group from the cache if available + * + * @param user + * the user + * @param group + * the group + * @return the social network data + */ + public SocialNetworkData get(final User user, final Group group) { + final Pair<User, Group> pair = Pair.create(user, group); + if (expiredGroups.contains(group)) { + // TODO Do this in a cron job + final Iterator<Pair<User, Group>> iterator = super.keySet().iterator(); + while (iterator.hasNext()) { + if (iterator.next().right.equals(group)) { + iterator.remove(); + } + } + expiredGroups.remove(group); + LOG.debug("Not returning expired SN info"); + return null; + } + return super.get(pair); + } + + public Object put(final User user, final Group group, final SocialNetworkData data) { + return super.put(Pair.create(user, group), data); + } +} Added: trunk/src/main/java/cc/kune/core/server/manager/impl/SocialNetworkCacheClearDailyJob.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/manager/impl/SocialNetworkCacheClearDailyJob.java (rev 0) +++ trunk/src/main/java/cc/kune/core/server/manager/impl/SocialNetworkCacheClearDailyJob.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -0,0 +1,40 @@ +/* + * + * Copyright (C) 2007-2012 The kune development team (see CREDITS for details) + * This file is part of kune. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package cc.kune.core.server.manager.impl; + +import java.text.ParseException; + +import org.quartz.SchedulerException; + +import cc.kune.core.server.persist.ClearCacheDailyJob; + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +@Singleton +public class SocialNetworkCacheClearDailyJob extends ClearCacheDailyJob { + + @Inject + public SocialNetworkCacheClearDailyJob(final SocialNetworkCache cache) throws ParseException, SchedulerException { + super(cache); + } + +} Modified: trunk/src/main/java/cc/kune/core/server/manager/impl/SocialNetworkManagerDefault.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/manager/impl/SocialNetworkManagerDefault.java 2012-03-29 01:36:02 UTC (rev 1806) +++ trunk/src/main/java/cc/kune/core/server/manager/impl/SocialNetworkManagerDefault.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -23,6 +23,9 @@ import javax.persistence.EntityManager; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import cc.kune.core.client.errors.AccessViolationException; import cc.kune.core.client.errors.AlreadyGroupMemberException; import cc.kune.core.client.errors.AlreadyUserMemberException; @@ -57,19 +60,22 @@ @Singleton public class SocialNetworkManagerDefault extends DefaultManager<SocialNetwork, Long> implements SocialNetworkManager { + public static final Log LOG = LogFactory.getLog(SocialNetworkManagerDefault.class); private final AccessRightsService accessRightsService; private final GroupFinder finder; + private final SocialNetworkCache snCache; private final UserManager userManager; @Inject public SocialNetworkManagerDefault(@DataSourceKune final Provider<EntityManager> provider, final GroupFinder finder, final AccessRightsService accessRightsService, - final UserManager userManager) { + final UserManager userManager, final SocialNetworkCache snCache) { super(provider, SocialNetwork.class); this.finder = finder; this.accessRightsService = accessRightsService; this.userManager = userManager; + this.snCache = snCache; } @Override @@ -81,6 +87,7 @@ if (pendingCollabs.contains(group)) { sn.addCollaborator(group); sn.removePendingCollaborator(group); + snCache.expire(inGroup); } else { throw new DefaultException("User is not a pending collaborator"); } @@ -89,6 +96,7 @@ void addAdmin(final User newAdmin, final Group group) { final SocialNetwork sn = group.getSocialNetwork(); sn.addAdmin(newAdmin.getUserGroup()); + snCache.expire(group); } @Override @@ -102,6 +110,7 @@ if (sn.isPendingCollab(group)) { sn.removePendingCollaborator(group); } + snCache.expire(inGroup); } @Override @@ -115,6 +124,7 @@ if (sn.isPendingCollab(group)) { sn.removePendingCollaborator(group); } + snCache.expire(inGroup); } @Override @@ -128,6 +138,7 @@ if (sn.isPendingCollab(group)) { sn.removePendingCollaborator(group); } + snCache.expire(inGroup); } private void checkGroupAddingToSelf(final Group group, final Group inGroup) throws DefaultException { @@ -157,6 +168,7 @@ checkUserLoggedIsAdmin(userLogged, sn); unJoinGroup(group, inGroup); + snCache.expire(inGroup); } @Override @@ -170,6 +182,7 @@ } else { throw new DefaultException("Person/Group is not a pending collaborator"); } + snCache.expire(inGroup); } @Override @@ -202,10 +215,16 @@ public SocialNetworkData getSocialNetworkData(final User userLogged, final Group group) { final SocialNetworkData socialNetData = new SocialNetworkData(); socialNetData.setGroupMembers(get(userLogged, group)); + + final SocialNetworkData cached = snCache.get(userLogged, group); + if (cached != null) { + LOG.debug("Returning cached SN"); + return cached; + } final AccessRights groupRights = accessRightsService.get(userLogged, group.getAccessLists()); socialNetData.setGroupRights(groupRights); socialNetData.setUserParticipation(findParticipation(userLogged, group)); - socialNetData.setGroupMembers(get(userLogged, group)); + // socialNetData.setGroupMembers(get(userLogged, group)); if (group.isPersonal()) { final UserBuddiesData userBuddies = userManager.getUserBuddies(group.getShortName()); final User userGroup = userManager.findByShortname(group.getShortName()); @@ -253,6 +272,7 @@ socialNetData.setSocialNetworkVisibility(visibility); socialNetData.setUserBuddies(UserBuddiesData.EMPTY); } + snCache.put(userLogged, group, socialNetData); return socialNetData; } @@ -287,6 +307,7 @@ checkGroupIsNotAlreadyAMember(userGroup, sn); if (isModerated(admissionType)) { sn.addPendingCollaborator(userGroup); + snCache.expire(inGroup); return SocialNetworkRequestResult.moderated; } else if (isOpen(admissionType)) { if (inGroup.getGroupType().equals(GroupType.ORPHANED_PROJECT)) { @@ -297,6 +318,7 @@ } else { sn.addCollaborator(userGroup); } + snCache.expire(inGroup); return SocialNetworkRequestResult.accepted; } else if (isClosed(admissionType)) { return SocialNetworkRequestResult.denied; @@ -316,6 +338,7 @@ } sn.removeAdmin(group); sn.addCollaborator(group); + snCache.expire(inGroup); } else { throw new InvalidSNOperationException("Person/Group is not an admin"); } @@ -327,6 +350,7 @@ final SocialNetwork sn = inGroup.getSocialNetwork(); checkUserLoggedIsAdmin(userLogged, sn); if (sn.isCollab(group)) { + snCache.expire(inGroup); sn.removeCollaborator(group); sn.addAdmin(group); } else { @@ -351,12 +375,15 @@ if (sn.getAccessLists().getEditors().getList().size() > 0) { throw new LastAdminInGroupException(); } else { + snCache.expire(inGroup); inGroup.setGroupType(GroupType.ORPHANED_PROJECT); inGroup.setAdmissionType(AdmissionType.Open); } } + snCache.expire(inGroup); sn.removeAdmin(groupToUnJoin); } else if (sn.isCollab(groupToUnJoin)) { + snCache.expire(inGroup); sn.removeCollaborator(groupToUnJoin); } else { throw new DefaultException("Person/Group is not a collaborator"); Added: trunk/src/main/java/cc/kune/core/server/persist/CachedCollection.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/persist/CachedCollection.java (rev 0) +++ trunk/src/main/java/cc/kune/core/server/persist/CachedCollection.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -0,0 +1,114 @@ +/* + * + * Copyright (C) 2007-2012 The kune development team (see CREDITS for details) + * This file is part of kune. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package cc.kune.core.server.persist; + +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.collections.map.LRUMap; + +/** + * The Class CachedCollection implements some custom cache for often accessed + * (and costly) objects + * + * @param <K> + * the key type + * @param <V> + * the value type + */ +public class CachedCollection<K, V> implements Map<K, V> { + + /** The cache. */ + // private final Map<K, V> cache; + private final Map cache; + + /** + * Instantiates a new cached collection. + * + * @param size + * the size of the cache + */ + public CachedCollection(final int size) { + cache = Collections.synchronizedMap(new LRUMap(size)); + } + + @Override + public void clear() { + cache.clear(); + } + + @Override + public boolean containsKey(final Object key) { + return cache.containsKey(key); + } + + @Override + public boolean containsValue(final Object value) { + return cache.containsKey(value); + } + + @Override + public Set<java.util.Map.Entry<K, V>> entrySet() { + return cache.entrySet(); + } + + @Override + public V get(final Object key) { + return (V) cache.get(key); + } + + @Override + public boolean isEmpty() { + return cache.isEmpty(); + } + + @Override + public Set<K> keySet() { + return cache.keySet(); + } + + @Override + public Object put(final Object key, final Object value) { + return cache.put(key, value); + } + + @Override + public void putAll(final Map<? extends K, ? extends V> m) { + cache.putAll(m); + } + + @Override + public V remove(final Object key) { + return (V) cache.remove(key); + } + + @Override + public int size() { + return cache.size(); + } + + @Override + public Collection<V> values() { + return cache.values(); + } +} Added: trunk/src/main/java/cc/kune/core/server/persist/CachedCollectionTest.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/persist/CachedCollectionTest.java (rev 0) +++ trunk/src/main/java/cc/kune/core/server/persist/CachedCollectionTest.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -0,0 +1,54 @@ +/* + * + * Copyright (C) 2007-2012 The kune development team (see CREDITS for details) + * This file is part of kune. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package cc.kune.core.server.persist; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; + +public class CachedCollectionTest { + + private CachedCollection<String, String> cache; + + @Before + public void before() { + cache = new CachedCollection<String, String>(2); + } + + @Test + public void testBasicSize() { + assertTrue(cache.size() == 0); + final String first = "1"; + cache.put(first, "1b"); + final String snd = "2"; + cache.put(snd, "2b"); + final String third = "3"; + cache.put(third, "3b"); + assertNull(cache.get(first)); + assertNotNull(cache.get(snd)); + assertNotNull(cache.get(third)); + assertTrue(cache.size() == 2); + } + +} Added: trunk/src/main/java/cc/kune/core/server/persist/ClearCacheDailyJob.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/persist/ClearCacheDailyJob.java (rev 0) +++ trunk/src/main/java/cc/kune/core/server/persist/ClearCacheDailyJob.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -0,0 +1,46 @@ +/* + * + * Copyright (C) 2007-2011 The kune development team (see CREDITS for details) + * This file is part of kune. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +package cc.kune.core.server.persist; + +import java.text.ParseException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.quartz.SchedulerException; + +public abstract class ClearCacheDailyJob implements Job { + + public static final Log LOG = LogFactory.getLog(ClearCacheDailyJob.class); + private final CachedCollection cache; + + public ClearCacheDailyJob(final CachedCollection cache) throws ParseException, SchedulerException { + this.cache = cache; + } + + @Override + public void execute(final JobExecutionContext context) throws JobExecutionException { + LOG.info("Daily cache clear"); + cache.clear(); + } + +} Modified: trunk/src/main/java/cc/kune/core/server/rpc/ContentRPC.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/rpc/ContentRPC.java 2012-03-29 01:36:02 UTC (rev 1806) +++ trunk/src/main/java/cc/kune/core/server/rpc/ContentRPC.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -35,6 +35,7 @@ import cc.kune.core.client.errors.NoDefaultContentException; import cc.kune.core.client.errors.ToolNotFoundException; import cc.kune.core.client.rpcservices.ContentService; +import cc.kune.core.server.LogThis; import cc.kune.core.server.UserSessionManager; import cc.kune.core.server.access.AccessRightsService; import cc.kune.core.server.access.AccessService; @@ -74,16 +75,19 @@ import cc.kune.domain.Content; import cc.kune.domain.Group; import cc.kune.domain.User; +import cc.kune.events.server.utils.EventsCache; import cc.kune.trash.shared.TrashToolConstants; import com.google.inject.Inject; +@LogThis public class ContentRPC implements ContentService, RPC { private final AccessService accessService; private final ChatManager chatManager; private final ContainerManager containerManager; private final ContentManager contentManager; private final CreationService creationService; + private final EventsCache eventsCache; private final FinderService finderService; private final GroupManager groupManager; private final Mapper mapper; @@ -99,7 +103,8 @@ final StateService stateService, final CreationService creationService, final GroupManager groupManager, final ContentManager contentManager, final ContainerManager containerManager, final TagUserContentManager tagManager, - final Mapper mapper, final ChatManager chatManager, final KuneWaveManager waveManager) { + final Mapper mapper, final ChatManager chatManager, final KuneWaveManager waveManager, + final EventsCache eventsCache) { this.finderService = finderService; this.userSession = userSession; this.accessService = accessService; @@ -113,6 +118,7 @@ this.mapper = mapper; this.chatManager = chatManager; this.waveManager = waveManager; + this.eventsCache = eventsCache; } @Override @@ -274,7 +280,6 @@ } final Container trash = containerManager.getTrashFolder(group); return moveContent(userHash, token, trash.getStateToken()); - // return getState(getCurrentUser(), previousParent); } @Override Modified: trunk/src/main/java/cc/kune/core/server/rpc/RPC.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/rpc/RPC.java 2012-03-29 01:36:02 UTC (rev 1806) +++ trunk/src/main/java/cc/kune/core/server/rpc/RPC.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -19,8 +19,6 @@ */ package cc.kune.core.server.rpc; -import cc.kune.core.server.LogThis; - import com.google.inject.Singleton; /** @@ -37,7 +35,6 @@ * */ @Singleton -@LogThis public interface RPC { } Modified: trunk/src/main/java/cc/kune/core/server/scheduler/CronServerTasksManager.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/scheduler/CronServerTasksManager.java 2012-03-29 01:36:02 UTC (rev 1806) +++ trunk/src/main/java/cc/kune/core/server/scheduler/CronServerTasksManager.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -35,11 +35,13 @@ import org.quartz.SchedulerException; import org.quartz.impl.StdSchedulerFactory; +import cc.kune.core.server.manager.impl.SocialNetworkCacheClearDailyJob; import cc.kune.core.server.notifier.ClearUpdatedWavesHourlyJob; import cc.kune.core.server.notifier.PendingNotificationDailyJob; import cc.kune.core.server.notifier.PendingNotificationHourlyJob; import cc.kune.core.server.notifier.PendingNotificationImmediateJob; import cc.kune.core.server.rack.ContainerListener; +import cc.kune.events.server.utils.EventsCacheClearDailyJob; import com.google.inject.Inject; import com.google.inject.Singleton; @@ -78,6 +80,8 @@ scheduleJob(PendingNotificationHourlyJob.class, "0 0 * * * ?", "pendingnotifhourly"); scheduleJob(ClearUpdatedWavesHourlyJob.class, "0 0 * * * ?", "clearupdatedwaveshourly"); scheduleJob(PendingNotificationDailyJob.class, "0 5 0 * * ?", "pendingnotifdaily"); + scheduleJob(EventsCacheClearDailyJob.class, "0 6 0 * * ?", "cleareventscachedaily"); + scheduleJob(SocialNetworkCacheClearDailyJob.class, "0 6 0 * * ?", "clearcontentcachedaily"); } catch (final SchedulerException e) { logError(e); } catch (final ParseException e) { Modified: trunk/src/main/java/cc/kune/core/server/state/StateServiceDefault.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/state/StateServiceDefault.java 2012-03-29 01:36:02 UTC (rev 1806) +++ trunk/src/main/java/cc/kune/core/server/state/StateServiceDefault.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -146,14 +146,15 @@ state.setContentRights(rightsService.get(userLogged, content.getAccessLists())); state.setAccessLists(content.getAccessLists()); setCommon(state, userLogged, group, container); - if (userLogged != User.UNKNOWN_USER) { - state.setCurrentUserRate(contentManager.getRateContent(userLogged, content)); - } + // if (userLogged != User.UNKNOWN_USER) { + // state.setCurrentUserRate(contentManager.getRateContent(userLogged, + // content)); + // } // FIXME: user RateResult - final Double rateAvg = contentManager.getRateAvg(content); - state.setRate(rateAvg != null ? rateAvg : 0D); - final Long rateByUsers = contentManager.getRateByUsers(content); - state.setRateByUsers(rateByUsers != null ? rateByUsers.intValue() : 0); + // final Double rateAvg = contentManager.getRateAvg(content); + // state.setRate(rateAvg != null ? rateAvg : 0D); + // final Long rateByUsers = contentManager.getRateByUsers(content); + // state.setRateByUsers(rateByUsers != null ? rateByUsers.intValue() : 0); return state; } Modified: trunk/src/main/java/cc/kune/domain/Container.java =================================================================== --- trunk/src/main/java/cc/kune/domain/Container.java 2012-03-29 01:36:02 UTC (rev 1806) +++ trunk/src/main/java/cc/kune/domain/Container.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -139,6 +139,28 @@ contents.add(descriptor); } + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Container other = (Container) obj; + if (id == null) { + if (other.id != null) { + return false; + } + } else if (!id.equals(other.id)) { + return false; + } + return true; + } + @Transient public List<Container> getAbsolutePath() { ArrayList<Container> path; @@ -230,6 +252,14 @@ return accessLists != null; } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + @Transient public boolean isLeaf() { return childs.size() == 0 && contents.size() == 0; Modified: trunk/src/main/java/cc/kune/domain/Content.java =================================================================== --- trunk/src/main/java/cc/kune/domain/Content.java 2012-03-29 01:36:02 UTC (rev 1806) +++ trunk/src/main/java/cc/kune/domain/Content.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -139,6 +139,8 @@ @Version private Integer version; + // TODO add index and also to debian package and liquibase + // @Index(name = "waveId") private String waveId; public Content() { @@ -269,7 +271,8 @@ || typeId.equals(TasksToolConstants.TYPE_TASK) || typeId.equals(ListsToolConstants.TYPE_POST) || typeId.equals(WikiToolConstants.TYPE_WIKIPAGE) - || (typeId.equals(BlogsToolConstants.TYPE_POST) || typeId.equals(BartersToolConstants.TYPE_BARTER) || typeId.equals(EventsToolConstants.TYPE_MEETING)); + || (typeId.equals(BlogsToolConstants.TYPE_POST) + || typeId.equals(BartersToolConstants.TYPE_BARTER) || typeId.equals(EventsToolConstants.TYPE_MEETING)); } public void removeAuthor(final User user) { Modified: trunk/src/main/java/cc/kune/events/client/actions/EventsClientActions.java =================================================================== --- trunk/src/main/java/cc/kune/events/client/actions/EventsClientActions.java 2012-03-29 01:36:02 UTC (rev 1806) +++ trunk/src/main/java/cc/kune/events/client/actions/EventsClientActions.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -52,7 +52,7 @@ @Inject public EventsClientActions(final I18nUITranslationService i18n, final Session session, final StateManager stateManager, final ActionRegistryByType registry, final CoreResources res, - final Provider<NewMeetingBtn> newMeetingsBtn, final Provider<GoParentFolderBtn> folderGoUp, + final Provider<NewEventBtn> newEventBtn, final Provider<GoParentFolderBtn> folderGoUp, final Provider<OpenMeetingMenuItem> openContentMenuItem, final Provider<DelMeetingMenuItem> delContentMenuItem, final Provider<ContentViewerOptionsMenu> optionsMenuContent, @@ -102,7 +102,7 @@ eventAddMenuItem.get(); eventRemoveMenuItem.get(); - actionsRegistry.addAction(ActionGroups.TOPBAR, newMeetingsBtn, containers); + actionsRegistry.addAction(ActionGroups.TOPBAR, newEventBtn, containers); // For now, commented: // actionsRegistry.addAction(ActionGroups.ITEM_MENU, openContentMenuItem, Copied: trunk/src/main/java/cc/kune/events/client/actions/NewEventBtn.java (from rev 1797, trunk/src/main/java/cc/kune/events/client/actions/NewMeetingBtn.java) =================================================================== --- trunk/src/main/java/cc/kune/events/client/actions/NewEventBtn.java (rev 0) +++ trunk/src/main/java/cc/kune/events/client/actions/NewEventBtn.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -0,0 +1,40 @@ +/* + * + * Copyright (C) 2007-2011 The kune development team (see CREDITS for details) + * This file is part of kune. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +package cc.kune.events.client.actions; + +import cc.kune.common.client.actions.ui.descrip.ButtonDescriptor; +import cc.kune.common.client.shortcuts.GlobalShortcutRegister; +import cc.kune.common.shared.i18n.I18nTranslationService; +import cc.kune.core.client.resources.nav.NavResources; +import cc.kune.events.client.actions.EventAddMenuItem.EventAddAction; + +import com.google.inject.Inject; + +public class NewEventBtn extends ButtonDescriptor { + + @Inject + public NewEventBtn(final I18nTranslationService i18n, final EventAddAction action, + final NavResources res, final GlobalShortcutRegister shorcutReg) { + super(i18n.t("New event"), action); + withIcon(res.calendarAdd()).withToolTip(i18n.t("Create a New Event")); + action.setOpenAfterCreation(true); + } + +} Deleted: trunk/src/main/java/cc/kune/events/client/actions/NewMeetingBtn.java =================================================================== --- trunk/src/main/java/cc/kune/events/client/actions/NewMeetingBtn.java 2012-03-29 01:36:02 UTC (rev 1806) +++ trunk/src/main/java/cc/kune/events/client/actions/NewMeetingBtn.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -1,40 +0,0 @@ -/* - * - * Copyright (C) 2007-2011 The kune development team (see CREDITS for details) - * This file is part of kune. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ -package cc.kune.events.client.actions; - -import cc.kune.common.client.actions.ui.descrip.ButtonDescriptor; -import cc.kune.common.client.shortcuts.GlobalShortcutRegister; -import cc.kune.common.shared.i18n.I18nTranslationService; -import cc.kune.core.client.resources.nav.NavResources; -import cc.kune.events.client.actions.EventAddMenuItem.EventAddAction; - -import com.google.inject.Inject; - -public class NewMeetingBtn extends ButtonDescriptor { - - @Inject - public NewMeetingBtn(final I18nTranslationService i18n, final EventAddAction action, - final NavResources res, final GlobalShortcutRegister shorcutReg) { - super(i18n.t("New meeting"), action); - withIcon(res.calendarAdd()).withToolTip(i18n.t("Create a New Meeting")); - action.setOpenAfterCreation(true); - } - -} Modified: trunk/src/main/java/cc/kune/events/client/viewer/CalendarViewerPanel.java =================================================================== --- trunk/src/main/java/cc/kune/events/client/viewer/CalendarViewerPanel.java 2012-03-29 01:36:02 UTC (rev 1806) +++ trunk/src/main/java/cc/kune/events/client/viewer/CalendarViewerPanel.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -81,15 +81,8 @@ final TutorialViewer tutorialViewer) { super(gsArmor, eventBus, i18n, capabilitiesRegistry, dragController, contentDropControllerProv, containerDropControllerProv, tutorialViewer); - final CalendarSettings settings = new CalendarSettings(); - settings.setIntervalsPerHour(4); - settings.setPixelsPerInterval(10); - // With Single is very annoying - // settings.setTimeBlockClickNumber(Click.Single); - // settings.setOffsetHourLabels(true); - settings.setScrollToHour(8); calendar = new Calendar(); - calendar.setSettings(settings); + calendar.setSettings(setCalendarSettings()); widget = calendar; calendar.sinkEvents(Event.ONMOUSEDOWN | Event.ONDBLCLICK | Event.KEYEVENTS | Event.ONMOUSEOVER | Event.ONCLICK); @@ -171,6 +164,7 @@ @Override public void attach() { + calendar.setSettings(setCalendarSettings()); super.attach(); gsArmor.enableCenterScroll(false); } @@ -246,6 +240,17 @@ calendar.resumeLayout(); } + private CalendarSettings setCalendarSettings() { + final CalendarSettings settings = new CalendarSettings(); + settings.setIntervalsPerHour(4); + settings.setPixelsPerInterval(10); + // With Single is very annoying + // settings.setTimeBlockClickNumber(Click.Single); + // settings.setOffsetHourLabels(true); + settings.setScrollToHour(8); + return settings; + } + @Override public void setDate(final Date date) { calendar.setDate(date); Modified: trunk/src/main/java/cc/kune/events/server/EventsServerTool.java =================================================================== --- trunk/src/main/java/cc/kune/events/server/EventsServerTool.java 2012-03-29 01:36:02 UTC (rev 1806) +++ trunk/src/main/java/cc/kune/events/server/EventsServerTool.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -45,21 +45,24 @@ import cc.kune.domain.Content; import cc.kune.domain.Group; import cc.kune.domain.User; +import cc.kune.events.server.utils.EventsCache; import com.google.inject.Inject; public class EventsServerTool extends AbstractServerTool implements ServerWaveTool { private static final String MEETING_GADGET = "http://mass-mob.appspot.com/massmob/org.ourproject.massmob.client.MassmobGad..."; + private final EventsCache eventsCache; private final URL gadgetUrl; @Inject public EventsServerTool(final ContentManager contentManager, final ContainerManager containerManager, final ToolConfigurationManager configurationManager, final I18nTranslationService i18n, - final CreationService creationService) { + final CreationService creationService, final EventsCache eventsCache) { super(NAME, ROOT_NAME, TYPE_ROOT, Arrays.asList(TYPE_MEETING), Arrays.asList(TYPE_ROOT), Collections.<String> emptyList(), Arrays.asList(TYPE_ROOT), contentManager, containerManager, creationService, configurationManager, i18n, ServerToolTarget.forBoth); + this.eventsCache = eventsCache; gadgetUrl = UrlUtils.of(MEETING_GADGET); } @@ -83,6 +86,7 @@ public void onCreateContent(final Content content, final Container parent) { content.setStatus(ContentStatus.publishedOnline); content.setPublishedOn(new Date()); + eventsCache.remove(parent); } @Override Modified: trunk/src/main/java/cc/kune/events/server/EventsServlet.java =================================================================== --- trunk/src/main/java/cc/kune/events/server/EventsServlet.java 2012-03-29 01:36:02 UTC (rev 1806) +++ trunk/src/main/java/cc/kune/events/server/EventsServlet.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -88,7 +88,7 @@ try { final Container cnt = getContainer(userHash, token); if (cnt != null && cnt.getTypeId().equals(EventsToolConstants.TYPE_ROOT)) { - final List<Map<String, String>> listOfProps = EventsServerConversionUtil.getAppointments(cnt); + final List<Map<String, String>> listOfProps = EventsServerConversionUtil.getAppointmentsUsingCache(cnt); for (final Map<String, String> props : listOfProps) { try { final VEvent vEvent = EventsServerConversionUtil.toVEvent(EventsServerConversionUtil.toApp(props)); Added: trunk/src/main/java/cc/kune/events/server/utils/EventsCache.java =================================================================== --- trunk/src/main/java/cc/kune/events/server/utils/EventsCache.java (rev 0) +++ trunk/src/main/java/cc/kune/events/server/utils/EventsCache.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -0,0 +1,82 @@ +/* + * + * Copyright (C) 2007-2012 The kune development team (see CREDITS for details) + * This file is part of kune. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package cc.kune.events.server.utils; + +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import cc.kune.core.server.LogThis; +import cc.kune.core.server.persist.CachedCollection; +import cc.kune.domain.Container; + +import com.google.inject.Singleton; + +/** + * The Class EventsCache is used to cache events of a group. Right now is only + * used in the export functionality because we don't have a way to detect gadget + * changes (of dates, etc) to expire this elements. + */ +@LogThis +@Singleton +public class EventsCache extends CachedCollection<Container, List<Map<String, String>>> { + + /** The Constant LOG. */ + public static final Log LOG = LogFactory.getLog(EventsCache.class); + + /** + * Instantiates a new events cache. + */ + public EventsCache() { + super(100); + } + + /* + * (non-Javadoc) + * + * @see cc.kune.core.server.persist.CachedCollection#get(java.lang.Object) + */ + @Override + public List<Map<String, String>> get(final Object key) { + final List<Map<String, String>> list = super.get(key); + if (list != null) { + LOG.debug("Using events cache for " + ((Container) key).getStateToken()); + } else { + LOG.debug("Events cache empty for " + ((Container) key).getStateToken()); + } + return list; + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#put(java.lang.Object, java.lang.Object) + */ + @Override + public List<Map<String, String>> put(final Container container, final List<Map<String, String>> value) { + final Object put = super.put(container, value); + LOG.debug("Event list added for container " + container.getStateToken() + ", size " + this.size()); + return (List<Map<String, String>>) put; + } + +} Added: trunk/src/main/java/cc/kune/events/server/utils/EventsCacheClearDailyJob.java =================================================================== --- trunk/src/main/java/cc/kune/events/server/utils/EventsCacheClearDailyJob.java (rev 0) +++ trunk/src/main/java/cc/kune/events/server/utils/EventsCacheClearDailyJob.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -0,0 +1,40 @@ +/* + * + * Copyright (C) 2007-2012 The kune development team (see CREDITS for details) + * This file is part of kune. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package cc.kune.events.server.utils; + +import java.text.ParseException; + +import org.quartz.SchedulerException; + +import cc.kune.core.server.persist.ClearCacheDailyJob; + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +@Singleton +public class EventsCacheClearDailyJob extends ClearCacheDailyJob { + + @Inject + public EventsCacheClearDailyJob(final EventsCache cache) throws ParseException, SchedulerException { + super(cache); + } + +} Modified: trunk/src/main/java/cc/kune/events/server/utils/EventsServerConversionUtil.java =================================================================== --- trunk/src/main/java/cc/kune/events/server/utils/EventsServerConversionUtil.java 2012-03-29 01:36:02 UTC (rev 1806) +++ trunk/src/main/java/cc/kune/events/server/utils/EventsServerConversionUtil.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -60,6 +60,9 @@ public class EventsServerConversionUtil extends EventsSharedConversionUtil { @Inject + static EventsCache eventsCache; + + @Inject private static EventsServerTool eventTool; @Inject @@ -94,9 +97,18 @@ + waveId, e2); } } + eventsCache.put(container, list); return list; } + public static List<Map<String, String>> getAppointmentsUsingCache(final Container container) { + final List<Map<String, String>> cached = eventsCache.get(container); + if (cached != null) { + return cached; + } + return getAppointments(container); + } + public static Appointment to(final VEvent event) { // http://build.mnode.org/projects/ical4j/apidocs/ final Appointment app = new Appointment(); Modified: trunk/src/main/java/cc/kune/wave/client/WaveStatusIndicator.java =================================================================== --- trunk/src/main/java/cc/kune/wave/client/WaveStatusIndicator.java 2012-03-29 01:36:02 UTC (rev 1806) +++ trunk/src/main/java/cc/kune/wave/client/WaveStatusIndicator.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -66,8 +66,10 @@ break; case DISCONNECTED: NotifyUser.showProgress(i18n.t("Connecting")); + break; case RECONNECTING: - putValue(Action.NAME, i18n.t("Offline")); + NotifyUser.showProgress(i18n.t("Offline")); + // putValue(Action.NAME, i18n.t("Offline")); putValue(AbstractAction.STYLES, "k-sitebar-wave-status, k-sitebar-wave-status-offline"); setVisible(true); break; Added: trunk/src/test/java/cc/kune/core/server/manager/impl/SocialNetworkCacheTest.java =================================================================== --- trunk/src/test/java/cc/kune/core/server/manager/impl/SocialNetworkCacheTest.java (rev 0) +++ trunk/src/test/java/cc/kune/core/server/manager/impl/SocialNetworkCacheTest.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -0,0 +1,73 @@ +/* + * + * Copyright (C) 2007-2012 The kune development team (see CREDITS for details) + * This file is part of kune. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package cc.kune.core.server.manager.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Before; +import org.junit.Test; + +import cc.kune.domain.Group; +import cc.kune.domain.SocialNetworkData; +import cc.kune.domain.User; + +public class SocialNetworkCacheTest { + + private SocialNetworkCache cache; + private SocialNetworkData data; + private Group group1; + private Group group2; + private User user1; + private User user2; + + @Before + public void before() { + cache = new SocialNetworkCache(); + user1 = new User(); + user2 = new User(); + user1.setShortName("user1"); + user2.setShortName("user2"); + group1 = new Group("group1", "group1"); + group2 = new Group("group2", "group2"); + data = new SocialNetworkData(); + } + + @Test + public void testBasicAdd() { + assertNull(cache.get(user1, group1)); + cache.put(user1, group1, data); + cache.expire(group2); + assertEquals(data, cache.get(user1, group1)); + assertEquals(1, cache.size()); + } + + @Test + public void testBasicAddDirty() { + assertNull(cache.get(user1, group1)); + cache.put(user1, group1, data); + cache.put(user2, group1, data); + assertEquals(2, cache.size()); + cache.expire(group1); + assertNull(cache.get(user1, group1)); + assertEquals(0, cache.size()); + } +} Added: trunk/src/test/java/cc/kune/events/server/utils/EventsCacheTest.java =================================================================== --- trunk/src/test/java/cc/kune/events/server/utils/EventsCacheTest.java (rev 0) +++ trunk/src/test/java/cc/kune/events/server/utils/EventsCacheTest.java 2012-03-30 11:26:03 UTC (rev 1807) @@ -0,0 +1,60 @@ +/* + * + * Copyright (C) 2007-2012 The kune development team (see CREDITS for details) + * This file is part of kune. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package cc.kune.events.server.utils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.util.ArrayList; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import cc.kune.core.shared.domain.utils.StateToken; +import cc.kune.domain.Container; + +public class EventsCacheTest { + private EventsCache cache; + private Container container; + private ArrayList<Map<String, String>> list; + + @Before + public void before() { + cache = new EventsCache(); + container = Mockito.mock(Container.class); + Mockito.when(container.getStateToken()).thenReturn(new StateToken("kk")); + list = new ArrayList<Map<String, String>>(); + } + + @Test + public void testBasicAdd() { + assertNull(cache.get(container)); + cache.put(container, list); + cache.put(container, list); + assertEquals(1, cache.size()); + cache.remove(container); + assertNull(cache.get(container)); + assertEquals(0, cache.size()); + } + +}
participants (1)
-
Vicente J. Ruiz Jurado