All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gwtplatform.dispatch.annotation.processor.ReflectionHelper Maven / Gradle / Ivy

There is a newer version: 1.6
Show newest version
/**
 * Copyright 2010 ArcBees Inc.
 * 
 * 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.gwtplatform.dispatch.annotation.processor;

import com.gwtplatform.dispatch.annotation.In;
import com.gwtplatform.dispatch.annotation.Optional;
import com.gwtplatform.dispatch.annotation.Order;
import com.gwtplatform.dispatch.annotation.Out;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.Elements;

/**
 * {@link ReflectionHelper} is an internal class that provides common routines
 * only used by the annotation processors.
 * 
 * @author Brendan Doherty 
 * @author Florian Sauter
 * @author Stephen Haberman (concept) 
 */
@SuppressWarnings("unchecked")
public class ReflectionHelper {

  private TypeElement classRepresenter;
  private ProcessingEnvironment environment;
  
  public ReflectionHelper(ProcessingEnvironment environment, TypeElement classRepresenter) {
    this.classRepresenter = classRepresenter;
    this.environment = environment;
  }
  
  public Collection filterConstantFields(Collection fieldElements) {
    return filterFields(fieldElements, Modifier.STATIC, Modifier.FINAL);
  }
  
  /**
   * Returns only fields which doesn't contain one of the passed modifiers.
   */
  public Collection filterFields(Collection fieldElements, Modifier... modifiers) {
    Collection filteredFields = new ArrayList();
    filteredFields.addAll(fieldElements);
    for (VariableElement fieldElement : fieldElements) {
      for (Modifier modifier : modifiers) {
        if (fieldElement.getModifiers().contains(modifier)) {
          filteredFields.remove(fieldElement);
          break;
        }
      }
    }
    return filteredFields;
  }
  
  /**
   * Returns only fields which doesn't annotated with one of the passed annotation.
   */
  public Collection filterFields(Collection fieldElements, Class... annotations) {
    Collection filteredFields = new ArrayList();
    filteredFields.addAll(fieldElements);
    for (VariableElement fieldElement : fieldElements) {
      for (Class passedAnnotation : annotations) {
        Annotation fieldAnnotation = fieldElement.getAnnotation(passedAnnotation);
        if (fieldAnnotation != null) {
          filteredFields.remove(fieldElement);
          break;
        }
      }
    }
    return filteredFields;
  }
  
  /**
   * Returns all fields annotated with the passed annotation classes.
   */
  public Collection getAnnotatedFields(Class... annotations) {
    Collection fieldsCopy = getFields();
    for (Class annotation : annotations) {
      Collection nonAnnotatedFields = filterFields(getFields(), annotation);
      fieldsCopy.removeAll(nonAnnotatedFields);
    }
    return fieldsCopy;
  }
  
