/*
*
* Copyright (C) 2007-2015 Licensed to the Comunes Association (CA) under
* one or more contributor license agreements (see COPYRIGHT for details).
* The CA licenses this file to you under the GNU Affero General Public
* License version 3, (the "License"); you may not use this file except in
* compliance with the License. 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;
import static com.google.inject.matcher.Matchers.annotatedWith;
import static com.google.inject.matcher.Matchers.any;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.waveprotocol.box.server.authentication.SessionManager;
import org.waveprotocol.box.server.robots.dataapi.DataApiOAuthServlet;
import org.waveprotocol.box.server.rpc.AttachmentInfoServlet;
import org.waveprotocol.box.server.rpc.AttachmentServlet;
import org.waveprotocol.box.stat.StatService;
import cc.kune.barters.server.BarterServerModule;
import cc.kune.blogs.server.BlogServerModule;
import cc.kune.chat.server.ChatServerModule;
import cc.kune.common.shared.i18n.I18n;
import cc.kune.core.client.rpcservices.ContentService;
import cc.kune.core.client.rpcservices.GroupService;
import cc.kune.core.client.rpcservices.I18nService;
import cc.kune.core.client.rpcservices.InvitationService;
import cc.kune.core.client.rpcservices.SiteService;
import cc.kune.core.client.rpcservices.SocialNetService;
import cc.kune.core.client.rpcservices.UpDownService;
import cc.kune.core.client.rpcservices.UserService;
import cc.kune.core.server.manager.file.EntityBackgroundDownloadManager;
import cc.kune.core.server.manager.file.EntityLogoDownloadManager;
import cc.kune.core.server.manager.file.FileDownloadManager;
import cc.kune.core.server.manager.file.FileUploadManager;
import cc.kune.core.server.manager.impl.GroupServerUtils;
import cc.kune.core.server.notifier.UsersOnline;
import cc.kune.core.server.persist.DataSourceKunePersistModule;
import cc.kune.core.server.persist.DataSourceOpenfirePersistModule;
import cc.kune.core.server.persist.KuneTransactional;
import cc.kune.core.server.persist.OpenfireTransactional;
import cc.kune.core.server.properties.KuneProperties;
import cc.kune.core.server.rack.RackBuilder;
import cc.kune.core.server.rack.RackModule;
import cc.kune.core.server.rack.filters.ForwardFilter;
import cc.kune.core.server.rack.filters.ListenerFilter;
import cc.kune.core.server.rack.filters.RedirectFilter;
import cc.kune.core.server.rack.filters.rest.RESTServicesModule;
import cc.kune.core.server.rest.ContentCORSService;
import cc.kune.core.server.rest.ContentJSONService;
import cc.kune.core.server.rest.GroupJSONService;
import cc.kune.core.server.rest.I18nTranslationJSONService;
import cc.kune.core.server.rest.SiteCORSService;
import cc.kune.core.server.rest.TestJSONService;
import cc.kune.core.server.rest.UserJSONService;
import cc.kune.core.server.scheduler.CronServerTasksManager;
import cc.kune.docs.server.DocumentServerModule;
import cc.kune.events.server.EventsServerModule;
import cc.kune.events.server.EventsServlet;
import cc.kune.events.server.utils.EventsServerConversionUtil;
import cc.kune.hspace.client.ClientStatsService;
import cc.kune.lists.client.rpc.ListsService;
import cc.kune.lists.server.ListsServerModule;
import cc.kune.tasks.server.TaskServerModule;
import cc.kune.trash.server.TrashServerModule;
import cc.kune.wave.server.CustomInitialsProfilesFetcher;
import cc.kune.wave.server.CustomInitialsProfilesFetcherImpl;
import cc.kune.wave.server.kspecific.KuneWaveServerUtils;
import cc.kune.wave.server.kspecific.WaveEmailNotifier;
import cc.kune.wave.server.search.CustomPerUserWaveViewHandler;
import cc.kune.wave.server.search.CustomPerUserWaveViewHandlerImpl;
import cc.kune.wiki.server.WikiServerModule;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.google.inject.Singleton;
import com.google.inject.matcher.Matchers;
import com.google.inject.persist.jpa.KuneJpaLocalTxnInterceptor;
import com.google.inject.persist.jpa.OpenfireJpaLocalTxnInterceptor;
import com.google.inject.servlet.GuiceFilter;
import com.google.inject.servlet.ServletModule;
/**
* The Class KuneRackModule.
*
* @author danigb@gmail.com
* @author vjrj@ourproject.org (Vicente J. Ruiz Jurado)
*/
public class KuneRackModule implements RackModule {
private static final String EMBED_SUFFIX = "/wse";
/** The Constant LOG. */
public static final Log LOG = LogFactory.getLog(KuneRackModule.class);
/** The suffix of the kune url. */
private static final String SUFFIX = "/ws";
/**
* The suffix regexp of the kune url, to match /ws/ and /wse/ (embed) for
* instance.
*/
private static final String SUFFIX_REG_EXP = "/ws[e]*";
/** The config module. */
private final Module configModule;
/**
* Instantiates a new kune rack module.
*
*/
public KuneRackModule() {
configModule = new AbstractModule() {
@Override
public void configure() {
// Warning: parent instances (like Wave classes) are not intercepted.
// See: http://code.google.com/p/google-guice/issues/detail?id=461
bindInterceptor(Matchers.annotatedWith(LogThis.class), new NotInObject(),
new LoggerMethodInterceptor());
// if (sessionScope != null) {
// bindScope(SessionScoped.class, sessionScope);
// }
bind(UserSessionManager.class).to(UserSessionManagerImpl.class).in(Singleton.class);
bind(UsersOnline.class).to(UserSessionManagerImpl.class).asEagerSingleton();
requestStaticInjection(KuneWaveServerUtils.class);
requestStaticInjection(EventsServerConversionUtil.class);
requestStaticInjection(GroupServerUtils.class);
requestStaticInjection(I18n.class);
}
};
}
/*
* (non-Javadoc)
*
* @see
* cc.kune.core.server.rack.RackModule#configure(cc.kune.core.server.rack.
* RackBuilder)
*/
@Override
@SuppressWarnings("unchecked")
public void configure(final RackBuilder builder) {
installGuiceModules(builder);
builder.add(KuneContainerListener.class);
builder.add(WaveEmailNotifier.class);
builder.add(CronServerTasksManager.class);
builder.exclude("/http-bind.*");
builder.exclude("/public/.*");
builder.exclude("/images/.*");
builder.exclude("/stylesheets/.*");
builder.exclude("/javascripts/.*");
builder.exclude("/templates/.*");
/*
* Wave with context '/'. See {@link CustomServerMain}
*/
builder.exclude("/");
builder.exclude("/gadget/gadgetlist");
builder.exclude("/attachment/.*");
builder.exclude(AttachmentServlet.ATTACHMENT_URL + "/*");
builder.exclude(AttachmentServlet.THUMBNAIL_URL + "/*");
builder.exclude(AttachmentInfoServlet.ATTACHMENTS_INFO_URL);
builder.exclude(SessionManager.SIGN_IN_URL);
builder.exclude("/auth/signout");
builder.exclude("/auth/register");
builder.exclude("/locale/.*");
builder.exclude("/fetch/.*");
builder.exclude("/search/.*");
builder.exclude("/notification/.*");
builder.exclude("/robot/dataapi");
builder.exclude(DataApiOAuthServlet.DATA_API_OAUTH_PATH + "/.*");
builder.exclude("/robot/dataapi/rpc");
builder.exclude("/robot/register/.*");
builder.exclude("/robot/rpc");
builder.exclude("/webclient/remote_logging");
builder.exclude("/profile/.*");
builder.exclude("/iniavatars/.*");
builder.exclude("/waveref/.*");
builder.exclude(StatService.STAT_URL + "/.*");
builder.exclude("/gadgets");
builder.exclude("/gadgets/.*");
builder.exclude("/socket.io/*");
builder.exclude("/socket.io/.*]");
builder.exclude("/atmosphere*");
builder.exclude("/atmosphere.*");
builder.exclude("/socket");
builder.exclude("/static/.*");
builder.exclude("/webclient/.*");
builder.exclude("/initials/.*");
// builder.at(".*").install(new LogFilter());
builder.at(".*").install(new GuiceFilter());
// NOTE: Commented this while testing Wave
// builder.at("^/$").install(new RedirectFilter(KUNE_PREFIX + "/"));
builder.at("^" + SUFFIX).install(new RedirectFilter(SUFFIX + "/"));
builder.at("^" + EMBED_SUFFIX).install(new RedirectFilter(EMBED_SUFFIX + "/"));
builder.at("^" + SUFFIX + "/$").install(new ListenerFilter(KuneApplicationListener.class),
new ForwardFilter(SUFFIX + "/ws.html"));
builder.at("^" + EMBED_SUFFIX + "/$").install(new ListenerFilter(KuneApplicationListener.class),
new ForwardFilter(EMBED_SUFFIX + "/wse.html"));
builder.installGWTServices("^" + SUFFIX_REG_EXP + "/", SiteService.class, GroupService.class,
ContentService.class, UserService.class, SocialNetService.class, I18nService.class,
ListsService.class, ClientStatsService.class, InvitationService.class, UpDownService.class);
builder.installRESTServices("^" + SUFFIX_REG_EXP + "/json/", TestJSONService.class,
GroupJSONService.class, UserJSONService.class, I18nTranslationJSONService.class,
ContentJSONService.class);
builder.installCORSServices("^" + SUFFIX_REG_EXP + "/cors/", SiteCORSService.class,
ContentCORSService.class);
builder.installServlet("^" + SUFFIX_REG_EXP + "/servlets/", FileUploadManager.class,
FileDownloadManager.class, EntityLogoDownloadManager.class,
EntityBackgroundDownloadManager.class, EventsServlet.class);
builder.at("^" + SUFFIX + "/(.*)$").install(
new ForwardFilter("^" + SUFFIX + "/(.*)$", SUFFIX + "/{0}"));
builder.at("^" + EMBED_SUFFIX + "/(.*)$").install(
new ForwardFilter("^" + EMBED_SUFFIX + "/(.*)$", EMBED_SUFFIX + "/{0}"));
}
/**
* Install guice modules.
*
* @param builder
* the builder
*/
private void installGuiceModules(final RackBuilder builder) {
// https://code.google.com/p/google-guice/wiki/ServletModule
builder.use(new ServletModule() {
@Override
protected void configureServlets() {
final DataSourceKunePersistModule kuneDataSource = new DataSourceKunePersistModule();
install(kuneDataSource);
final KuneProperties kuneProperties = kuneDataSource.getKuneProperties();
final DataSourceOpenfirePersistModule openfireDataSource = new DataSourceOpenfirePersistModule(
kuneProperties);
install(openfireDataSource);
final KuneJpaLocalTxnInterceptor kuneJpaTxnInterceptor = kuneDataSource.getTransactionInterceptor();
// Warning: parent instances (like Wave classes) are not intercepted
// See: http://code.google.com/p/google-guice/issues/detail?id=461
// and https://code.google.com/p/google-guice/issues/detail?id=390
bindInterceptor(annotatedWith(KuneTransactional.class), any(), kuneJpaTxnInterceptor);
bindInterceptor(any(), annotatedWith(KuneTransactional.class), kuneJpaTxnInterceptor);
bindInterceptor(any(), annotatedWith(TestChildInterception.class), new TestChildInterceptor());
filter("/*").through(DataSourceKunePersistModule.MY_DATA_SOURCE_ONE_FILTER_KEY);
if (!kuneProperties.getBoolean(KuneProperties.SITE_OPENFIRE_IGNORE)) {
final OpenfireJpaLocalTxnInterceptor openfireJpaTxnInterceptor = openfireDataSource.getTransactionInterceptor();
bindInterceptor(annotatedWith(OpenfireTransactional.class), any(), openfireJpaTxnInterceptor);
bindInterceptor(any(), annotatedWith(OpenfireTransactional.class), openfireJpaTxnInterceptor);
filter("/*").through(DataSourceOpenfirePersistModule.MY_DATA_SOURCE_TWO_FILTER_KEY);
}
// As parent instances are not intercepted by Guice AOP we have to use
// the delegation pattern with a child so Wave instances are binded in
// the kune child injector (and intercepted)
bind(CustomPerUserWaveViewHandlerImpl.class).in(Singleton.class);
requestStaticInjection(CustomPerUserWaveViewHandler.class);
bind(CustomInitialsProfilesFetcherImpl.class).in(Singleton.class);
requestStaticInjection(CustomInitialsProfilesFetcher.class);
super.configureServlets();
}
});
builder.use(new PlatformServerModule());
builder.use(new DocumentServerModule());
builder.use(new WikiServerModule());
builder.use(new BlogServerModule());
builder.use(new EventsServerModule());
builder.use(new TaskServerModule());
builder.use(new ListsServerModule());
builder.use(new ChatServerModule());
builder.use(new BarterServerModule());
builder.use(new TrashServerModule());
// builder.use(new GalleryServerModule());
builder.use(new RESTServicesModule());
builder.use(configModule);
}
}