-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refs #89 EL2とEL3の実装を分離しNoClassDefFoundErrorが発生する事象を修正
- Loading branch information
Showing
9 changed files
with
875 additions
and
333 deletions.
There are no files selected for viewing
57 changes: 57 additions & 0 deletions
57
src/main/java/com/gh/mygreen/xlsmapper/expression/AbstractExpressionLanguageEL.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package com.gh.mygreen.xlsmapper.expression; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Formatter; | ||
import java.util.List; | ||
|
||
import org.hibernate.validator.internal.engine.messageinterpolation.el.RootResolver; | ||
|
||
import com.github.mygreen.expression.el.FormatterWrapper; | ||
import com.github.mygreen.expression.el.tld.Taglib; | ||
import com.github.mygreen.expression.el.tld.TldLoader; | ||
|
||
/** | ||
* EL式を利用する際のベースとなる抽象クラス。 | ||
* | ||
* @since 1.6 | ||
* @author T.TSUCHIE | ||
* | ||
*/ | ||
public abstract class AbstractExpressionLanguageEL implements ExpressionLanguage { | ||
|
||
/** TLDファイルの定義内容 */ | ||
protected List<Taglib> taglibList = new ArrayList<>(); | ||
|
||
/** | ||
* カスタムタグの定義ファイル「TLD(Tag Library Defenitioin)」を登録する。 | ||
* <p>{@link TldLoader}クラスで読み込む。 | ||
* | ||
* @since 1.5 | ||
* @param taglib カスタムタグの定義内容。 | ||
*/ | ||
public void register(final Taglib taglib) { | ||
this.taglibList.add(taglib); | ||
} | ||
|
||
/** | ||
* 登録されているEL式中の変数(Bean)が、{@link Formatter}かどうか判定する。 | ||
* <p>{@link Formatter}中のメソッド{@code format(...)}メソッドは、オーバロードで複数のメソッドが定義されいるが、 | ||
* EL式はメソッドのオーバーロードはサポートされていない。 | ||
* <br>そのため、{@link FormatterWrapper}でラップして、オーバーロードなしのメソッドする。 | ||
* </p> | ||
* @param key 判定対象のキー値 | ||
* @param value 判定対象の値のインスタンス | ||
* @return キー名が{@link RootResolver#FORMATTER}(formatter)と一致し、かつ、valueのインスタンスが{@link Formatter}の場合、trueを返します。 | ||
*/ | ||
protected boolean isFormatter(final String key, final Object value) { | ||
if(!RootResolver.FORMATTER.equals(key)) { | ||
return false; | ||
} | ||
|
||
if(value instanceof Formatter) { | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
} |
76 changes: 76 additions & 0 deletions
76
src/main/java/com/gh/mygreen/xlsmapper/expression/ExpressionLangaugeEL2Impl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package com.gh.mygreen.xlsmapper.expression; | ||
|
||
import java.util.Formatter; | ||
import java.util.Map; | ||
import java.util.Map.Entry; | ||
|
||
import javax.el.ELException; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import com.gh.mygreen.xlsmapper.ArgUtils; | ||
import com.gh.mygreen.xlsmapper.Utils; | ||
import com.github.mygreen.expression.el.ELProcessor; | ||
import com.github.mygreen.expression.el.FormatterWrapper; | ||
import com.github.mygreen.expression.el.tld.Function; | ||
import com.github.mygreen.expression.el.tld.Taglib; | ||
|
||
/** | ||
* EL式(EL 2.x)を使用するための実装。 | ||
* | ||
* @since 1.6 | ||
* @author T.TSUCHIE | ||
* | ||
*/ | ||
public class ExpressionLangaugeEL2Impl extends AbstractExpressionLanguageEL { | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(ExpressionLangaugeEL2Impl.class); | ||
|
||
@Override | ||
public Object evaluate(final String expression, final Map<String, ?> values) { | ||
|
||
ArgUtils.notEmpty(expression, "expression"); | ||
ArgUtils.notNull(values, "values"); | ||
|
||
try { | ||
final ELProcessor elProc = new ELProcessor(); | ||
|
||
for (final Entry<String, ? > entry : values.entrySet()) { | ||
if(isFormatter(entry.getKey(), entry.getValue())) { | ||
elProc.setVariable(entry.getKey(), new FormatterWrapper((Formatter) entry.getValue())); | ||
} else { | ||
elProc.setVariable(entry.getKey(), entry.getValue()); | ||
} | ||
} | ||
|
||
// カスタムタグを登録する。 | ||
for(Taglib taglib : taglibList) { | ||
final String prefix = Utils.trimToEmpty(taglib.getShortName()); | ||
|
||
for(Function function : taglib.getFunctions()) { | ||
final String className = Utils.trimToEmpty(function.getFunctionClass()); | ||
final String signature = Utils.trimToEmpty(function.getFunctionSignature()); | ||
final String name = Utils.trimToEmpty(function.getName()); | ||
|
||
try { | ||
elProc.defineFunction(prefix, name, className, signature); | ||
|
||
} catch(ClassNotFoundException | NoSuchMethodException ex) { | ||
throw new ExpressionEvaluationException(String.format("Faild defined with EL function : [%s:%s].", className, signature), ex); | ||
} | ||
} | ||
} | ||
|
||
if(logger.isDebugEnabled()) { | ||
logger.debug("Evaluating EL expression: {}", expression); | ||
} | ||
|
||
return elProc.eval(expression); | ||
|
||
} catch (final ELException ex){ | ||
throw new ExpressionEvaluationException(String.format("Evaluating [%s] script with EL failed.", expression), ex); | ||
} | ||
} | ||
|
||
} |
113 changes: 113 additions & 0 deletions
113
src/main/java/com/gh/mygreen/xlsmapper/expression/ExpressionLangaugeEL3Impl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package com.gh.mygreen.xlsmapper.expression; | ||
|
||
import java.util.Formatter; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Map.Entry; | ||
|
||
import javax.el.BeanNameResolver; | ||
import javax.el.ELException; | ||
import javax.el.ELProcessor; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import com.gh.mygreen.xlsmapper.ArgUtils; | ||
import com.gh.mygreen.xlsmapper.Utils; | ||
import com.github.mygreen.expression.el.FormatterWrapper; | ||
import com.github.mygreen.expression.el.tld.Function; | ||
import com.github.mygreen.expression.el.tld.Taglib; | ||
|
||
/** | ||
* EL式(EL 3.x)を使用するための実装。 | ||
* | ||
* @since 1.6 | ||
* @author T.TSUCHIE | ||
* | ||
*/ | ||
public class ExpressionLangaugeEL3Impl extends AbstractExpressionLanguageEL { | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(ExpressionLangaugeEL3Impl.class); | ||
|
||
@Override | ||
public Object evaluate(final String expression, final Map<String, ?> values) { | ||
|
||
ArgUtils.notEmpty(expression, "expression"); | ||
ArgUtils.notNull(values, "values"); | ||
|
||
try { | ||
final ELProcessor elProc = new ELProcessor(); | ||
|
||
final Map<String, Object> beans = new HashMap<String, Object>(); | ||
for (final Entry<String, ? > entry : values.entrySet()) { | ||
if(isFormatter(entry.getKey(), entry.getValue())) { | ||
// Formatterの場合は、ラップクラスを設定する。 | ||
beans.put(entry.getKey(), new FormatterWrapper((Formatter) entry.getValue())); | ||
} else { | ||
beans.put(entry.getKey(), entry.getValue()); | ||
} | ||
} | ||
|
||
elProc.getELManager().addBeanNameResolver(new LocalBeanNameResolver(beans)); | ||
|
||
// カスタムタグを登録する。 | ||
for(Taglib taglib : taglibList) { | ||
final String prefix = Utils.trimToEmpty(taglib.getShortName()); | ||
|
||
for(Function function : taglib.getFunctions()) { | ||
final String className = Utils.trimToEmpty(function.getFunctionClass()); | ||
final String signature = Utils.trimToEmpty(function.getFunctionSignature()); | ||
final String name = Utils.trimToEmpty(function.getName()); | ||
|
||
try { | ||
elProc.defineFunction(prefix, name, className, signature); | ||
|
||
} catch(ClassNotFoundException | NoSuchMethodException ex) { | ||
throw new ExpressionEvaluationException(String.format("Faild defined with EL function : [%s:%s].", className, signature), ex); | ||
} | ||
} | ||
} | ||
|
||
if(logger.isDebugEnabled()) { | ||
logger.debug("Evaluating EL expression: {}", expression); | ||
} | ||
|
||
return elProc.eval(expression); | ||
|
||
} catch (final ELException ex){ | ||
throw new ExpressionEvaluationException(String.format("Evaluating [%s] script with EL failed.", expression), ex); | ||
} | ||
} | ||
|
||
/** | ||
* EL3.0用の式中の変数のResolver。 | ||
* ・存在しない場合はnullを返す。 | ||
* | ||
*/ | ||
private class LocalBeanNameResolver extends BeanNameResolver { | ||
|
||
private final Map<String, Object> map; | ||
|
||
public LocalBeanNameResolver(final Map<String, ?> map) { | ||
this.map = new HashMap<>(map); | ||
} | ||
|
||
@Override | ||
public boolean isNameResolved(final String beanName){ | ||
// 存在しない場合はnullを返すように、必ずtrueを設定する。 | ||
return true; | ||
} | ||
|
||
@Override | ||
public Object getBean(final String beanName){ | ||
return map.get( beanName ); | ||
} | ||
|
||
@Override | ||
public void setBeanValue(String beanName, Object value){ | ||
map.put(beanName, value ); | ||
} | ||
|
||
} | ||
|
||
} |
Oops, something went wrong.