package com.xnx3.template; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Vector; import javax.swing.DefaultCellEditor; import javax.swing.JComboBox; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableColumn; import net.sf.json.JSONObject; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import com.xnx3.DateUtil; import com.xnx3.Lang; import com.xnx3.UI; import com.xnx3.exception.NotReturnValueException; import com.xnx3.file.FileUtil; import com.xnx3.template.Global; import com.xnx3.template.bean.ElementDiffRecord; import com.xnx3.template.bean.Template; import com.xnx3.template.ui.Diff; import com.xnx3.template.ui.diffJeditorPanel; import com.xnx3.template.vo.ElementDiffListVO; import com.xnx3.template.vo.ElementDiffVO; import com.xnx3.util.StringDiff; import com.xnx3.util.StringUtil; /** * 其他的一些动作 * @author 管雷鸣 */ public class Action { /** * 加载本地模版 */ public static void loadLocalTemplate(String templateFilePath){ System.out.println("加载本地模版 : "+ templateFilePath); Global.templateMap.clear(); /**加载本地的模板**/ File file = new File(templateFilePath); for (int i = 0; i < file.listFiles().length; i++) { File f = file.listFiles()[i]; if(f.isFile()){ //如果是文件 if(f.getName().indexOf(".html") > 0){ //找出所有的html模板文件 //读取模板文件加载 Template temp = new Template(); temp.setFile(f); String html = FileUtil.read(f.getPath(), FileUtil.UTF8); // temp.setDoc(Jsoup.parse(html)); try { temp.setDoc(Jsoup.parse(f, "UTF-8")); } catch (IOException e) { e.printStackTrace(); } // templateList.add(temp); Global.templateMap.put(f.getName(), temp); } } } //将之前的在table中的清空掉 Global.mainUI.getTemplatePageTableModel().setRowCount( 0 ); //将新的加入进table中 for (Map.Entry<String, Template> entry : Global.templateMap.entrySet()) { Template temp = entry.getValue(); Vector rowData = new Vector(); rowData.add(temp.getFile().getName()); rowData.add("请选择"); rowData.add("备注"); Global.mainUI.getTemplatePageTableModel().insertRow(0, rowData); } for (int i = 0; i < Global.mainUI.getTemplatePageTableModel().getRowCount(); i++) { JComboBox<String> jcb = new JComboBox<String>(); jcb.addItem("首页模版"); jcb.addItem("列表页模版"); jcb.addItem("详情页模版"); jcb.setEditable(true); TableColumn tableColumn = Global.mainUI.getTemplatePageJTable().getColumnModel().getColumn(1); tableColumn.setCellEditor(new DefaultCellEditor(jcb)); } } /** * 替换模版源代码,将资源引用的相对路径改为绝对路径 */ public static void replaceResourceQuote(){ for (Map.Entry<String, Template> entry : Global.templateMap.entrySet()) { Template temp = entry.getValue(); Document doc = temp.getDoc(); String baseUri = Global.mainUI.getTextArea_ResourceUrl().getText().trim(); if(baseUri == null){ UI.showMessageDialog("请先输入资源路径"); return; } if(baseUri.lastIndexOf("/")+1 == baseUri.length()){ baseUri = baseUri.substring(0, baseUri.length()-1); } ResourceQuote rq = new ResourceQuote(baseUri); doc = rq.tagReplace(doc, "img", "src"); doc = rq.tagReplace(doc, "link", "href"); doc = rq.tagReplace(doc, "script", "src"); String html = rq.htmlFilter(doc.toString(), "src=\"(.*?)\""); html = rq.htmlFilter(html, "background-image: *url\\('*(.*?)'*\\)"); temp.setDoc(Jsoup.parse(html)); Global.templateMap.put(temp.getFile().getName(), temp); // FileUtil.write(temp.getFile(), html); } } /** * 人工比对,比对极其相似的模版变量 */ public static void previewDiffUI(ElementDiffListVO vo){ //找出的完全相同的 key:file.name Map<String, ElementDiffVO> equalMap = new HashMap<String, ElementDiffVO>(); //找出不完全相同,但是绝大多数相同的 Map<String, ElementDiffVO> similarMap = new HashMap<String, ElementDiffVO>(); try { for (int i = 0; i < vo.getList().size(); i++) { ElementDiffVO ed = vo.getList().get(i); if(ed.getD() == 1){ equalMap.put(ed.getTargetFile().getName(), ed); }else if (ed.getD() >= Global.sim) { similarMap.put(ed.getTargetFile().getName(), ed); } } } catch (Exception e) { e.printStackTrace(); } if(similarMap.size() == 0 ){ //根本没有相似的要进行对比,退出判断 return; } //判断一下,是完全相同的数量多,还是极近相同的多 if(similarMap.size() > equalMap.size()){ //极近相同的多,那么,对比一下这些极近相同的里面,是否这些是一样的,而完全相同的只是个例而已 /* * */ System.out.println("极近相同的多,那么,对比一下这些极近相同的里面,是否这些是一样的,而完全相同的只是个例而已"); } //进行相似度diff展示 /** diff第一个 **/ String fileNames1 = ""; Element firstElement = null; for (Map.Entry<String, ElementDiffVO> entry : equalMap.entrySet()) { fileNames1 = fileNames1 + entry.getKey()+", "; if(firstElement == null){ firstElement = entry.getValue().getTargetElement(); } } Diff d = new Diff(); diffJeditorPanel item1 = new diffJeditorPanel(); item1.getLblNewLabel().setText(fileNames1); item1.originalElement = firstElement; /** diff其他不相似的列表 **/ for (Map.Entry<String, ElementDiffVO> entry : similarMap.entrySet()) { StringDiff sd = new StringDiff(firstElement.toString(), entry.getValue().getTargetElement().toString()); diffJeditorPanel jp = new diffJeditorPanel(); jp.getEditorPane().setText(sd.getTwoStrDiff()); jp.getLblNewLabel().setText(entry.getValue().getTargetFile().getName()); jp.originalElement = entry.getValue().getTargetElement(); d.getContentPane().add(jp); //将两个对比的字符串合并,然后去空格。判断其是否包含特殊符号等,如果不全是汉字或英文及数字,那么返回false,即不能合并 String diffOriginalStr = (sd.getFirstStrOriginalDiff()+sd.getTwoStrOriginalDiff()).replaceAll(" ", ""); //对比取得的原始的不相同的字符串 System.out.println("diff----"+diffOriginalStr); if(StringUtil.isChinese(diffOriginalStr)){ //true,那么可以合并! Template temp = Global.templateMap.get(entry.getValue().getTargetFile().getName()); String html = temp.getDoc().toString().replace(entry.getValue().getTargetElement().toString(), entry.getValue().getDiffElement().toString()); try { FileUtil.write(temp.getFile().getPath(), html, FileUtil.UTF8); temp.setDoc(Jsoup.parse(html)); System.out.println("已经替换:"+StringUtil.purification(entry.getValue().getTargetElement().toString())); Global.templateMap.put(temp.getFile().getName(), temp); } catch (IOException e1) { e1.printStackTrace(); } // entry.getValue().getTargetFile(). }else{ System.out.println("不可合并:"+StringUtil.purification(entry.getValue().getTargetElement().toString())); } item1.getEditorPane().setText(sd.getFirstStrDiff()); } d.getContentPane().add(item1); d.setVisible(true); } /** * 计算以下,是否有必要进行人工干预diff * @return int[] int[0]:完全相同的变量的数量, int[1]:非常相近的变量的数量 */ public static int[] isPreviewDiff(ElementDiffListVO vo){ int result[] = new int[3]; //找出的完全相同的 key:file.name Map<String, ElementDiffVO> equalMap = new HashMap<String, ElementDiffVO>(); //找出不完全相同,但是绝大多数相同的 Map<String, ElementDiffVO> similarMap = new HashMap<String, ElementDiffVO>(); try { for (int i = 0; i < vo.getList().size(); i++) { ElementDiffVO ed = vo.getList().get(i); if(ed.getD() == 1){ equalMap.put(ed.getTargetFile().getName(), ed); }else if (ed.getD() >= Global.sim) { similarMap.put(ed.getTargetFile().getName(), ed); } } } catch (Exception e) { e.printStackTrace(); } result[0] = equalMap.size(); result[1] = similarMap.size(); return result; } /** * 导出.wscso模版文件 */ public static void exportTemplate(){ /* * 遍历出模版变量 */ Map<String, ElementDiffRecord> templateVarVOMap = new HashMap<String, ElementDiffRecord>(); //存储的是ElementDiffRecord对象。 key:变量名字(JTable重新命名的)。 此在模版页面中将变量替换为{include}时用到 List<Map<String, String>> templateVarList = new ArrayList<Map<String,String>>(); //存储的是直接变为json的变量内容 DefaultTableModel varModel = Global.mainUI.getTemplateVarTableModel(); int varRowCount = varModel.getRowCount(); for (int i = 0; i < varRowCount; i++) { Map<String, String> map = new HashMap<String, String>(); //模版变量名字 String name = (String) varModel.getValueAt(i, 0); if(name != null && name.length() > 0){ map.put("var_name", exportTemplateStringDispose(name)); map.put("remark", exportTemplateStringDispose((String)varModel.getValueAt(i, 5))); map.put("text", exportTemplateStringDispose(Global.templateVarMap.get(name).getElementDiffVO().getDiffElement().toString())); templateVarList.add(map); templateVarVOMap.put(name, Global.templateVarMap.get(name)); writeTemplateFile("var_"+name, Global.templateVarMap.get(name).getElementDiffVO().getDiffElement().toString()); //本地写出文件 } } /* * 遍历出模版页面 */ List<Map<String, String>> templatePageList = new ArrayList<Map<String,String>>(); DefaultTableModel pageModel = Global.mainUI.getTemplatePageTableModel(); int pageRowCount = pageModel.getRowCount(); for (int i = 0; i < pageRowCount; i++) { Map<String, String> map = new HashMap<String, String>(); //模版页面名字 String name = (String) pageModel.getValueAt(i, 0); if(name != null && name.length() > 0){ String templatePageName = name; if(name.indexOf(".") > 0){ //如果是index.html这样的,那么过滤掉后面的后缀 templatePageName = name.split("\\.")[0]; } map.put("name", exportTemplateStringDispose(templatePageName)); //模版页面备注 map.put("remark", exportTemplateStringDispose((String) pageModel.getValueAt(i, 2))); String type = (String) pageModel.getValueAt(i, 1); switch (type) { case "首页模版": type = "1"; break; case "列表页模版": type = "2"; break; case "详情页模版": type = "3"; break; default: type = "3"; break; } map.put("type", type); String tihuanmobanbianliangdepage = templatePageReplaceVar(name, templateVarVOMap); map.put("text", exportTemplateStringDispose(tihuanmobanbianliangdepage)); map.put("editMode", "2"); templatePageList.add(map); writeTemplateFile("page_"+templatePageName, tihuanmobanbianliangdepage); //本地写出文件 } } JSONObject jo = new JSONObject(); jo.put("systemVersion", exportTemplateStringDispose(Global.VERSION)); // 当前系统版本号 jo.put("time", DateUtil.timeForUnix10()); //导出的时间,10为时间戳 jo.put("templateName", exportTemplateStringDispose(Global.mainUI.getTextField_templateName().getText())); //当前模版的名字 jo.put("sourceUrl", ""); //模版来源的网站,从那个网站导出来的,可以作为预览网站 jo.put("useUtf8Encode", "true"); jo.put("templatePageList", templatePageList); jo.put("templateVarList", templateVarList); //将.wscso模版文件保存到当前项目文件夹 FileUtil.write(Global.getAppPath()+getTemplatePathName()+"/template.wscso", jo.toString()); try { java.awt.Desktop.getDesktop().open(new File(Global.getAppPath()+getTemplatePathName()+"/")); } catch (IOException e) { e.printStackTrace(); } } /** * 在app跟目录写出模版文件 * @param fileName 文件名字 * @param text 文件内容 */ public static void writeTemplateFile(String fileName, String text){ File file = new File(Global.getAppPath()+getTemplatePathName()+"/"); if(!file.exists()){ file.mkdir(); } FileUtil.write(Global.getAppPath()+getTemplatePathName()+"/"+fileName+".html", text); } /** * 将模版页面替换上模版变量,即用{include=??}替换上 * @param tempaltePageName 要进行抽取替换的模版页面的名字,Jtable的名字,如index.html * @param templateVarVOMap 当前提取好的模版变量,要保存为模版的模版变量 */ public static String templatePageReplaceVar(String tempaltePageName, Map<String, ElementDiffRecord> templateVarVOMap){ if(Global.templateMap.get(tempaltePageName) == null){ System.err.println("----------null------"+tempaltePageName); return ""; } Document doc = Jsoup.parse(Global.templateMap.get(tempaltePageName).getDoc().toString()); //当前模版页面所使用的模版变量的名字。会在下面for中判断出 List<String> haveVarNameList = new ArrayList<String>(); //遍历当前的模版变量,将页面中,每个模版变量都找一遍 for (Map.Entry<String, ElementDiffRecord> entry : templateVarVOMap.entrySet()) { ElementDiffRecord record = entry.getValue(); String varName = entry.getKey(); //变量名 ElementDiffVO diffVO = null; //当前模版页面中,拿来对比的元素 for (int i = 0; i < record.getElementDiffListVO().getList().size(); i++) { ElementDiffVO edVO = record.getElementDiffListVO().getList().get(i); if(edVO.getTargetFile().getName().equals(tempaltePageName)){ //针对遍历的某个变量,找到其在 tempaltePageName 这个模版页面中的记录。当然, 若找不到记录,那就是这个模版页面没有使用这个变量,忽略即可 if(edVO.getD() >= Global.sim){ //其相似度符合标准,那么取之 diffVO = edVO; //发现了,那么退出本次for循环,继续找下一个变量在页面中是否存在 break; } } } if(diffVO != null){ //找到页面中的模版变量了,将变量替换为变量标签 Element varElement = diffVO.getTargetElement(); //变量Element //元素搜索 Elements eles = doc.getElementsByTag(varElement.tagName()); //页面中搜寻的变量的element for (int i = 0; i < eles.size(); i++) { Element e = eles.get(i); double s = StringUtil.similarity(e, varElement); if(s > Global.sim){ System.out.println("发现相同="+s+"="+varName+"===="+e.toString().length()); haveVarNameList.add(varName); //加入使用列表 e.before("<h1>include_varName="+varName+"</h1>"); // e.after("<h2>include_after_varName="+varName+"</h2>"); e.remove(); //将当前找到的元素删除掉 } } } } String html = doc.toString(); for (int i = 0; i < haveVarNameList.size(); i++) { String varName = haveVarNameList.get(i); System.out.println("--替换模版:"+varName); html = StringUtil.replaceAll(html, "<h1>include_varName="+varName+"</h1>", " {include="+varName+"} "); // html = com.xnx3.StringUtil.subStringReplace(html, "<h1>include_before_varName="+varName+"</h1>", "<h2>include_after_varName="+varName+"</h2>", " {include="+varName+"} "); } return html; } /** * 导出模版文件,对String类型的数据进行处理 * @return */ private static String exportTemplateStringDispose(String value){ return com.xnx3.StringUtil.StringToUtf8(value); } static String site_name = "{site.name}"; static String siteColumn_name = "{siteColumn.name}"; static String news_title = "{news.title}"; /** * 替换模版页面中的动态标签 * 1.替换title标签 * 2.删除keywords 、 description */ public static void replaceDongtaiTag(){ /* * 遍历出模版页面 */ List<Map<String, String>> templatePageList = new ArrayList<Map<String,String>>(); DefaultTableModel pageModel = Global.mainUI.getTemplatePageTableModel(); int pageRowCount = pageModel.getRowCount(); for (int i = 0; i < pageRowCount; i++) { Map<String, String> map = new HashMap<String, String>(); //模版页面名字 String name = (String) pageModel.getValueAt(i, 0); if(name != null && name.length() > 0){ Template temp = Global.templateMap.get(name); if(temp != null){ //有这个模版页面 Document doc = temp.getDoc(); //删除 keywords 、 description Elements metaEles = doc.getElementsByTag("meta"); Iterator<Element> it = metaEles.iterator(); while(it.hasNext()){ Element metaEle = it.next(); String metaName = metaEle.attr("name"); if(metaEle != null && metaName != null){ if(metaName.equalsIgnoreCase("keywords") || metaName.equalsIgnoreCase("description")){ try { metaEle.remove(); it.remove(); } catch (Exception e) { e.printStackTrace(); System.out.println(metaEle); } } } } //替换title标签 Elements titleEles = doc.getElementsByTag("title"); Element titleEle = null; if(titleEles != null && titleEles.size() > 0){ titleEle = titleEles.first(); }else{ //若没有这个title,那么需要新增加一个 Elements headElements = doc.getElementsByTag("head"); if(headElements == null || headElements.size() == 0){ UI.showMessageDialog("模版页面"+temp.getFile().getName()+"中无head标签!模版页估计不完整!请手动补上head标签"); return; }else{ // titleEle = new Element(tag, baseUri) // headElements.first().appendElement(tagName) /* * 待加入 */ } } if(titleEle != null){ //替换title标签为动态标签 String type = (String) pageModel.getValueAt(i, 1); switch (type) { case "首页模版": titleEle.text(site_name); break; case "列表页模版": titleEle.text(siteColumn_name+"_"+site_name); break; case "详情页模版": titleEle.text(news_title+"_"+site_name); break; default: titleEle.text(site_name); break; } } Global.templateMap.put(temp.getFile().getName(), temp); } } } } /** * 获取当前操作的模版,保存路径的模版名,将要保存到文件夹的名称 * @return */ public static String getTemplatePathName(){ String uiTN = Global.mainUI.getTextField_templateName().getText(); if(uiTN == null || uiTN.length() == 0){ try { uiTN = "template_"+DateUtil.dateFormat(DateUtil.timeForUnix10(), "yyyy_MM_dd__hh_mm"); } catch (NotReturnValueException e) { e.printStackTrace(); } } return uiTN; } /** * 显示当前最新的模版变量,将Global中存的模版变量显示到JTable中。也可以作为刷新使用 */ public static void showUITemplateVarJTabel(){ Global.mainUI.getTemplateVarTableModel().setRowCount( 0 ); for (Map.Entry<String, ElementDiffRecord> entry : Global.templateVarMap.entrySet()) { ElementDiffRecord record = entry.getValue(); Vector rowData = new Vector(); int[] diff = Action.isPreviewDiff(record.getElementDiffListVO()); rowData.add(entry.getKey()); rowData.add(diff[0]); rowData.add(diff[1]); rowData.add("删除"); rowData.add(diff[1] > 0? "对比":""); rowData.add(""); Global.mainUI.getTemplateVarTableModel().insertRow(0, rowData); } } /** * 第3步,提取模版变量,对提取的模版变量进行过滤,如过滤其字符串长度、相似度文件占的比例 */ public static void templateVarListFilter(){ //得到模版变量过滤的最长字符数 int len = Lang.stringToInt(Global.templateVarGainJframe.getVarTextLengthtextField().getText(), 0); System.out.println("len -- >"+len); //相似度百分比,不过这里是整数, 如相似度70%,这里的数字是 70 int percent = Lang.stringToInt(Global.templateVarGainJframe.getXiangsiduPercentTextField().getText(), 0); /* * 进行筛选 */ //要删除的列表。 item: map.key List<String> removeMapList = new ArrayList<String>(); //从map中找到要删除的key,放入list for (Map.Entry<String, ElementDiffRecord> entry : Global.templateVarMap.entrySet()) { ElementDiffRecord record = entry.getValue(); //进行长度筛选 String html = record.getElementDiffVO().getDiffElement().html(); System.out.println("---------html---------"+html); if(html.length() < len){ removeMapList.add(entry.getKey()); } //进行相似度筛选 int[] diff = Action.isPreviewDiff(record.getElementDiffListVO()); int findNum = diff[0]+diff[1]; //发现相同的条数,等于 完全相同的数量+相似度达标的数量 double baifenbi= Math.ceil(findNum*100/Global.templateMap.size()); System.out.println("模版变量数目:"+Global.templateMap.size()+", 相同条数:"+findNum+", 相似度达标的条数,占模版页面总条数的百分比:"+baifenbi); if(baifenbi < percent){ //百分比跟模版变量-高级设置中的百分比还小,那么舍弃,删除(过滤掉)这个模版变量 removeMapList.add(entry.getKey()); System.out.println("----------删除掉这个模版变量:"+record); } } //从map中删除 for (int i = 0; i < removeMapList.size(); i++) { Global.templateVarMap.remove(removeMapList.get(i)); } Global.log("模版变量提取完毕!"); showUITemplateVarJTabel(); } }