com.manydesigns.portofino.modules.PageactionsModule Maven / Gradle / Ivy
/*
* Copyright (C) 2005-2017 ManyDesigns srl. All rights reserved.
* http://www.manydesigns.com/
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package com.manydesigns.portofino.modules;
import com.manydesigns.elements.util.ElementsFileUtils;
import com.manydesigns.portofino.PortofinoProperties;
import com.manydesigns.portofino.cache.CacheResetEvent;
import com.manydesigns.portofino.cache.CacheResetListener;
import com.manydesigns.portofino.cache.CacheResetListenerRegistry;
import com.manydesigns.portofino.di.Inject;
import com.manydesigns.portofino.dispatcher.DispatcherLogic;
import com.manydesigns.portofino.pageactions.activitystream.ActivityStreamAction;
import com.manydesigns.portofino.pageactions.custom.CustomAction;
import com.manydesigns.portofino.pageactions.form.FormAction;
import com.manydesigns.portofino.pageactions.form.TableFormAction;
import com.manydesigns.portofino.pageactions.registry.PageActionRegistry;
import com.manydesigns.portofino.pageactions.registry.TemplateRegistry;
import com.manydesigns.portofino.pageactions.text.TextAction;
import com.manydesigns.portofino.shiro.SecurityGroovyRealm;
import groovy.util.GroovyScriptEngine;
import net.sf.ehcache.CacheManager;
import org.apache.commons.configuration.Configuration;
import org.apache.shiro.mgt.RealmSecurityManager;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.util.LifecycleUtils;
import org.apache.shiro.web.env.EnvironmentLoader;
import org.apache.shiro.web.env.WebEnvironment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletContext;
import java.io.File;
/*
* @author Paolo Predonzani - [email protected]
* @author Angelo Lupo - [email protected]
* @author Giampiero Granatella - [email protected]
* @author Alessio Stalla - [email protected]
*/
public class PageactionsModule implements Module {
public static final String copyright =
"Copyright (C) 2005-2017 ManyDesigns srl";
//**************************************************************************
// Fields
//**************************************************************************
@Inject(BaseModule.SERVLET_CONTEXT)
public ServletContext servletContext;
@Inject(BaseModule.PORTOFINO_CONFIGURATION)
public Configuration configuration;
@Inject(BaseModule.APPLICATION_DIRECTORY)
public File applicationDirectory;
@Inject(BaseModule.GROOVY_SCRIPT_ENGINE)
public GroovyScriptEngine groovyScriptEngine;
@Inject(BaseModule.GROOVY_CLASS_PATH)
public File groovyClasspath;
@Inject(BaseModule.CACHE_RESET_LISTENER_REGISTRY)
public CacheResetListenerRegistry cacheResetListenerRegistry;
protected EnvironmentLoader environmentLoader = new EnvironmentLoader();
protected CacheManager cacheManager;
protected ModuleStatus status = ModuleStatus.CREATED;
//**************************************************************************
// Constants
//**************************************************************************
public static final String PAGES_DIRECTORY = "PAGES_DIRECTORY";
public static final String EHCACHE_MANAGER = "portofino.ehcache.manager";
public static final String PAGE_ACTIONS_REGISTRY =
"com.manydesigns.portofino.pageactions.registry.PageActionRegistry";
public static final String TEMPLATES_REGISTRY =
"com.manydesigns.portofino.pageactions.templates.registry";
//**************************************************************************
// Logging
//**************************************************************************
public static final Logger logger =
LoggerFactory.getLogger(PageactionsModule.class);
@Override
public String getModuleVersion() {
return ModuleRegistry.getPortofinoVersion();
}
@Override
public int getMigrationVersion() {
return 1;
}
@Override
public double getPriority() {
return 10;
}
@Override
public String getId() {
return "pageactions";
}
@Override
public String getName() {
return "Pageactions";
}
@Override
public int install() {
return 1;
}
@Override
public void init() {
logger.debug("Initializing dispatcher");
DispatcherLogic.init(configuration);
logger.info("Initializing ehcache service");
cacheManager = CacheManager.newInstance();
servletContext.setAttribute(EHCACHE_MANAGER, cacheManager);
File pagesDirectory = new File(applicationDirectory, "pages");
logger.info("Pages directory: " + pagesDirectory);
ElementsFileUtils.ensureDirectoryExistsAndWarnIfNotWritable(pagesDirectory);
if(configuration.getBoolean(PortofinoProperties.GROOVY_PRELOAD_PAGES, false)) {
logger.info("Preloading pages");
preloadPageActions(pagesDirectory);
}
if(configuration.getBoolean(PortofinoProperties.GROOVY_PRELOAD_CLASSES, false)) {
logger.info("Preloading Groovy classes");
preloadGroovyClasses(groovyClasspath);
}
servletContext.setAttribute(PAGES_DIRECTORY, pagesDirectory);
logger.debug("Creating pageactions registry");
PageActionRegistry pageActionRegistry = new PageActionRegistry();
pageActionRegistry.register(ActivityStreamAction.class);
pageActionRegistry.register(CustomAction.class);
pageActionRegistry.register(FormAction.class);
pageActionRegistry.register(TableFormAction.class);
pageActionRegistry.register(TextAction.class);
servletContext.setAttribute(PAGE_ACTIONS_REGISTRY, pageActionRegistry);
servletContext.setAttribute(TEMPLATES_REGISTRY, new TemplateRegistry());
cacheResetListenerRegistry.getCacheResetListeners().add(new ConfigurationCacheResetListener());
status = ModuleStatus.ACTIVE;
}
protected void preloadPageActions(File directory) {
for(File file : directory.listFiles()) {
logger.debug("visit {}", file);
if(file.isDirectory()) {
if(!file.equals(directory) && !file.equals(directory.getParentFile())) {
preloadPageActions(file);
}
} else if("action.groovy".equals(file.getName())) {
logger.debug("Preloading page: {}", file);
try {
Class> clazz = DispatcherLogic.getActionClass(configuration, directory);
clazz.newInstance();
} catch(Throwable t) {
logger.warn("PageAction preload failed for page " + file.getAbsolutePath(), t);
}
}
}
}
protected void preloadGroovyClasses(File directory) {
for(File file : directory.listFiles()) {
logger.debug("visit {}", file);
if(file.isDirectory()) {
if(!file.equals(directory) && !file.equals(directory.getParentFile())) {
preloadGroovyClasses(file);
}
} else {
String scriptName = file.toURI().toString();
logger.debug("Preloading " + scriptName);
try {
groovyScriptEngine.loadScriptByName(scriptName);
} catch(Throwable t) {
logger.warn("Groovy class preload failed for " + scriptName, t);
}
}
}
}
@Override
public void start() {
logger.info("Initializing Shiro environment");
WebEnvironment environment = environmentLoader.initEnvironment(servletContext);
RealmSecurityManager rsm = (RealmSecurityManager) environment.getWebSecurityManager();
logger.debug("Creating SecurityGroovyRealm");
try {
String securityGroovy = new File(groovyClasspath, "Security.groovy").toURI().toString();
logger.debug("Security.groovy URL: {}", securityGroovy);
SecurityGroovyRealm realm = new SecurityGroovyRealm(groovyScriptEngine, securityGroovy, servletContext);
LifecycleUtils.init(realm);
rsm.setRealm(realm);
status = ModuleStatus.STARTED;
} catch (Exception e) {
logger.error("Security.groovy not found or invalid; installing dummy realm", e);
SimpleAccountRealm realm = new SimpleAccountRealm();
LifecycleUtils.init(realm);
rsm.setRealm(realm);
status = ModuleStatus.FAILED;
}
}
@Override
public void stop() {
status = ModuleStatus.STOPPED;
}
@Override
public void destroy() {
logger.info("Destroying Shiro environment...");
environmentLoader.destroyEnvironment(servletContext);
logger.info("Shutting down cache...");
cacheManager.shutdown();
status = ModuleStatus.DESTROYED;
}
@Override
public ModuleStatus getStatus() {
return status;
}
private static class ConfigurationCacheResetListener implements CacheResetListener {
@Override
public void handleReset(CacheResetEvent e) {
DispatcherLogic.clearConfigurationCache();
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy