Skip to content

Commit

Permalink
マークダウンのパース処理でエラーが発生する事がある #77
Browse files Browse the repository at this point in the history
IE11で添付ファイル(日本語)のファイル名が文字化けする #58
タグが数文字でスクロールして消えてしまう #74
  • Loading branch information
koda-masaru committed Jul 31, 2015
1 parent 59fb9c4 commit c68b83c
Show file tree
Hide file tree
Showing 17 changed files with 1,649 additions and 28 deletions.
8 changes: 7 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,13 @@
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-parsers</artifactId>
<version>1.6</version>
<version>1.9</version>
<exclusions>
<exclusion>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-debug-all</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.support.project.knowledge.logic.TargetLogic;
import org.support.project.knowledge.logic.UploadedFileLogic;
import org.support.project.knowledge.vo.LikeCount;
import org.support.project.knowledge.vo.MarkDown;
import org.support.project.knowledge.vo.UploadFile;
import org.support.project.web.bean.LabelValue;
import org.support.project.web.bean.LoginedUser;
Expand Down Expand Up @@ -104,7 +105,8 @@ public Boundary view() throws InvalidParamException, ParseException {
}
//Markdownを処理
entity.setTitle(sanitize(entity.getTitle()));
entity.setContent(MarkdownLogic.get().markdownToHtml(entity.getContent()));
MarkDown markDown = MarkdownLogic.get().markdownToHtml(entity.getContent());
entity.setContent(markDown.getHtml());

setAttributeOnProperty(entity);

Expand Down Expand Up @@ -132,7 +134,8 @@ public Boundary view() throws InvalidParamException, ParseException {
List<CommentsEntity> comments = commentsDao.selectOnKnowledgeId(knowledgeId);
// Markdown を処理
for (CommentsEntity commentsEntity : comments) {
commentsEntity.setComment(MarkdownLogic.get().markdownToHtml(commentsEntity.getComment()));
MarkDown markDown2 = MarkdownLogic.get().markdownToHtml(commentsEntity.getComment());
commentsEntity.setComment(markDown2.getHtml());
}
setAttribute("comments", comments);

Expand Down Expand Up @@ -186,8 +189,10 @@ public Boundary list() throws Exception {
int userId = Integer.parseInt(user);
knowledges.addAll(knowledgeLogic.showKnowledgeOnUser(userId, loginedUser, offset * PAGE_LIMIT, PAGE_LIMIT));
UsersEntity usersEntity = UsersDao.get().selectOnKey(userId);
usersEntity.setPassword("");
setAttribute("selectedUser", usersEntity);
if (user != null) {
usersEntity.setPassword("");
setAttribute("selectedUser", usersEntity);
}
} else if (StringUtils.isNotEmpty(tagNames)) {
// タグとキーワードで検索
LOG.trace("show on Tags and keyword");
Expand Down Expand Up @@ -313,7 +318,8 @@ public Boundary escape(KnowledgesEntity entity) throws ParseException {
public Boundary marked(KnowledgesEntity entity) throws ParseException {
super.setSendEscapeHtml(false);
entity.setTitle(sanitize(entity.getTitle()));
entity.setContent(MarkdownLogic.get().markdownToHtml(entity.getContent()));
MarkDown markDown = MarkdownLogic.get().markdownToHtml(entity.getContent());
entity.setContent(markDown.getHtml());
return super.send(entity);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.httpclient.HttpStatus;
import org.support.project.aop.Aspect;
import org.support.project.common.log.Log;
import org.support.project.common.log.LogFactory;
Expand Down Expand Up @@ -281,7 +280,7 @@ public MessageResult addUsers(LoginedUser loginedUser, Integer groupId, String u
if (groupsDao.selectAccessAbleGroup(groupId, loginedUser) == null) {
MessageResult messageResult = new MessageResult();
messageResult.setStatus(MessageStatus.Error.getValue());
messageResult.setCode(HttpStatus.SC_FORBIDDEN);
messageResult.setCode(org.support.project.web.common.HttpStatus.SC_403_FORBIDDEN);
return messageResult; // アクセス権がないユーザ
}
}
Expand Down
152 changes: 142 additions & 10 deletions src/main/java/org/support/project/knowledge/logic/MarkdownLogic.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
package org.support.project.knowledge.logic;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.util.Date;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.pegdown.Extensions;
import org.pegdown.LinkRenderer;
import org.pegdown.PegDownProcessor;
Expand All @@ -10,39 +20,161 @@
import org.support.project.di.Container;
import org.support.project.di.DI;
import org.support.project.di.Instance;
import org.support.project.knowledge.vo.MarkDown;
import org.support.project.web.logic.SanitizingLogic;

@DI(instance=Instance.Singleton)
@DI(instance = Instance.Singleton)
public class MarkdownLogic {
/** ログ */
private static Log LOG = LogFactory.getLog(MarkdownLogic.class);

public static final int ENGINE_PEGDOWN = 1;
public static final int ENGINE_MARKEDJS = 2;

private ScriptEngine engine = null;
private boolean initEngine = false;

public static MarkdownLogic get() {
return Container.getComp(MarkdownLogic.class);
}

public String markdownToHtml(String markdown) throws ParseException {
/**
* マークダウンをパースしてHTMLを取得
* @param markdown
* @return
* @throws ParseException
*/
public MarkDown markdownToHtml(String markdown) throws ParseException {
return markdownToHtml(markdown, ENGINE_PEGDOWN);
}
/**
* マークダウンをパースしてHTMLを取得(エンジンを指定)
* @param markdown
* @param engine
* @return
* @throws ParseException
*/
public MarkDown markdownToHtml(String markdown, int engine) throws ParseException {
MarkDown result = new MarkDown();
if (engine == ENGINE_MARKEDJS) {
markdownToHtmlOnMarkedJs(markdown, result);
} else {
markdownToHtmlOnPegDown(markdown, result);
}
return sanitize(markdown, result);
}


/**
* サニタイジング
* @param markdown
* @param result
* @return
* @throws ParseException
*/
private MarkDown sanitize(String markdown, MarkDown result) throws ParseException {
try {
String html = result.getHtml();
if (LOG.isDebugEnabled()) {
LOG.debug("[Markdown] : " + markdown);
LOG.debug("[ParsedHtml] : " + html);
}
// 危険なHTMLは削除
html = SanitizingLogic.get().sanitize(html);
if (LOG.isDebugEnabled()) {
LOG.debug("[SanitizeHtml] : " + html);
}
result.setHtml(html);
return result;
} catch (Exception e) {
// サニタイズではエラーにならないはず
throw new ParseException(e);
}
}

/**
* PegDownでMarkDownのパース
* @param markdown
* @param result
*/
private void markdownToHtmlOnPegDown(String markdown, MarkDown result) {
Date start = new Date();
result.setMarkdown(markdown);
String html = markdown;
try {
// Markdownのパース
PegDownProcessor processor = new PegDownProcessor(Extensions.ALL - Extensions.ANCHORLINKS);
String html = processor.markdownToHtml(markdown, new LinkRenderer() {
html = processor.markdownToHtml(markdown, new LinkRenderer() {
@Override
public Rendering render(AnchorLinkNode node) {
return new Rendering(node.getText(), node.getText());
}
});
result.setHtml(html);
result.setParsed(true);
if (LOG.isDebugEnabled()) {
LOG.debug("[Markdown] : " + markdown);
LOG.debug("[ParsedHtml] : " + html);
Date end = new Date();
LOG.debug("Parse time (PegDown): " + (end.getTime() - start.getTime()) + " [ms]");
}
// 危険なHTMLは削除
html = SanitizingLogic.get().sanitize(html);
} catch (Exception e) {
// Markdownのパースに失敗する事がある
LOG.error("Markdown parse error.", e);
// PegDownをデフォルトとして、失敗した場合、Marked.jsでパースしてみる
markdownToHtmlOnMarkedJs(markdown, result);
}
}

private ScriptEngine getScriptEngine() throws ScriptException, IOException {
if (initEngine) {
return engine;
}
ScriptEngineManager manager = new ScriptEngineManager();
engine = manager.getEngineByName("js");
if (engine == null) {
System.out.println("JavaScriptはサポート外");
initEngine = true;
return null;
}
Reader fr = null;
try {
fr = new InputStreamReader(this.getClass().getResourceAsStream("/org/support/project/knowledge/logic/marked.js"), Charset.forName("UTF-8"));
engine.eval(fr);
initEngine = true;
return engine;
} finally {
if (fr != null) {
fr.close();
}
}
}


/**
* marked.jsでMarkDownのパース
* @param markdown
* @param result
*/
private void markdownToHtmlOnMarkedJs(String markdown, MarkDown result) {
Date start = new Date();
result.setMarkdown(markdown);
String html = markdown;
try {
engine = getScriptEngine();
if (engine == null) {
return;
}
engine.put("content", markdown);
html = (String) engine.eval("marked(content)");
result.setHtml(html);
result.setParsed(true);
if (LOG.isDebugEnabled()) {
LOG.debug("[SanitizeHtml] : " + html);
Date end = new Date();
LOG.debug("Parse time (marked.js): " + (end.getTime() - start.getTime()) + " [ms]");
}
return html;
} catch (Exception e) {
throw new ParseException(e);
LOG.error("Markdown parse error.", e);
}
}


}
53 changes: 53 additions & 0 deletions src/main/java/org/support/project/knowledge/vo/MarkDown.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.support.project.knowledge.vo;

public class MarkDown {

private String markdown;

private String html;

private boolean parsed = false;

/**
* @return the markdown
*/
public String getMarkdown() {
return markdown;
}

/**
* @param markdown the markdown to set
*/
public void setMarkdown(String markdown) {
this.markdown = markdown;
}

/**
* @return the html
*/
public String getHtml() {
return html;
}

/**
* @param html the html to set
*/
public void setHtml(String html) {
this.html = html;
}

/**
* @return the parsed
*/
public boolean isParsed() {
return parsed;
}

/**
* @param parsed the parsed to set
*/
public void setParsed(boolean parsed) {
this.parsed = parsed;
}

}
2 changes: 1 addition & 1 deletion src/main/resources/appresource.properties
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ message.allready.updated=Allready updated.
message.allready.started=Allready started.

# Common Label
label.version=0.5.3 pre3
label.version=0.5.3 pre4
label.login=Sign in
label.previous = Previous
label.next=Next
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/appresource_ja.properties
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ message.allready.updated=すでに更新されています
message.allready.started=すでに開始済です

# Common Label
label.version=0.5.3 pre3
label.version=0.5.3 pre4
label.login=サインイン
label.previous = 前へ
label.next = 次へ
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/log4j.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
</category>

<category name="org.support.project.knowledge.bat">
<level value="DEBUG" />
<level value="INFO" />
</category>
<category name="org.support.project.knowledge.listener">
<level value="INFO" />
Expand Down
Loading

0 comments on commit c68b83c

Please sign in to comment.