com.github.dandelion.datatables.thymeleaf.processor.TableFinalizerElProcessor Maven / Gradle / Ivy
package com.github.dandelion.datatables.thymeleaf.processor;
import java.io.IOException;
import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.thymeleaf.Arguments;
import org.thymeleaf.context.IWebContext;
import org.thymeleaf.dom.Element;
import org.thymeleaf.dom.Node;
import org.thymeleaf.dom.Text;
import org.thymeleaf.processor.IElementNameProcessorMatcher;
import org.thymeleaf.processor.ProcessorResult;
import org.thymeleaf.processor.element.AbstractElementProcessor;
import com.github.dandelion.datatables.core.aggregator.ResourceAggregator;
import com.github.dandelion.datatables.core.cache.AssetCache;
import com.github.dandelion.datatables.core.compressor.ResourceCompressor;
import com.github.dandelion.datatables.core.constants.CdnConstants;
import com.github.dandelion.datatables.core.constants.ExportConstants;
import com.github.dandelion.datatables.core.exception.BadConfigurationException;
import com.github.dandelion.datatables.core.exception.CompressionException;
import com.github.dandelion.datatables.core.exception.DataNotFoundException;
import com.github.dandelion.datatables.core.exception.ExportException;
import com.github.dandelion.datatables.core.export.ExportDelegate;
import com.github.dandelion.datatables.core.export.ExportProperties;
import com.github.dandelion.datatables.core.export.ExportType;
import com.github.dandelion.datatables.core.feature.FilteringFeature;
import com.github.dandelion.datatables.core.generator.WebResourceGenerator;
import com.github.dandelion.datatables.core.model.CssResource;
import com.github.dandelion.datatables.core.model.HtmlColumn;
import com.github.dandelion.datatables.core.model.HtmlTable;
import com.github.dandelion.datatables.core.model.JsResource;
import com.github.dandelion.datatables.core.model.WebResources;
import com.github.dandelion.datatables.core.util.DandelionUtils;
import com.github.dandelion.datatables.core.util.RequestHelper;
import com.github.dandelion.datatables.thymeleaf.util.DomUtils;
import com.github.dandelion.datatables.thymeleaf.util.Utils;
/**
*
* Element processor applied to the internal HTML div
tag.
*
* The div
is added by the TableInitializerProcessor after the
* table
in order to be processed after all the "table" processors.
*
* @author Thibault Duchateau
*/
public class TableFinalizerElProcessor extends AbstractElementProcessor {
// Logger
private static Logger logger = LoggerFactory.getLogger(TableFinalizerElProcessor.class);
private HtmlTable htmlTable;
public TableFinalizerElProcessor(IElementNameProcessorMatcher matcher) {
super(matcher);
}
@Override
public int getPrecedence() {
return 50000;
}
@Override
protected ProcessorResult processElement(Arguments arguments, Element element) {
// Get the HTTP request
HttpServletRequest request = ((IWebContext) arguments.getContext()).getHttpServletRequest();
this.htmlTable = Utils.getTable(arguments);
if (this.htmlTable != null) {
// The table is being exported
if (RequestHelper.isTableBeingExported(request, this.htmlTable)) {
setupExport(arguments);
}
// The table must be generated and displayed
else {
setupHtmlGeneration(arguments, element, request);
}
}
// The "finalizing div" can now be removed
element.getParent().removeChild(element);
return ProcessorResult.OK;
}
private void registerFeatures(Element element, Arguments arguments, HtmlTable htmlTable) {
if (htmlTable.hasOneFilterableColumn()) {
logger.info("Feature detected : select with filter");
// Duplicate header row in the footer
generateFooter(element, arguments);
htmlTable.registerFeature(new FilteringFeature());
}
}
/**
* Set up the export properties, before the filter intercepts the response.
*/
private void setupExport(Arguments arguments) {
logger.debug("Setting export up ...");
HttpServletRequest request = ((IWebContext) arguments.getContext()).getHttpServletRequest();
HttpServletResponse response = ((IWebContext) arguments.getContext())
.getHttpServletResponse();
// Init the export properties
ExportProperties exportProperties = new ExportProperties();
ExportType currentExportType = getCurrentExportType(request);
exportProperties.setCurrentExportType(currentExportType);
exportProperties.setExportConf(this.htmlTable.getExportConfMap().get(currentExportType));
exportProperties.setFileName(this.htmlTable.getExportConfMap().get(currentExportType)
.getFileName());
this.htmlTable.setExportProperties(exportProperties);
this.htmlTable.setExporting(true);
try {
// Call the export delegate
ExportDelegate exportDelegate = new ExportDelegate(this.htmlTable, exportProperties,
request);
exportDelegate.launchExport();
} catch (ExportException e) {
logger.error("Something went wront with the Dandelion-datatables export configuration.");
e.printStackTrace();
}
response.reset();
}
/**
* Set up the HTML table generation.
*/
private void setupHtmlGeneration(Arguments arguments, Element element,
HttpServletRequest request) {
WebResources webResources = null;
this.htmlTable.setExporting(false);
// Plugins and themes are activated in their respective attribute
// processor
// Register all activated features
registerFeatures(element, arguments, this.htmlTable);
try {
// First we check if the DataTables configuration already exist in the cache
String keyToTest = RequestHelper.getCurrentUrl(request) + "|" + htmlTable.getId();
if(DandelionUtils.isDevModeEnabled() || !AssetCache.cache.containsKey(keyToTest)){
logger.debug("No asset for the key {}. Generating...", keyToTest);
// Init the web resources generator
WebResourceGenerator contentGenerator = new WebResourceGenerator();
// Generate the web resources (JS, CSS) and wrap them into a
// WebResources POJO
webResources = contentGenerator.generateWebResources(htmlTable);
logger.debug("Web content generated successfully");
AssetCache.cache.put(keyToTest, webResources);
logger.debug("Cache updated with new web resources");
}
else{
logger.debug("Asset(s) already exist, retrieving content from cache...");
webResources = (WebResources) AssetCache.cache.get(keyToTest);
}
// Aggregation
if (htmlTable.getTableProperties().isAggregatorEnable()) {
logger.debug("Aggregation enabled");
ResourceAggregator.processAggregation(webResources, htmlTable);
}
// Compression
if (htmlTable.getTableProperties().isCompressorEnable()) {
logger.debug("Compression enabled");
ResourceCompressor.processCompression(webResources, htmlTable);
}
// HTML tag generation
if (htmlTable.getCdn() != null && htmlTable.getCdn()) {
DomUtils.addLinkTag(DomUtils.getParentAsElement(element), request,
CdnConstants.CDN_DATATABLES_CSS);
}
for (Entry entry : webResources.getStylesheets().entrySet()) {
DomUtils.addLinkTag(element, request, Utils.getBaseUrl(request)
+ "/datatablesController/" + entry.getKey() + "?id=" + htmlTable.getId() + "&c=" + RequestHelper.getCurrentUrl(request));
}
//