AnnotationInfo.java
- package com.gh.mygreen.xlsmapper.xml.bind;
- import java.io.Serializable;
- import java.lang.annotation.Annotation;
- import java.util.ArrayList;
- import java.util.List;
- import javax.xml.bind.annotation.XmlAccessType;
- import javax.xml.bind.annotation.XmlAccessorType;
- import javax.xml.bind.annotation.XmlAttribute;
- import javax.xml.bind.annotation.XmlElement;
- import javax.xml.bind.annotation.XmlValue;
- import com.gh.mygreen.xlsmapper.util.ArgUtils;
- import com.gh.mygreen.xlsmapper.util.Utils;
- import com.gh.mygreen.xlsmapper.xml.OgnlValueFormatter;
- /**
- * XMLのアノテーション情報を保持する。
- *
- * XMLの使用例:
- *
- * <pre class="highlight"><code class="xml">
- * {@literal <!-- 属性 「name」を持ち必須。--> }
- * {@literal <annotation name="net.java.amateras.xlsbeans.annotation.Sheet">}
- * {@literal <attribute name="name">'Users'</attribute>}
- * {@literal </annotation>}
- * </code></pre>
- *
- * @version 1.4.1
- * @since 0.5
- * @author T.TSUCHIE
- *
- */
- public class AnnotationInfo implements Serializable {
-
- /** serialVersionUID */
- private static final long serialVersionUID = 1L;
-
- /**
- * アノテーションのクラス名
- */
- private String className;
-
- private List<AttributeInfo> attributes = new ArrayList<>();
-
- /**
- * ビルダクラスのインスタンスを取得する。
- * @since 1.1
- * @return
- */
- public static Builder builder() {
- return new Builder();
- }
-
- /**
- * ビルダクラスのインスタンスを取得する。
- * @since 1.1
- * @param valueFormatter JavaオブジェクトをOGNL式に変換するためのクラス。
- * @return
- * @throws IllegalArgumentException valueFormatter is null.
- */
- public static Builder builder(final OgnlValueFormatter valueFormatter) {
- ArgUtils.notNull(valueFormatter, "valueFormatter");
- return new Builder(valueFormatter);
- }
-
- public AnnotationInfo() {
-
- }
-
- private AnnotationInfo(final Builder builder) {
- this.className = builder.className;
- setAttributeInfos(builder.attributeInfos);
- }
-
- @Override
- public String toString() {
-
- StringBuilder sb = new StringBuilder();
- sb.append("AnnotationInfo:")
- .append(String.format(" [name=%s]", getClassName()));
-
- for(AttributeInfo entry : attributes) {
- sb.append(String.format(" [(attr)%s=%s]", entry.name, entry.value));
- }
-
- return sb.toString();
-
- }
-
- /**
- * アノテーションのクラス名を取得する。
- * @return FQCN(完全限定クラス名)。
- */
- public String getClassName() {
- return className;
- }
-
- /**
- * アノテーションのクラス名を設定する。
- * @param className FQCN(完全限定クラス名)を指定します。
- * @throws IllegalArgumentException className is empty.
- */
- @XmlAttribute(name="name", required=true)
- public void setClassName(String className) {
- ArgUtils.notEmpty(className, "className");
- this.className = className;
- }
-
- /**
- * アノテーションの属性を追加する。
- * <p>ただし、既に同じ属性名が存在する場合は、それと入れ替えされます。</p>
- * @param name 属性名。必須です。
- * @param value 値。
- * <a href="http://s2container.seasar.org/2.4/ja/ognl.html" target="_blank">OGNL形式</a>で指定します。
- * @throws IllegalArgumentException name is empty.
- */
- public void addAttribute(final String name, final String value) {
- ArgUtils.notEmpty(name, "name");
- removeAttribute(name);
- this.attributes.add(AttributeInfo.create(name, value));
- }
-
- /**
- * アノテーションの属性名の一覧を取得する。
- * @return 属性名の一覧情報。
- */
- public String[] getAttributeKeys() {
-
- final List<String> list = new ArrayList<>(attributes.size());
- for(AttributeInfo item : attributes) {
- list.add(item.name);
- }
-
- return list.toArray(new String[list.size()]);
- }
-
- /**
- * アノテーションの属性名を指定して、アノテーションの値を取得する。
- * @param name 属性名。
- * @return 存在しない属性名の場合、nullを返します。
- */
- public String getAttribute(final String name) {
- for(AttributeInfo item : attributes) {
- if(item.name.equals(name)) {
- return item.value;
- }
- }
-
- return null;
- }
-
- /**
- * 指定したアノテーションの属性情報を含むかどうか。
- * @since 1.1
- * @param name アノテーションの属性名。
- * @return true: 指定したアノテーションの属性名が存在する場合。
- */
- public boolean containsAttribute(final String name) {
- return getAttribute(name) != null;
- }
-
- /**
- * 指定したアノテーションの属性情報を削除します。
- * @since 1.4.1
- * @param name アノテーションの属性名。
- * @return true:指定したアノテーション属性名を含み、それが削除できた場合。
- */
- public boolean removeAttribute(final String name) {
-
- AttributeInfo existInfo = null;
- for(AttributeInfo item : attributes) {
- if(item.name.equals(name)) {
- existInfo = item;
- break;
- }
-
- }
-
- if(existInfo != null) {
- this.attributes.remove(existInfo);
- return true;
- }
-
- return false;
-
- }
-
- /**
- * アノテーションの属性情報を保持するクラス。
- * <p>JAXBによるXMLのマッピングのために使用する。</p>
- *
- */
- @XmlAccessorType(XmlAccessType.FIELD)
- public static class AttributeInfo implements Serializable {
-
- /** serialVersionUID */
- private static final long serialVersionUID = 5570368711168203217L;
-
- @XmlAttribute(name="name", required=true)
- String name;
-
- @XmlValue
- String value;
-
- public static AttributeInfo create(final String name, final String value) {
-
- AttributeInfo attr = new AttributeInfo();
- attr.name = name;
- attr.value = value;
- return attr;
- }
-
- }
-
- /**
- * JAXB用のアノテーションの属性情報を設定するメソッド。
- * <p>XMLの読み込み時に呼ばれます。
- * <br>ただし、Java8からはこのメソッドは呼ばれず、{@link #getAttributeInfos()} で取得したインスタンスに対して要素が追加されます。
- * </p>
- * <p>既存の情報はクリアされます。</p>
- * @since 1.1
- * @param attributeInfos アノテーションの属性情報。
- */
- @XmlElement(name="attribute")
- public void setAttributeInfos(final List<AttributeInfo> attributeInfos) {
- if(attributeInfos == this.attributes) {
- // Java7の場合、getterで取得したインスタンスをそのまま設定するため、スキップする。
- return;
- }
-
- this.attributes.clear();
- for(AttributeInfo attr : attributeInfos) {
- addAttribute(attr.name, attr.value);
- }
- }
-
- /**
- * JAXB用のアノテーションの属性情報を取得するメソッド。
- * <p>XMLの書き込み時に呼ばれます。
- * <br>Java8から読み込み時に呼ばれるようになり、取得したインスタンスに対して、読み込んだ要素が呼ばれます。
- * </p>
- * @since 1.1
- * @return
- */
- public List<AttributeInfo> getAttributeInfos() {
- return attributes;
- }
-
- /**
- * {@link AnnotationInfo}を組み立てるためのクラス。
- *
- */
- public static final class Builder {
-
- private static final OgnlValueFormatter DEFAULT_VALUE_FORMATTER = new OgnlValueFormatter();
-
- private OgnlValueFormatter valueFormatter;
-
- private String className;
-
- private List<AttributeInfo> attributeInfos;
-
- private Builder() {
- this(DEFAULT_VALUE_FORMATTER);
- }
-
- private Builder(final OgnlValueFormatter valueFormatter) {
- this.valueFormatter = valueFormatter;
- this.attributeInfos = new ArrayList<>();
-
- }
-
- /**
- * 組み立てた{@link AnnotationInfo}のインスタンスを取得する。
- * @return
- */
- public AnnotationInfo buildAnnotation() {
- if(Utils.isEmpty(className)) {
- throw new IllegalStateException("class name is required.");
- }
-
- return new AnnotationInfo(this);
-
- }
-
- /**
- * アノテーションのクラス名を設定する。
- * @param className アノテーションのクラス名。FQCN(完全限定クラス名)を指定します。
- * @return
- * @throws IllegalArgumentException className is empty.
- */
- public Builder name(final String className) {
- ArgUtils.notEmpty(className, "className");
- this.className = className;
- return this;
- }
-
- /**
- * アノテーションのクラス名を設定する。
- * @param clazz アノテーションのクラス。
- * @return
- * @throws IllegalArgumentException clazz is null.
- */
- public Builder name(final Class<? extends Annotation> clazz) {
- ArgUtils.notNull(clazz, "clazz");
- return name(clazz.getName());
- }
-
- /**
- * アノテーションの属性値を設定する。
- * @param attrName 属性名
- * @param attrValue 属性の値。
- * <a href="http://s2container.seasar.org/2.4/ja/ognl.html" target="_blank">OGNL形式</a>で指定します。
- * @return
- * @throws IllegalArgumentException attrName is empty.
- */
- public Builder attributeWithNative(final String attrName, final String attrValue) {
- ArgUtils.notEmpty(attrName, "attrName");
- this.attributeInfos.add(AttributeInfo.create(attrName, attrValue));
- return this;
- }
-
- /**
- * アノテーションの属性値を設定する。
- * @param attrName 属性名
- * @param attrValue 属性の値。値は自動的にOGNLの書式に変換されて設定されます。
- * @return
- * @throws IllegalArgumentException attrName is empty.
- */
- public Builder attribute(final String attrName, final Object attrValue) {
- ArgUtils.notEmpty(attrName, "attrName");
-
- String ognlValue = valueFormatter.format(attrValue);
- attributeWithNative(attrName, ognlValue);
-
- return this;
- }
-
- }
-
- }