/** * Copyright 2011-2017 Asakusa Framework Team. * * 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 com.asakusafw.utils.java.model.util; import java.util.ArrayList; import java.util.List; import java.util.Map; import com.asakusafw.utils.java.model.syntax.Annotation; import com.asakusafw.utils.java.model.syntax.AnnotationElement; import com.asakusafw.utils.java.model.syntax.Attribute; import com.asakusafw.utils.java.model.syntax.Expression; import com.asakusafw.utils.java.model.syntax.ModelFactory; import com.asakusafw.utils.java.model.syntax.ModelKind; import com.asakusafw.utils.java.model.syntax.Modifier; import com.asakusafw.utils.java.model.syntax.ModifierKind; import com.asakusafw.utils.java.model.syntax.NamedType; import com.asakusafw.utils.java.model.syntax.Type; // CHECKSTYLE:OFF /** * A builder for building attributes of declarations. * @since 0.1.0 * @version 0.9.0 */ public class AttributeBuilder { private final ModelFactory f; private final List<Attribute> attributes; /** * Creates a new instance. * @param factory the Java DOM factory * @throws IllegalArgumentException if the parameter is {@code null} */ public AttributeBuilder(ModelFactory factory) { if (factory == null) { throw new IllegalArgumentException("factory must not be null"); //$NON-NLS-1$ } this.f = factory; this.attributes = new ArrayList<>(); } /** * Returns a copy of this builder. * @return the copy */ public AttributeBuilder copy() { AttributeBuilder copy = new AttributeBuilder(f); copy.attributes.addAll(attributes); return copy; } /** * Returns the attribute list which contains the added attributes as their order. * @return the attributes */ public List<Attribute> toAttributes() { return new ArrayList<>(attributes); } /** * Returns the Java modifier list which contains the added modifiers as their order. * Note that, each attribute which is not a modifier is ignored. * @return the Java modifiers */ public List<Modifier> toModifiers() { List<Modifier> results = new ArrayList<>(); for (Attribute attribute : toAttributes()) { if (attribute instanceof Modifier) { results.add((Modifier) attribute); } } return results; } /** * Returns the Java annotation list which contains the added annotations as their order. * Note that, each attribute which is not an annotation will be ignored. * @return the Java annotations */ public List<Annotation> toAnnotations() { List<Annotation> results = new ArrayList<>(); for (Attribute attribute : toAttributes()) { if (attribute instanceof Annotation) { results.add((Annotation) attribute); } } return results; } // CHECKSTYLE:OFF MethodNameCheck /** * Appends {@code public} modifier to this builder. * @return this */ public AttributeBuilder Public() { return modifier(ModifierKind.PUBLIC); } /** * Appends {@code protected} modifier to this builder. * @return this */ public AttributeBuilder Protected() { return modifier(ModifierKind.PROTECTED); } /** * Appends {@code private} modifier to this builder. * @return this */ public AttributeBuilder Private() { return modifier(ModifierKind.PRIVATE); } /** * Appends {@code static} modifier to this builder. * @return this */ public AttributeBuilder Static() { return modifier(ModifierKind.STATIC); } /** * Appends {@code abstract} modifier to this builder. * @return this */ public AttributeBuilder Abstract() { return modifier(ModifierKind.ABSTRACT); } /** * Appends {@code default} modifier to this builder. * @return this * @since 0.9.0 */ public AttributeBuilder Default() { return modifier(ModifierKind.DEFAULT); } /** * Appends {@code native} modifier to this builder. * @return this */ public AttributeBuilder Native() { return modifier(ModifierKind.NATIVE); } /** * Appends {@code final} modifier to this builder. * @return this */ public AttributeBuilder Final() { return modifier(ModifierKind.FINAL); } /** * Appends {@code synchronized} modifier to this builder. * @return this */ public AttributeBuilder Synchronized() { return modifier(ModifierKind.SYNCHRONIZED); } /** * Appends {@code transient} modifier to this builder. * @return this */ public AttributeBuilder Transient() { return modifier(ModifierKind.TRANSIENT); } /** * Appends {@code volatile} modifier to this builder. * @return this */ public AttributeBuilder Volatile() { return modifier(ModifierKind.VOLATILE); } /** * Appends {@code strictfp} modifier to this builder. * @return this */ public AttributeBuilder Strictfp() { return modifier(ModifierKind.STRICTFP); } // CHECKSTYLE:ON MethodNameCheck /** * Appends the modifier to this builder. * @param modifier the target modifier kind * @return this * @throws IllegalArgumentException if the parameter is {@code null} */ public AttributeBuilder modifier(ModifierKind modifier) { if (modifier == null) { throw new IllegalArgumentException("modifier must not be null"); //$NON-NLS-1$ } return chain(f.newModifier(modifier)); } /** * Appends the annotation to the builder. * @param type the annotation type * @return this * @throws IllegalArgumentException if the parameter is {@code null} */ public AttributeBuilder annotation(Type type) { if (type == null) { throw new IllegalArgumentException("type must not be null"); //$NON-NLS-1$ } if (type.getModelKind() != ModelKind.NAMED_TYPE) { throw new IllegalArgumentException("type must be a simple named-type"); //$NON-NLS-1$ } return annotation(f.newMarkerAnnotation((NamedType) type)); } /** * Appends the marker annotation to the builder. * @param type the annotation type * @return this * @throws IllegalArgumentException if the parameter is {@code null} */ public AttributeBuilder annotation(java.lang.reflect.Type type) { if (type == null) { throw new IllegalArgumentException("type must not be null"); //$NON-NLS-1$ } return annotation(Models.toType(f, type)); } /** * Appends the single element annotation to the builder. * @param type the annotation type * @param value the annotation value * @return this * @throws IllegalArgumentException if the parameters are {@code null} */ public AttributeBuilder annotation(Type type, Expression value) { if (type == null) { throw new IllegalArgumentException("type must not be null"); //$NON-NLS-1$ } if (type.getModelKind() != ModelKind.NAMED_TYPE) { throw new IllegalArgumentException("type must be a simple named-type"); //$NON-NLS-1$ } return annotation(f.newSingleElementAnnotation((NamedType) type, value)); } /** * Appends the single element annotation to the builder. * @param type the annotation type * @param value the annotation value * @return this * @throws IllegalArgumentException if the parameters are {@code null} */ public AttributeBuilder annotation(java.lang.reflect.Type type, Expression value) { if (type == null) { throw new IllegalArgumentException("type must not be null"); //$NON-NLS-1$ } return annotation(Models.toType(f, type), value); } /** * Adds the specified annotation. * @param type the target annotation type * @param elements the element name-value pairs * @return this * @throws IllegalArgumentException if some parameters were {@code null} * @since 0.5.1 */ public AttributeBuilder annotation(Type type, Map<? extends String, ? extends Expression> elements) { if (type == null) { throw new IllegalArgumentException("type must not be null"); //$NON-NLS-1$ } if (type.getModelKind() != ModelKind.NAMED_TYPE) { throw new IllegalArgumentException("type must be a simple named-type"); //$NON-NLS-1$ } if (elements == null) { throw new IllegalArgumentException("elements must not be null"); //$NON-NLS-1$ } List<AnnotationElement> elems = new ArrayList<>(); for (Map.Entry<? extends String, ? extends Expression> entry : elements.entrySet()) { elems.add(f.newAnnotationElement(f.newSimpleName(entry.getKey()), entry.getValue())); } return annotation(f.newNormalAnnotation((NamedType) type, elems)); } /** * Appends the annotation to the builder. * @param type the annotation type * @param elementName the element name * @param elementValue the element value * @return this * @throws IllegalArgumentException if the parameters are {@code null} */ public AttributeBuilder annotation( Type type, String elementName, Expression elementValue) { if (type == null) { throw new IllegalArgumentException("type must not be null"); //$NON-NLS-1$ } if (type.getModelKind() != ModelKind.NAMED_TYPE) { throw new IllegalArgumentException("type must be a simple named-type"); //$NON-NLS-1$ } if (elementName == null) { throw new IllegalArgumentException("elementName must not be null"); //$NON-NLS-1$ } if (elementValue == null) { throw new IllegalArgumentException("elementValue must not be null"); //$NON-NLS-1$ } List<AnnotationElement> elements = new ArrayList<>(); elements.add(f.newAnnotationElement(f.newSimpleName(elementName), elementValue)); return annotation(f.newNormalAnnotation((NamedType) type, elements)); } /** * Appends the annotation to the builder. * @param type the annotation type * @param elementName1 the element name (1) * @param elementValue1 the element value (1) * @param elementName2 the element name (2) * @param elementValue2 the element value (2) * @return this * @throws IllegalArgumentException if the parameters are {@code null} */ public AttributeBuilder annotation( Type type, String elementName1, Expression elementValue1, String elementName2, Expression elementValue2) { if (type == null) { throw new IllegalArgumentException("type must not be null"); //$NON-NLS-1$ } if (type.getModelKind() != ModelKind.NAMED_TYPE) { throw new IllegalArgumentException("type must be a simple named-type"); //$NON-NLS-1$ } if (elementName1 == null) { throw new IllegalArgumentException("elementName1 must not be null"); //$NON-NLS-1$ } if (elementValue1 == null) { throw new IllegalArgumentException("elementValue1 must not be null"); //$NON-NLS-1$ } if (elementName2 == null) { throw new IllegalArgumentException("elementName2 must not be null"); //$NON-NLS-1$ } if (elementValue2 == null) { throw new IllegalArgumentException("elementValue2 must not be null"); //$NON-NLS-1$ } List<AnnotationElement> elements = new ArrayList<>(); elements.add(f.newAnnotationElement(f.newSimpleName(elementName1), elementValue1)); elements.add(f.newAnnotationElement(f.newSimpleName(elementName2), elementValue2)); return annotation(f.newNormalAnnotation((NamedType) type, elements)); } /** * Appends the annotation to the builder. * @param type the annotation type * @param elementName1 the element name (1) * @param elementValue1 the element value (1) * @param elementName2 the element name (2) * @param elementValue2 the element value (2) * @param elementName3 the element name (3) * @param elementValue3 the element value (3) * @return this * @throws IllegalArgumentException if the parameters are {@code null} */ public AttributeBuilder annotation( Type type, String elementName1, Expression elementValue1, String elementName2, Expression elementValue2, String elementName3, Expression elementValue3) { if (type == null) { throw new IllegalArgumentException("type must not be null"); //$NON-NLS-1$ } if (type.getModelKind() != ModelKind.NAMED_TYPE) { throw new IllegalArgumentException("type must be a simple named-type"); //$NON-NLS-1$ } if (elementName1 == null) { throw new IllegalArgumentException("elementName1 must not be null"); //$NON-NLS-1$ } if (elementValue1 == null) { throw new IllegalArgumentException("elementValue1 must not be null"); //$NON-NLS-1$ } if (elementName2 == null) { throw new IllegalArgumentException("elementName2 must not be null"); //$NON-NLS-1$ } if (elementValue2 == null) { throw new IllegalArgumentException("elementValue2 must not be null"); //$NON-NLS-1$ } if (elementName3 == null) { throw new IllegalArgumentException("elementName3 must not be null"); //$NON-NLS-1$ } if (elementValue3 == null) { throw new IllegalArgumentException("elementValue3 must not be null"); //$NON-NLS-1$ } List<AnnotationElement> elements = new ArrayList<>(); elements.add(f.newAnnotationElement(f.newSimpleName(elementName1), elementValue1)); elements.add(f.newAnnotationElement(f.newSimpleName(elementName2), elementValue2)); elements.add(f.newAnnotationElement(f.newSimpleName(elementName3), elementValue3)); return annotation(f.newNormalAnnotation((NamedType) type, elements)); } /** * Appends the annotation to the builder. * @param type the annotation type * @param elementName1 the element name (1) * @param elementValue1 the element value (1) * @param elementName2 the element name (2) * @param elementValue2 the element value (2) * @param elementName3 the element name (3) * @param elementValue3 the element value (3) * @param elementName4 the element name (4) * @param elementValue4 the element value (4) * @return this * @throws IllegalArgumentException if the parameters are {@code null} */ public AttributeBuilder annotation( Type type, String elementName1, Expression elementValue1, String elementName2, Expression elementValue2, String elementName3, Expression elementValue3, String elementName4, Expression elementValue4) { if (type == null) { throw new IllegalArgumentException("type must not be null"); //$NON-NLS-1$ } if (type.getModelKind() != ModelKind.NAMED_TYPE) { throw new IllegalArgumentException("type must be a simple named-type"); //$NON-NLS-1$ } if (elementName1 == null) { throw new IllegalArgumentException("elementName1 must not be null"); //$NON-NLS-1$ } if (elementValue1 == null) { throw new IllegalArgumentException("elementValue1 must not be null"); //$NON-NLS-1$ } if (elementName2 == null) { throw new IllegalArgumentException("elementName2 must not be null"); //$NON-NLS-1$ } if (elementValue2 == null) { throw new IllegalArgumentException("elementValue2 must not be null"); //$NON-NLS-1$ } if (elementName3 == null) { throw new IllegalArgumentException("elementName3 must not be null"); //$NON-NLS-1$ } if (elementValue3 == null) { throw new IllegalArgumentException("elementValue3 must not be null"); //$NON-NLS-1$ } if (elementName4 == null) { throw new IllegalArgumentException("elementName4 must not be null"); //$NON-NLS-1$ } if (elementValue4 == null) { throw new IllegalArgumentException("elementValue4 must not be null"); //$NON-NLS-1$ } List<AnnotationElement> elements = new ArrayList<>(); elements.add(f.newAnnotationElement(f.newSimpleName(elementName1), elementValue1)); elements.add(f.newAnnotationElement(f.newSimpleName(elementName2), elementValue2)); elements.add(f.newAnnotationElement(f.newSimpleName(elementName3), elementValue3)); elements.add(f.newAnnotationElement(f.newSimpleName(elementName4), elementValue4)); return annotation(f.newNormalAnnotation((NamedType) type, elements)); } // CHECKSTYLE:OFF ParameterNumberCheck /** * Appends the annotation to the builder. * @param type the annotation type * @param elementName1 the element name (1) * @param elementValue1 the element value (1) * @param elementName2 the element name (2) * @param elementValue2 the element value (2) * @param elementName3 the element name (3) * @param elementValue3 the element value (3) * @param elementName4 the element name (4) * @param elementValue4 the element value (4) * @param elementName5 the element name (5) * @param elementValue5 the element value (5) * @return this * @throws IllegalArgumentException if the parameters are {@code null} */ public AttributeBuilder annotation( Type type, String elementName1, Expression elementValue1, String elementName2, Expression elementValue2, String elementName3, Expression elementValue3, String elementName4, Expression elementValue4, String elementName5, Expression elementValue5) { if (type == null) { throw new IllegalArgumentException("type must not be null"); //$NON-NLS-1$ } if (type.getModelKind() != ModelKind.NAMED_TYPE) { throw new IllegalArgumentException("type must be a simple named-type"); //$NON-NLS-1$ } if (elementName1 == null) { throw new IllegalArgumentException("elementName1 must not be null"); //$NON-NLS-1$ } if (elementValue1 == null) { throw new IllegalArgumentException("elementValue1 must not be null"); //$NON-NLS-1$ } if (elementName2 == null) { throw new IllegalArgumentException("elementName2 must not be null"); //$NON-NLS-1$ } if (elementValue2 == null) { throw new IllegalArgumentException("elementValue2 must not be null"); //$NON-NLS-1$ } if (elementName3 == null) { throw new IllegalArgumentException("elementName3 must not be null"); //$NON-NLS-1$ } if (elementValue3 == null) { throw new IllegalArgumentException("elementValue3 must not be null"); //$NON-NLS-1$ } if (elementName4 == null) { throw new IllegalArgumentException("elementName4 must not be null"); //$NON-NLS-1$ } if (elementValue4 == null) { throw new IllegalArgumentException("elementValue4 must not be null"); //$NON-NLS-1$ } if (elementName5 == null) { throw new IllegalArgumentException("elementName5 must not be null"); //$NON-NLS-1$ } if (elementValue5 == null) { throw new IllegalArgumentException("elementValue5 must not be null"); //$NON-NLS-1$ } List<AnnotationElement> elements = new ArrayList<>(); elements.add(f.newAnnotationElement(f.newSimpleName(elementName1), elementValue1)); elements.add(f.newAnnotationElement(f.newSimpleName(elementName2), elementValue2)); elements.add(f.newAnnotationElement(f.newSimpleName(elementName3), elementValue3)); elements.add(f.newAnnotationElement(f.newSimpleName(elementName4), elementValue4)); elements.add(f.newAnnotationElement(f.newSimpleName(elementName5), elementValue5)); return annotation(f.newNormalAnnotation((NamedType) type, elements)); } // CHECKSTYLE:ON ParameterNumberCheck /** * Appends the annotation to the builder. * @param annotation the target annotation * @return this * @throws IllegalArgumentException if the parameter is {@code null} */ public AttributeBuilder annotation(Annotation annotation) { if (annotation == null) { throw new IllegalArgumentException("annotation must not be null"); //$NON-NLS-1$ } return chain(annotation); } private AttributeBuilder chain(Attribute attribute) { assert attribute != null; attributes.add(attribute); return this; } }