CombineAttributeModelProcessor.java
package sk.iway.iwcm.system.spring.webjet_component.dialect;
import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.model.IModel;
import org.thymeleaf.model.IModelFactory;
import org.thymeleaf.model.IOpenElementTag;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.model.IStandaloneElementTag;
import org.thymeleaf.model.ITemplateEvent;
import sk.iway.iwcm.Constants;
import sk.iway.iwcm.Logger;
import sk.iway.iwcm.Tools;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* Trieda CombineAttributeTagProcessor pre iwcm tag s nazvom combine
* Tag <combine data-iwcm-combine=""/> sluzi na vlozenie JS a CSS do sablon
* parsuje aj BODY tagu, kde hlada script a link tagy a berie z nich linky
* je to tak preto, aby sa to dalo pouzit aj bez WJ s npm run start
*/
public class CombineAttributeModelProcessor extends AbstractIwcmAttributeModelProcessor {
private static final String ATTR_NAME = "combine";
private static final int PRECEDENCE = 10002;
public CombineAttributeModelProcessor(String dialectPrefix) {
super(dialectPrefix, ATTR_NAME, PRECEDENCE);
}
@Override
protected void processTag(ITemplateContext context, IModel model, IProcessableElementTag baseTag, HttpServletRequest request) {
final IModelFactory modelFactory = context.getModelFactory();
//zozbieraj zoznam liniek
List<String> links = new ArrayList<>();
for (int i=0; i<model.size(); i++) {
final ITemplateEvent event = model.get(i);
//Logger.debug(CombineAttributeModelProcessor.class, "event="+event);
if (event instanceof IStandaloneElementTag) {
IStandaloneElementTag tag = (IStandaloneElementTag)event;
if ("link".equalsIgnoreCase(tag.getElementCompleteName())) {
links.add(tag.getAttributeValue("href"));
}
} else if (event instanceof IOpenElementTag) {
IOpenElementTag tag = (IOpenElementTag)event;
if ("script".equalsIgnoreCase(tag.getElementCompleteName())) {
links.add(tag.getAttributeValue("src"));
}
}
}
model.reset();
//mame zoznam liniek vnutri v tagu
//Logger.debug(CombineAttributeModelProcessor.class, "======> LINKS.size="+links.size()+" words="+request.getParameter("words"));
String lng = ProcessorTools.getLng(request);
boolean combine = isCombine(request);
long v = ProcessorTools.getVersion();
List<String> set = getSetFiles(baseTag, context, request, links);
if (set == null || set.isEmpty()) {
Logger.error(CombineAttributeModelProcessor.class, "Set is null");
return;
}
// pridanie systemovych JS A CSS suborov
set = addSystemFiles(set);
// vyfiltrovanie CSS suborov
List<String> css = set.stream().filter(s -> s.endsWith(".css")).collect(Collectors.toList());
// vyfiltrovanie JS suborov
List<String> js = set.stream().filter(s -> s.endsWith(".js") || s.endsWith(".js.jsp")).collect(Collectors.toList());
// ak je povoleny combine
if (combine) {
if (!css.isEmpty()) {
addCssTag(model, modelFactory, "/components/_common/combine.jsp?t=css&f="+String.join(",", css)+"&v="+v+"&lng="+lng);
}
if (!js.isEmpty()) {
addScriptTag(model, modelFactory, "/components/_common/combine.jsp?t=js&f="+String.join(",", js)+"&v="+v+"&lng="+lng);
}
}
// ak nie je povoleny combine
else
{
if (!css.isEmpty()) {
for (String s : css) {
addCssTag(model, modelFactory, s+"?v="+v+"&lng="+lng);
}
}
if (!js.isEmpty()) {
for (String s : js) {
addScriptTag(model, modelFactory, s+"?v="+v+"&lng="+lng);
}
}
}
}
/**
* Metoda pre pridanie systemovych suborov do zoznamu na vlozenie
* @param set List<String>
* @return List<String>
*/
private static List<String> addSystemFiles(List<String> set) {
List<String> result = new ArrayList<>();
for (String s : set) {
// pridanie combine soborov z konstanty
String constValue = Constants.getString("combine-" + s);
if (Tools.isNotEmpty(constValue)) {
result.add(constValue);
continue;
}
result.add(s);
}
return result;
}
/**
* Metoda pre overenie ci je povolene kombinovat subory cez combine.jsp
* @param request HttpServletRequest
* @return boolean
*/
private static boolean isCombine(HttpServletRequest request) {
boolean combine = true;
if ("false".equals(request.getParameter("combineEnabled")))
{
combine = false;
request.getSession().setAttribute("combineEnabled", "false");
}
if ("true".equals(request.getParameter("combineEnabled")))
{
combine = true;
request.getSession().removeAttribute("combineEnabled");
}
if (request.getSession().getAttribute("combineEnabled")!=null) combine = false;
return combine;
}
/**
* Metoda pre ziskanie suborov na vlozenie
* @return List<String>
*/
private static List<String> getSetFiles(IProcessableElementTag combineTag, ITemplateContext context, HttpServletRequest request, List<String> bodyLinks) {
final String basePath = ProcessorTools.getAttributeValue(combineTag, context, "basePath");
final String baseCss = (String)request.getAttribute("base_css_link_nocombine");
final String cssLink = (String)request.getAttribute("css_link_nocombine");
String combineAttribute = ProcessorTools.getAttributeValue(combineTag, context, "data-iwcm-combine");
List<String> list = new ArrayList<>();
//prve musia ist body linky, tam je typicky jquery
list.addAll(bodyLinks);
//az potom specificke pre WJ
list.addAll(Tools.getStringListValue(Tools.getTokens(combineAttribute, "\n")));
list = list.stream().map(l -> {
l = removeCrLf(l.trim());
l = Tools.replace(l, "USERLANG", Tools.replace(ProcessorTools.getLng(request), "cz", "cs"));
if (Tools.isNotEmpty(baseCss) && l.contains("base_css_link")) {
l = Tools.replace(l, "base_css_link", removeCrLf(baseCss));
}
if (Tools.isNotEmpty(cssLink) && l.contains("css_link")) {
l = Tools.replace(l, "css_link", removeCrLf(cssLink));
}
if (Tools.isNotEmpty(basePath) && (l.endsWith(".js") || l.endsWith(".css"))) {
if (l.startsWith(basePath)==false && l.startsWith("/templates/")==false) l = basePath + l;
}
if (l.contains("page_functions")) {
//ak obsahuje page_functions predpokladame, ze je uz vlozene aj jQuery, musime poznacit aby sa nevlozilo pri doc_data
Tools.insertJQuery(request);
}
return l;
}).collect(Collectors.toList());
return list;
}
/**
* Metoda pre odstranenie nechcenych znakov z vyrazu
* @param str String
* @return String
*/
private static String removeCrLf(String str)
{
String result = Tools.replace(str, "\n", ",");
result = Tools.replace(result, "\r", "");
result = Tools.replace(result, " ", "");
result = Tools.replace(result, "\t", "");
result = Tools.replace(result, ",,", ",");
//ked nie je pagefunctions na konci a je to vlozene cez EL tak sa spojja dve dokopy (odstrani sa enter) a vtedy sa to posaha
result = Tools.replace(result, "page_functions.js.jsp/", "page_functions.js.jsp,/");
return result;
}
}