package org.exoplatform.platform.common.portlet;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import javax.portlet.PortletConfig;
import javax.portlet.PortletContext;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.filter.FilterChain;
import javax.portlet.filter.FilterConfig;
import javax.portlet.filter.RenderFilter;
import org.exoplatform.container.PortalContainer;
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.platform.common.module.ModuleRegistry;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
/**
* This portlet filter ensures that the portlet is active. To be active, a
* portlet must have its context name declared as a dependency of the
* current {@link PortalContainer}.
*/
public class PortletDisablerFilter implements RenderFilter {
private static final String PORTLET_DISABLED_DEFAULT_MESSAGE = "Portlet disabled.";
private static final String DISABLED_HTML_FILE_PATH = "war:/../portlet-disabled.html";
private static final Log LOG = ExoLogger.getExoLogger(PortletDisablerFilter.class);
private PortletContext context;
private String messageContent = null;
private ModuleRegistry moduleRegistry = null;
private Map<String, String> disabledPortletMessages = new HashMap<String, String>();
public void init(FilterConfig filterConfig) throws PortletException {
context = filterConfig.getPortletContext();
}
/**
* Serves a page with a message if the portlet is not a valid dependency
* of the current portal container.
*/
public void doFilter(RenderRequest request, RenderResponse response, FilterChain chain) throws IOException, PortletException {
PortletConfig portletConfig = (PortletConfig) request.getAttribute("javax.portlet.config");
String portletName = portletConfig.getPortletName();
String portletID = context.getPortletContextName() + "/" + portletName;
if (getModuleRegistry().isPortletActive(portletID)) {
chain.doFilter(request, response);
} else {
LOG.info("The portlet '" + portletID + "' is currently disabled.");
// Get the message from cache
String html = getPortletSpecificMessage(request, portletName, portletID);
response.getWriter().print(html);
}
}
public void destroy() {}
private String getPortletSpecificMessage(RenderRequest request, String portletName, String portletID) {
String html = disabledPortletMessages.get(portletID);
if (html == null || html.isEmpty()) {
String portletDisplayName = getModuleRegistry().getDisplayName(portletName, request.getLocale());
html = mergeDisabledContent(getModuleRegistry(), getDisablerMessage(), portletDisplayName, portletName, portletID);
disabledPortletMessages.put(portletID, html);
}
return html;
}
private String getDisablerMessage() {
if (messageContent == null || messageContent.isEmpty()) {
ConfigurationManager confManager = (ConfigurationManager) PortalContainer.getComponent(ConfigurationManager.class);
try {
InputStream inputStream = confManager.getInputStream(DISABLED_HTML_FILE_PATH);
messageContent = convertStreamToString(inputStream);
} catch (Exception exception) {
messageContent = PORTLET_DISABLED_DEFAULT_MESSAGE;
LOG.error("Cannot read message for disabled portlet", exception);
}
}
return messageContent;
}
/**
* Replace some variables into HTML content
*
* @param content
* @return specific message for the selected portlet, after some
* replacements
*/
private String mergeDisabledContent(ModuleRegistry moduleRegistry, String content, String portletDisplayName,
String portletName, String portletID) {
String result = content;
result = result.replaceAll("ACTIVE_PROFILES", PortalContainer.getProfiles().toString());
result = result.replaceAll("APP_NAME", portletDisplayName);
result = result.replaceAll("APP_ID", portletName);
//result = result.replaceAll("PROFILE", moduleRegistry.getModulesForPortlet(portletID).toString());
result = result.replaceAll("PROFILE", "all");
return result;
}
/**
* @param is
* the InputStream
* @return the String content of the input stream
* @throws IOException
*/
private String convertStreamToString(InputStream is) throws IOException {
/*
* To convert the InputStream to String we use the Reader.read(char[]
* buffer) method. We iterate until the Reader return -1 which means
* there's no more data to read. We use the StringWriter class to
* produce the string.
*/
if (is != null) {
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
} finally {
is.close();
}
return writer.toString();
} else {
return "";
}
}
/**
* @return ModuleRegistry component
*/
private ModuleRegistry getModuleRegistry() {
if (moduleRegistry == null) {
moduleRegistry = (ModuleRegistry) PortalContainer.getComponent(ModuleRegistry.class);
}
return moduleRegistry;
}
}