  /**
   * Returns the class name. 
   * 

* For example:
* {@code com.gwtplatform.dispatch.shared.annotation.Foo} *

* @return the class name. */ public String getClassName() { return getPackageName() + '.' + getSimpleClassName(); } public TypeElement getClassRepresenter() { return classRepresenter; } /** * Returns all fields ordered that are {@link Modifier#FINAL} or {@link Modifier#STATIC}. */ public Collection getConstantFields() { return getModifierFields(Modifier.FINAL, Modifier.STATIC); } /** * Returns all fields. *

* Important: Fields are not sorted according to @{@link Order}! *

* To get these sorted use {@link ReflectionHelper#getOrderedFields()}. */ public Collection getFields() { List members = getElementUtils().getAllMembers(classRepresenter); return ElementFilter.fieldsIn(members); } /** * Returns all fields which contains {@link Modifier#FINAL}. */ public Collection getFinalFields() { return filterFields(getOrderedFields(), Modifier.FINAL); } /** * Returns all fields annotated with @{@link In}. */ public Collection getInFields() { return sortFields(In.class, getAnnotatedFields(In.class)); } /** * Returns all fields with the passed modifier. */ public Collection getModifierFields(Modifier... modifiers) { Collection modifierFields = new ArrayList(); modifierFields.addAll(getFields()); for (Modifier modifier : modifiers) { Collection nonModifierFields = filterFields(getFields(), modifier); modifierFields.removeAll(nonModifierFields); } return modifierFields; } /** * Returns all fields ordered that are not {@link Modifier#FINAL} or {@link Modifier#STATIC}. */ public Collection getNonConstantFields() { return filterFields(getOrderedFields(), Modifier.FINAL, Modifier.STATIC); } /** * Returns all non constant fields annotated with @{@link Optional}. Sorted based on the @ * {@link Order} annotation. */ public Collection getOptionalFields() { return sortFields(Order.class, filterConstantFields(getAnnotatedFields(Optional.class))); } /** * Returns all non constant fields annotated with passed annotation. *

* Important: Fields are not sorted! *

*/ public Collection getOptionalFields(Class annotation) { return filterConstantFields(getAnnotatedFields(Optional.class, annotation)); } /** * Returns all fields ordered. See {@link Order} for detailed informations. */ public Collection getOrderedFields() { return sortFields(Order.class, getFields()); } /** * Returns all fields annotated with @{@link Out}. */ public Collection getOutFields() { return sortFields(Out.class, getAnnotatedFields(Out.class)); } public String getPackageName() { return getElementUtils().getPackageOf(classRepresenter).getQualifiedName().toString(); } public ProcessingEnvironment getProcessingEnvironment() { return environment; } /** * Returns all non {@link Optional}|{@link Modifier#STATIC}| * {@link Modifier#FINAL} fields ordered. See {@link Order} for * detailed order informations. *

* Required are all: *

    *
  • Declared fields matching rules below
  • *
  • Non annotated {@link Optional} fields
  • *
  • Non {@link Modifier#STATIC} fields
  • *
  • Non {@link Modifier#FINAL} fields
  • *
*

*/ public Collection getRequiredFields() { Collection fields = getFields(); fields.removeAll(getOptionalFields()); fields = filterFields(fields, Modifier.FINAL, Modifier.STATIC); return sortFields(Order.class, fields); } public String getSimpleClassName() { return classRepresenter.getSimpleName().toString(); } /** * Returns all fields which contains {@link Modifier#STATIC}. */ public Collection getStaticFields() { return filterFields(getOrderedFields(), Modifier.STATIC); } /** * Sorts the passed fields based on the passed annotation sort logic. */ public Collection sortFields(Class annotation, Collection fields) { SortedMap sortedFields = new TreeMap(); if (In.class.equals(annotation)) { sortInFields(sortedFields, fields); } else if (Out.class.equals(annotation)) { sortOutFields(sortedFields, fields); } else if (Order.class.equals(annotation)) { sortOrderFields(sortedFields, fields); } else { return fields; } return sortedFields.values(); } /** * Utility method. */ protected Elements getElementUtils() { return environment.getElementUtils(); } protected void sortInFields(SortedMap sortedFields, Collection fields) { for (VariableElement fieldElement : fields) { In inFieldAnnotation = fieldElement.getAnnotation(In.class); if (inFieldAnnotation != null) { sortedFields.put(inFieldAnnotation.value(), fieldElement); } } } protected void sortOrderFields(SortedMap sortedFields, Collection fields) { int maxOrderNum = -1; for (VariableElement fieldElement : fields) { Order order = fieldElement.getAnnotation(Order.class); if (order != null) { maxOrderNum = Math.max(maxOrderNum, order.value()); } } for (VariableElement fieldDecl : fields) { Order order = fieldDecl.getAnnotation(Order.class); if (order != null) { maxOrderNum = Math.max(maxOrderNum, order.value()); sortedFields.put(order.value(), fieldDecl); } else { sortedFields.put(++maxOrderNum, fieldDecl); } } } protected void sortOutFields(SortedMap sortedFields, Collection fields) { for (VariableElement fieldElement : fields) { Out outFieldAnnotation = fieldElement.getAnnotation(Out.class); if (outFieldAnnotation != null) { sortedFields.put(outFieldAnnotation.value(), fieldElement); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy