/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openuap.cms.engine.generate.processor;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.FilenameUtils;
import org.openuap.base.util.FileUtil;
import org.openuap.base.util.StringUtil;
import org.openuap.cms.config.CMSConfig;
import org.openuap.cms.engine.profile.PublishProfileInfoHolder;
import org.openuap.cms.engine.profile.impl.PublishOperationProfileImpl;
import org.openuap.cms.node.model.Node;
import org.openuap.cms.psn.manager.PsnManager;
import org.openuap.cms.psn.model.Psn;
import org.openuap.tpl.engine.TemplateContext;
import org.openuap.tpl.engine.TemplateProcessor;
import org.openuap.tpl.engine.TemplateProcessorChain;
/**
* <p> 模板中的资源处理 </p>
*
* <p> $Id: SkinProcessor.java 4080 2012-05-04 16:52:23Z orangeforjava $ </p>
*
* @author Joseph
* @version 1.0
*/
public class SkinProcessor implements TemplateProcessor {
private int priority = 10;
private PsnManager psnManager;
public final static String EXT_POINT_NAME = "tpl-processor-skin";
public String getName() {
return EXT_POINT_NAME;
}
public void processTemplate(TemplateProcessorChain chain,
TemplateContext context, List errors) {
String tplContent = context.getTplContent();
if (tplContent != null) {
// 性能诊断-start
PublishOperationProfileImpl op = null;
Exception exception = null;
if (PublishProfileInfoHolder.isEnableProfile()) {
op = new PublishOperationProfileImpl();
op.setOperation("SkinProcessor");
op.setStartTime(System.currentTimeMillis());
}
//
Object preview = context.getModel().get("__preview__");
if (preview == null) {
//
String tplContent2 = processSkinFile(tplContent, context,
errors);
//
if (PublishProfileInfoHolder.isEnableProfile()) {
op.setEndTime(System.currentTimeMillis());
op.setException(exception);
PublishProfileInfoHolder.getProfile().addPublishOperation(
op);
}
context.setTplContent(tplContent2);
//
}
chain.doProcess(context, errors);
}
}
/**
*
* 处理模板中的资源
*
* @param tplContent
*
* @param node
*
* @param errors
*
* @return String
*/
public String processSkinFile(String tplContent, TemplateContext context,
List errors) {
CMSConfig config = CMSConfig.getInstance();
String imgExtensions = config.getUploadFileImageType();
String flashExtensions = config.getUploadFileFlashType();
String attachExtensions = config.getUploadFileAttachType();
String sAllowExt = imgExtensions + "|" + flashExtensions + "|"
+ attachExtensions + "|js|html|htm|shtml|css|icon";
// 1)处理资源库的引用
List tplRsList = new ArrayList();
// 资源匹配模式
String sp = "\\.\\.\\/resource\\/((img|flash|attach)(\\/\\w+)+\\.("
+ sAllowExt + "))";
String rsRootDir = config.getResourceRootPath();
Pattern p = Pattern.compile(sp);
Matcher m = p.matcher(tplContent);
boolean result = m.find();
StringBuffer sb = new StringBuffer();
// 模板皮肤路径
String skinRootPath = config.getTemplateSkinPath();
String sysRootPath = config.getSysRootPath();
//
String destResourceUrl = "";
String destSkinUrl = "";
//
Object oNode = context.getModel().get("node");
if (oNode != null && oNode instanceof Node) {
Node node = (Node) oNode;
// 获得本结点的资源发布Url信息
String rsUrl = node.getResourceUrl();
//
destResourceUrl = psnManager.getPsnUrlInfo(rsUrl);
while (result) {
//
String path = m.group(1);
if (!tplRsList.contains(path)) {
tplRsList.add(path);
//
String fullPath = rsRootDir;
fullPath += File.separator + path;
fullPath = StringUtil.normalizePath(fullPath);
File srcFile = new File(fullPath);
// 获得资源Copy的目的目录
File destFile = getResourceDestFile(sysRootPath, path,
node, errors);
try {
// decide if should copy file.
if (shouldCopyFile(srcFile, destFile)) {
FileUtil.copy(srcFile, destFile);
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
//
String destResourceUrl2 = destResourceUrl + "/" + path;
m.appendReplacement(sb, destResourceUrl2);
result = m.find();
}
m.appendTail(sb);
// 2)process the template skin refrence
String skinContent = sb.toString();
tplRsList = null;
//
destSkinUrl = getDestSkinUrl(node);
return processTemplateSkins(node, errors, sAllowExt, skinRootPath,
sysRootPath, destSkinUrl, skinContent);
}
return tplContent;
}
protected String getDestSkinUrl(Node node) {
String destResourceUrl = "";
String rsUrl = node.getResourceUrl();
String sp = "\\{PSN-URL:(\\d+)\\}((\\/\\p{Print}*\\s*)*)";
Pattern p = Pattern.compile(sp);
Matcher m = p.matcher(rsUrl);
boolean result = m.find();
StringBuffer sb = new StringBuffer();
while (result) {
String path = m.group(2);
String psnId = m.group(1);
Psn psn = psnManager.getPsnFromCache(new Long(psnId));
String psnUrl = psn.getUrl();
m.appendReplacement(sb, psnUrl + path);
result = m.find();
} // end while result
m.appendTail(sb);
destResourceUrl = sb.toString();
return destResourceUrl;
}
private File getResourceDestFile(String sysRootDir, String destFileName,
Node node, List errors) {
String fullPath = sysRootDir;
String rsPsn = node.getResourcePsn();
String relativePath = getRelativePath(rsPsn);
if (!relativePath.equals("")) {
fullPath += "/" + relativePath;
}
int pos = destFileName.lastIndexOf("/");
String destPath = "";
String destFile = "";
if (pos > -1) {
destPath = destFileName.substring(0, pos);
destFile = destFileName.substring(pos + 1);
} else {
destFile = destFileName;
}
if (!destPath.equals("")) {
fullPath += "/" + destPath;
}
fullPath = StringUtil.normalizePath(fullPath);
File destDir = new File(fullPath);
if (!destDir.exists()) {
destDir.mkdirs();
}
File dest = new File(destDir, destFile);
return dest;
}
private String getRelativePath(String selfPsn) throws NumberFormatException {
String relativePath = "";
String sp = "\\{PSN:(\\d+)\\}((\\/\\p{Print}*\\s*)*)";
Pattern p = Pattern.compile(sp);
Matcher m = p.matcher(selfPsn);
boolean result = m.find();
while (result) {
String path = m.group(2);
String psnId = m.group(1);
Psn psn = psnManager.getPsnFromCache(new Long(psnId));
// String psnUrl = psn.getPsn();
if (psn.getType() == Psn.LOCAL_PSN_TYPE) {
// now,only process the local
// remote will be do later.
relativePath = psn.getLocalPath();
relativePath += "/" + path;
}
result = m.find();
} // end while result
return relativePath;
}
private boolean shouldCopyFile(File srcFile, File destFile) {
if (srcFile.exists()) {
if (!destFile.exists()
|| (destFile.exists() && (destFile.lastModified() < srcFile.lastModified() || destFile.length() != srcFile.length()))) {
return true;
}
}
return false;
}
private String testProcessTemplateSkins(String sAllowExt, String skinRootPath, String sysRootPath,
String destSkinUrl, String skinContent) {
List tplSkinList = new ArrayList();
//这里解决了一个Bug,若资源里出现.符号,将出现死循环
String sp_skin = "\\.\\.\\/templates\\/skins(([\\/\\w\\-\\~\\.])+?\\.("
+ sAllowExt + ")+?)";
// String sp_skin = "\\.\\.\\/templates\\/skins(([\\/\\w\\-\\~\\.]+)+\\.("
// + sAllowExt + "))";
Pattern p_skin = Pattern.compile(sp_skin);
Matcher m_skin = p_skin.matcher(skinContent);
boolean result_skin = m_skin.find();
StringBuffer sb_skin = new StringBuffer();
String css_url_patter = "";
long s = System.currentTimeMillis();
while (result_skin) {
String full = m_skin.group(0);
System.out.println("full="+full);
String path = m_skin.group(1);
if (!tplSkinList.contains(path)) {
tplSkinList.add(path);
String fullPath = skinRootPath;
fullPath += File.separator + path;
fullPath = StringUtil.normalizePath(fullPath);
File srcFile = new File(fullPath);
//File destFile = getSkinDestFile(sysRootPath, path, node, errors);
try {
//if (shouldCopyFile(srcFile, destFile)) {
// FileUtil.copy(srcFile, destFile);
//}
if (srcFile.exists()) {
// 处理css文件,css文件里可能会引用图片资源
// 目前只处理相对路径的引用,不处理绝对路径
String extension = FilenameUtils.getExtension(srcFile.getAbsolutePath());
//if ("css".equalsIgnoreCase(extension)) {
// processCssImages(srcFile, destFile);
//}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
//
String mydestSkinUrl = destSkinUrl;
mydestSkinUrl += "/skins" + path;
m_skin.appendReplacement(sb_skin, mydestSkinUrl);
result_skin = m_skin.find();
}
m_skin.appendTail(sb_skin);
tplSkinList = null;
// System.out.println(sb_skin.toString());
return sb_skin.toString();
}
/**
* 处理模板中使用的资源
*
* @param node
* @param errors
* @param sAllowExt
* @param skinRootPath
* @param sysRootPath
* @param destSkinUrl
* @param skinContent
* @return
*/
protected String processTemplateSkins(Node node, List errors,
String sAllowExt, String skinRootPath, String sysRootPath,
String destSkinUrl, String skinContent) {
//
List tplSkinList = new ArrayList();
//这里解决了一个Bug,若资源里出现.符号,将出现死循环
// String sp_skin = "\\.\\.\\/templates\\/skins(([\\/\\w\\-\\~\\.]+)+\\.("
// + sAllowExt + "))";
String sp_skin = "\\.\\.\\/templates\\/skins(([\\/\\w\\-\\~\\.])+?\\.("
+ sAllowExt + ")+?)";
Pattern p_skin = Pattern.compile(sp_skin);
Matcher m_skin = p_skin.matcher(skinContent);
boolean result_skin = m_skin.find();
StringBuffer sb_skin = new StringBuffer();
String css_url_patter = "";
long s = System.currentTimeMillis();
while (result_skin) {
// String full = m_skin.group(0);
String path = m_skin.group(1);
if (!tplSkinList.contains(path)) {
tplSkinList.add(path);
String fullPath = skinRootPath;
fullPath += File.separator + path;
fullPath = StringUtil.normalizePath(fullPath);
File srcFile = new File(fullPath);
File destFile = getSkinDestFile(sysRootPath, path, node, errors);
try {
if (shouldCopyFile(srcFile, destFile)) {
FileUtil.copy(srcFile, destFile);
}
if (srcFile.exists()) {
// 处理css文件,css文件里可能会引用图片资源
// 目前只处理相对路径的引用,不处理绝对路径
String extension = FilenameUtils.getExtension(srcFile.getAbsolutePath());
if ("css".equalsIgnoreCase(extension)) {
processCssImages(srcFile, destFile);
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
//
String mydestSkinUrl = destSkinUrl;
mydestSkinUrl += "/skins" + path;
m_skin.appendReplacement(sb_skin, mydestSkinUrl);
result_skin = m_skin.find();
}
m_skin.appendTail(sb_skin);
tplSkinList = null;
// System.out.println(sb_skin.toString());
return sb_skin.toString();
}
protected File getSkinDestFile(String rootDir, String destFileName,
Node node, List errors) {
String fullPath = rootDir;
// Node node = nodeManager.getNodeById(nodeId);
String rsPsn = node.getResourcePsn();
String relativePath = getRelativePath(rsPsn);
if (!relativePath.equals("")) {
fullPath += "/" + relativePath;
}
fullPath += "/" + "skins";
int pos = destFileName.lastIndexOf("/");
String destPath = "";
String destFile = "";
if (pos > -1) {
destPath = destFileName.substring(0, pos);
destFile = destFileName.substring(pos + 1);
} else {
destFile = destFileName;
}
if (!destPath.equals("")) {
fullPath += "/" + destPath;
}
fullPath = StringUtil.normalizePath(fullPath);
File destDir = new File(fullPath);
if (!destDir.exists()) {
destDir.mkdirs();
}
File dest = new File(destDir, destFile);
return dest;
}
public void setPsnManager(PsnManager psnManager) {
this.psnManager = psnManager;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
protected void processCssImages(File srcFile, File destFile) {
try {
String cssContent = FileUtil.readTextFile(srcFile, "UTF-8");
String css_url_patter = "url\\((['\"]*)?([^\\)]*?)(['\"]*)?\\)";
Pattern p_css_url = Pattern.compile(css_url_patter);
Matcher m_skin = p_css_url.matcher(cssContent);
boolean result_skin = m_skin.find();
String srcPath = srcFile.getAbsolutePath();
String srcBaseDir = FilenameUtils.getFullPath(srcPath);
String destPath = destFile.getAbsolutePath();
String destBaseDir = FilenameUtils.getFullPath(destPath);
while (result_skin) {
//
String path = m_skin.group(2);
String srcFullPath = StringUtil.normalizePath(srcBaseDir + path);
// System.out.println(srcFullPath);
String destFullPath = StringUtil.normalizePath(destBaseDir
+ path);
File imgSrcFile = new File(srcFullPath);
File imgDestFile = new File(destFullPath);
try {
if (shouldCopyFile(imgSrcFile, imgDestFile)) {
FileUtil.copy(imgSrcFile, imgDestFile);
}
} catch (Exception e) {
e.printStackTrace();
}
//
result_skin = m_skin.find();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
String skinContent = ".cgky5 li {float:left; margin-left:5px; width:200px; text-indent:10px; text-indent /**/:15px; line-height:23px; background-image: url(../images/ind_r19_c23.jpg); background-repeat: no-repeat; background-position: 0px center; background-position /**/: 5px center;}"
+ ".cgky6{float:left; height:120px; width:228px;}"
+ ".cgky6 ul {clear:both; list-style:none;}.cgky6 li {float:left; margin-left:5px; width:200px; text-indent:10px; text-indent /**/:15px; line-height:24px; background-image: url(../images/ind_r19_c23.jpg); background-repeat: no-repeat; background-position: 0px center; background-position /**/: 5px center;}"
+ ".tonglan-right-box2{float:left; width:237px; height:183px; margin:4px auto auto 0px; margin-left /**/:4px;}"
+ ".tonglan-right-box2-centents{float:left; width:234px; height:153px; border:#e4b951 solid 1px}.zhpxzx42{float:left; width:237px; height:182px; margin:0px auto auto 0px; margin-left /**/:4px; background-image:url(\"../images/school_r5_c2.jpg\"); background-repeat:no-repeat; background-position:left top; background-attachment:scroll;}.zhpxzx42 h1{float:left; width:237px; height:30px; line-height:30px; margin-top:10px; font-size:13px; text-align:center; color:#FF9501; font-weight:bold;}";
String css_url_patter = "url\\((['\"]*)?([^\\)]*?)(['\"]*)?\\)";
Pattern p_css_url = Pattern.compile(css_url_patter);
Matcher m_skin = p_css_url.matcher(skinContent);
boolean result_skin = m_skin.find();
File srcFile = new File("d:/home/dir/css/skin.css");
File parentFile = srcFile.getParentFile();
System.out.println(parentFile.getAbsolutePath());
String extension = FilenameUtils.getExtension(srcFile.getAbsolutePath());
System.out.println(extension);
String path1 = srcFile.getAbsolutePath();
System.out.println(path1);
String baseDir = org.apache.commons.io.FilenameUtils.getFullPath(path1);
System.out.println("baseDir=" + baseDir);
while (result_skin) {
// String full = m_skin.group(0);
String path = m_skin.group(2);
String fullPath = StringUtil.normalizePath(baseDir + path);
System.out.println(fullPath);
result_skin = m_skin.find();
}
//
String testStr = "<li><a target=\"_blank\" href=\"http://www.cihucn.com/page-muqinjie.html\"><img alt=\"\" width=\"744\" height=\"108\" src=\"../templates/skins/ccun-main/images/744c108.JPG\" /></a></li>";
SkinProcessor p = new SkinProcessor();
p.testProcessTemplateSkins("jpg|bmp|gif", "", "", "http://test.mycms.org/skins", testStr);
System.out.println("OK.");
}
}