Package com.onpositive.gae.baseviewer

Source Code of com.onpositive.gae.baseviewer.ProjectMiner$AnnotationSearchRequestor

package com.onpositive.gae.baseviewer;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ArrayInitializer;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchParticipant;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.SearchRequestor;
import org.eclipse.jdt.internal.core.Annotation;
import org.eclipse.jdt.internal.core.CompilationUnit;
import org.eclipse.jdt.internal.core.ResolvedSourceType;
import org.eclipse.jdt.internal.core.SourceField;

import com.google.appengine.api.datastore.Blob;
import com.google.appengine.api.datastore.Category;
import com.google.appengine.api.datastore.Email;
import com.google.appengine.api.datastore.GeoPt;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.Link;
import com.google.appengine.api.datastore.PhoneNumber;
import com.google.appengine.api.datastore.PostalAddress;
import com.google.appengine.api.datastore.ShortBlob;
import com.google.appengine.api.datastore.Text;
import com.google.appengine.api.users.User;

public class ProjectMiner {

  public static final Class[] SUPPORTED_TYPES_FOR_JPA = new Class[] {
      boolean.class, byte.class, char.class, double.class, float.class,
      int.class, long.class, short.class, boolean[].class, byte[].class,
      char[].class, double[].class, float[].class, int[].class,
      long[].class, short[].class, java.lang.Boolean.class,
      java.lang.Byte.class, java.lang.Character.class,
      java.lang.Double.class, java.lang.Float.class,
      java.lang.Integer.class, java.lang.Long.class,
      java.lang.Short.class, java.lang.Boolean[].class,
      java.lang.Byte[].class, java.lang.Character[].class,
      java.lang.Double[].class, java.lang.Float[].class,
      java.lang.Integer[].class, java.lang.Long[].class,
      java.lang.Short[].class, java.lang.Number.class,
      java.lang.String.class, java.lang.StringBuffer.class,
      java.lang.String[].class, java.math.BigDecimal.class,
      java.math.BigInteger.class, java.math.BigDecimal[].class,
      java.math.BigInteger[].class, java.util.ArrayList.class,
      java.util.Collection.class, java.util.Currency.class,
      java.util.Date.class, java.util.Date[].class,
      java.util.HashSet.class, java.util.Hashtable.class,
      java.util.LinkedHashMap.class, java.util.LinkedHashSet.class,
      java.util.LinkedList.class, java.util.List.class,
      java.util.Locale.class, java.util.Locale[].class,
      java.util.Map.class, java.util.Set.class, java.util.TreeMap.class,
      java.util.TreeSet.class, java.util.Vector.class,
      java.lang.Enum.class, java.lang.Enum[].class, Blob.class,
      Key.class, Text.class, ShortBlob.class, Link.class, Category.class,
      Email.class, PostalAddress.class, PhoneNumber.class, GeoPt.class,
      User.class };

  public static class FieldInfo {
    public static final int COMPLETED = 0;
    public static final int INCOMPLETED = 1;

    private String name;
    private String enclosingType;
    private String fieldTypeName;
    private Class fieldType;

    public Class getFieldType() {
      return fieldType;
    }

    public void setFieldType(Class fieldType) {
      this.fieldType = fieldType;
    }

    private IField f;

    IField getF() {
      return f;
    }

    void setF(IField f) {
      this.f = f;
    }

    private int state;

    public int getState() {
      return state;
    }

    public void setState(int state) {
      this.state = state;
    }

    public FieldInfo(String name, String enclosingType, String fieldType,
        int state) {
      this.name = name;
      this.enclosingType = enclosingType;
      this.fieldTypeName = fieldType;
      this.state = state;
    }

    public String getName() {
      return name;
    }

    public void setName(String name) {
      this.name = name;
    }

    public String getEnclosingType() {
      return enclosingType;
    }

    public void setEnclosingType(String enclosingType) {
      this.enclosingType = enclosingType;
    }

    public String getFieldTypeName() {
      return fieldTypeName;
    }

    public void setFieldTypeName(String fieldType) {
      this.fieldTypeName = fieldType;
    }
  }

  protected static boolean isSupportedType(String simpleName) {
    boolean flag = false;
    if (simpleName != null) {

      for (Class t : SUPPORTED_TYPES_FOR_JPA) {
        String n = t.getSimpleName();
        if (n.equals(simpleName)) {
          flag = true;
          break;
        }
      }
    }
    return flag;
  }

  private static Class getSupported(String simpleName) {
    if (simpleName != null) {

      for (Class t : SUPPORTED_TYPES_FOR_JPA) {
        String n = t.getSimpleName();
        if (n.equals(simpleName)) {
          if (t.isPrimitive()) {
            if (t == float.class || t == double.class) {
              return Double.class;
            } else {
              return Long.class;
            }

          } else {
            return t;
          }
        }
      }
    }
    return null;
  }

  protected static final ArrayList<String> JPA_PERSISTENT_ANNOTATIONS_FOR_TYPES = new ArrayList();
  static {
    JPA_PERSISTENT_ANNOTATIONS_FOR_TYPES.add("Entity");
  }

  protected static final ArrayList<String> JDO_PERSISTENT_ANNOTATIONS_FOR_TYPES = new ArrayList();
  static {
    JDO_PERSISTENT_ANNOTATIONS_FOR_TYPES.add("PersistenceCapable");
  }

  protected static final ArrayList<String> JPA_PERSISTENT_ANNOTATIONS_FOR_FIELDS = new ArrayList();

  static {
    JPA_PERSISTENT_ANNOTATIONS_FOR_FIELDS.add("Basic");
    JPA_PERSISTENT_ANNOTATIONS_FOR_FIELDS.add("OneToOne");
    JPA_PERSISTENT_ANNOTATIONS_FOR_FIELDS.add("OneToMany");
    JPA_PERSISTENT_ANNOTATIONS_FOR_FIELDS.add("ManyToOne");
    JPA_PERSISTENT_ANNOTATIONS_FOR_FIELDS.add("ManyToMany");
  }

  protected static final ArrayList<String> JDO_PERSISTENT_ANNOTATIONS_FOR_FIELDS = new ArrayList();
  static {
    JDO_PERSISTENT_ANNOTATIONS_FOR_FIELDS.add("Persistent");
  }

  protected static final ArrayList<String> EMBEDDED_ANNOTATIONS_FOR_FIELDS = new ArrayList();
  static {
    EMBEDDED_ANNOTATIONS_FOR_FIELDS.add("Embedded");
    EMBEDDED_ANNOTATIONS_FOR_FIELDS.add("EmbeddedId");
  }

  protected class EmbeddedFieldsSearchRequestor extends SearchRequestor {

    private HashMap<String, FieldInfo> fields;
    private List<String> typeAnnotationSet;
    private String[] fieldsAnnotationSet;
    private String encType;

    private void setEncType(String encType) {
      this.encType = encType;
    }

    public String[] getFieldsAnnotationSet() {
      return fieldsAnnotationSet;
    }

    public void setFieldsAnnotationSet(String[] fieldsAnnotationSet) {
      this.fieldsAnnotationSet = fieldsAnnotationSet;
    }

    public void setFields(HashMap<String, FieldInfo> fields) {
      this.fields = fields;
    }

    public List<String> getAnnotationSet() {
      return typeAnnotationSet;
    }

    public void setTypeAnnotationSet(List<String> annotationSet) {
      this.typeAnnotationSet = annotationSet;
    }

    public HashMap<String, FieldInfo> getFields() {
      return fields;
    }

    public void acceptSearchMatch(SearchMatch match) throws CoreException {
      Object element = match.getElement();
      if (fields == null) {
        fields = new HashMap();
      }
      if (element instanceof IType) {
        IType rst = (IType) element;
        IAnnotation ia = null;
        ia = getAppropriateAnnotation(rst);
        if (ia != null && ia.exists()) {
          IField[] fields = rst.getFields();
          for (IField f : fields) {
            if (isCorrectField(f)) {
              int state = FieldInfo.COMPLETED;
              if (hasEmbeddedAnnotation(f)) {
                state = FieldInfo.INCOMPLETED;
              }
              String fName = f.getElementName();
              String tName = rst.getElementName();
              if (encType != null) {
                tName = encType;
              }
              String fType = Signature.toString(f
                  .getTypeSignature());
              FieldInfo fi = new FieldInfo(fName, tName, fType,
                  state);
              if (isSupportedType(fType)) {
                fi.setFieldType(getSupported(fType));
              }
              if (state == FieldInfo.INCOMPLETED) {
                fi.setF(f);
              }
              this.fields.put(fName, fi);
            }
          }
        }
      }
      return;
    }

    private boolean hasEmbeddedAnnotation(IField f) {
      for (String s : EMBEDDED_ANNOTATIONS_FOR_FIELDS) {
        IAnnotation a = f.getAnnotation(s);
        if (a != null && a.exists()) {
          return true;
        }
      }
      return false;
    }

    private boolean isCorrectField(IField f) {
      if (fieldsAnnotationSet == null || fieldsAnnotationSet.length == 0) {
        return true;
      }

      for (String s : fieldsAnnotationSet) {
        IAnnotation ia = f.getAnnotation(s);
        if (ia != null && ia.exists()) {
          return true;
        }
      }

      return false;
    }

    private IAnnotation getAppropriateAnnotation(IType t) {
      IAnnotation[] iaa;
      try {
        iaa = t.getAnnotations();
        for (IAnnotation ia : iaa) {
          String en = ia.getElementName();
          if (typeAnnotationSet.contains(en)) {
            return ia;
          }
        }
      } catch (JavaModelException e) {
        e.printStackTrace();
      }
      return null;
    }

  }

  protected class ReferenceChildSearchRequestor extends SearchRequestor {

    private ArrayList<String> types = new ArrayList();
    private List<String> annotationsSet;

    private boolean isJDO = false;

    private boolean isJDO() {
      return isJDO;
    }

    private void setJDO(boolean isJDO) {
      this.isJDO = isJDO;
    }

    public ArrayList<String> getTypes() {
      return types;
    }

    public void setTypes(ArrayList<String> types) {
      this.types = types;
    }

    public List<String> getAnnotationsSet() {
      return annotationsSet;
    }

    public void setAnnotationsSet(List<String> annotationsSet) {
      this.annotationsSet = annotationsSet;
    }

    public void acceptSearchMatch(SearchMatch match) throws CoreException {
      Object element = match.getElement();
      if (element instanceof IType) {
        IType rst = (IType) element;
        IAnnotation ia = null;
        ia = getAppropriateAnnotation(rst);
        if (ia != null && ia.exists()) {
          IAnnotation ia2 = rst.getAnnotation("Table");
          if (ia2 != null && ia2.exists()) {
            String name = rst.getFullyQualifiedName();
            String[] els = name.split("\\.");
            types.add(els[els.length - 1]);
          } else {
            String name = rst.getFullyQualifiedName();
            String[] els = name.split("\\.");
            types.add(els[els.length - 1]);
          }
        }
      }
      return;
    }

    public ArrayList<String> getFound() {
      return (ArrayList<String>) types.clone();
    }

    public void clear() {
      types.clear();
    }

    private IAnnotation getAppropriateAnnotation(IType t) {
      IAnnotation[] iaa;
      try {
        iaa = t.getAnnotations();
        for (IAnnotation ia : iaa) {
          String en = ia.getElementName();
          if (annotationsSet.contains(en)) {
            return ia;
          }
        }
      } catch (JavaModelException e) {
        e.printStackTrace();
      }
      return null;
    }

  }

  private String kind;
  private IJavaProject project;
  private ArrayList<IType> types;
  private IJavaSearchScope ijss;

  public ProjectMiner(String kind2, IJavaProject project2) {
    this.kind = kind2;
    this.project = project2;
    init();
  }

  protected HashMap<String, FieldInfo> getPossibleEmbeddedTypeMembers(
      final String typename, final IJavaSearchScope ijss,
      final String[] typeAnnotations, String[] fieldAnnotations,
      String encType) {
    SearchEngine eng = new SearchEngine();
    EmbeddedFieldsSearchRequestor efcr = new EmbeddedFieldsSearchRequestor();
    efcr.setTypeAnnotationSet(Arrays.asList(typeAnnotations));
    efcr.setFieldsAnnotationSet(fieldAnnotations);
    efcr.setEncType(encType);
    SearchPattern patternFirst = SearchPattern.createPattern(".*"
        + typename, IJavaSearchConstants.CLASS,
        IJavaSearchConstants.DECLARATIONS,
        SearchPattern.R_PATTERN_MATCH);

    try {
      eng.search(patternFirst, new SearchParticipant[] { SearchEngine
          .getDefaultSearchParticipant() }, ijss, efcr,
          new NullProgressMonitor());
      return efcr.getFields();
    } catch (CoreException e) {
      Activator.log(e);
    }
    return null;
  }

  protected ArrayList<String> getPossibleRelatedKinds(String typeName,
      IJavaSearchScope ijss, String[] annotationL) {
    SearchEngine eng = new SearchEngine();

    ReferenceChildSearchRequestor asr = new ReferenceChildSearchRequestor();
    if (annotationL != null && annotationL.length != 0) {
      asr.setAnnotationsSet((List<String>) Arrays.asList(annotationL));
    } else {
      asr.setAnnotationsSet(new ArrayList());
    }
    SearchPattern patternFirst = SearchPattern.createPattern(".*"
        + typeName, IJavaSearchConstants.CLASS,
        IJavaSearchConstants.DECLARATIONS,
        SearchPattern.R_PATTERN_MATCH);

    try {
      eng.search(patternFirst, new SearchParticipant[] { SearchEngine
          .getDefaultSearchParticipant() }, ijss, asr,
          new NullProgressMonitor());
      return asr.getFound();
    } catch (CoreException e) {
      Activator.log(e);
    }
    return null;
  }

  protected class SpecialAppEngSeacrhRequestor extends SearchRequestor {

    private ArrayList<IType> types = new ArrayList();

    public void acceptSearchMatch(SearchMatch match) throws CoreException {
      Object element = match.getElement();
      if (element instanceof IType) {
        IType rst = (IType) element;
        types.add(rst);
      }
      return;
    }

    public ArrayList<IType> getFound() {
      return (ArrayList<IType>) types.clone();
    }

    public void clear() {
      types.clear();
    }

  }

  public HashMap<String, Class> findAllPossibleFields(Set<String> childs) {

    try {

      HashMap<String, Class> fieldss = new HashMap();

      for (Iterator<IType> i = types.iterator(); i.hasNext();) {
        IType r = i.next();
        IAnnotation ia = r.getAnnotation("Entity");
        if (ia != null && ia.exists()) {
          IField[] fields = r.getFields();
          for (IField f : fields) {
            IField sf = (IField) f;
            if (sf instanceof SourceField) {
              SourceField ssf = (SourceField) sf;
              String sigString = ssf.getTypeSignature();
              IAnnotation[] ias = sf.getAnnotations();
              if (ias == null || ias.length == 0 && true) {
                sigString = Signature.getTypeErasure(sigString);
                String simpleName = Signature
                    .toString(sigString);

                String name = sf.getElementName();
                if (isSupportedType(simpleName)) {
                  fieldss.put(name, getSupported(simpleName));
                } else {
                  fieldss.put(name, Blob.class);
                }

              }
            }
          }
        } else {
          IAnnotation ib = r.getAnnotation("PersistenceCapable");
          if (ib != null && ib.exists()) {
            IField[] fields = r.getFields();
            for (IField f : fields) {
              IField sf = (IField) f;
              if (sf instanceof SourceField) {
                SourceField ssf = (SourceField) sf;
                String sigString = ssf.getTypeSignature();
                IAnnotation iaf = sf
                    .getAnnotation("Persistent");
                IAnnotation iaPk = sf
                    .getAnnotation("PrimaryKey");
                if (iaf != null && iaf.exists()
                    && (iaPk == null || !iaPk.exists())) {
                  sigString = Signature
                      .getTypeErasure(sigString);
                  String simpleName = Signature
                      .toString(sigString);

                  String name = sf.getElementName();
                  boolean flg = containsSerializedFlag(iaf);
                  if ((isSupportedType(simpleName) || flg)
                      && !childs.contains(name)) {

                    if (!flg) {
                      fieldss.put(name,
                          getSupported(simpleName));
                    } else {
                      if (isSupportedType(simpleName)) {
                        Class cl = getSupported(simpleName);
                        if (Collection.class
                            .isAssignableFrom(cl)) {
                          fieldss.put(name,
                              Collection.class);
                        }
                      } else {
                        fieldss.put(name, Blob.class);
                      }
                    }
                  }

                }
              }
            }
          }
        }
      }
      return fieldss;

    } catch (JavaModelException e) {
      e.printStackTrace();
    }
    return null;
  }

  private boolean containsSerializedFlag(IAnnotation ia) {
    if (ia instanceof Annotation) {
      @SuppressWarnings("restriction")
      Annotation a = (Annotation) ia;
      ICompilationUnit ic = a.getCompilationUnit();
      CompilationUnit cu = (CompilationUnit) ic;

      ASTParser astParser = ASTParser.newParser(AST.JLS3);
      astParser.setSource(cu.getContents());
      ASTNode node = astParser.createAST(new NullProgressMonitor());

      ASTNode aNode = a
          .findNode((org.eclipse.jdt.core.dom.CompilationUnit) node);
      if (aNode instanceof NormalAnnotation) {
        NormalAnnotation aA = (NormalAnnotation) aNode;
        List values = aA.values();
        for (Object exp : values) {
          if (exp instanceof MemberValuePair) {
            MemberValuePair mvp = (MemberValuePair) exp;
            String paramName = mvp.getName()
                .getFullyQualifiedName();
            if (paramName.startsWith("serialized")) {
              Expression val = mvp.getValue();
              if (val instanceof StringLiteral) {
                StringLiteral sl = (StringLiteral) val;
                if (sl.getLiteralValue().equals("true")) {
                  return true;
                }
              }
            }
          }
        }
        return false;
      }
    }
    return false;
  }

  private void init() {
    try {
      ArrayList<IJavaElement> elements = prepareJavaElementSet();

      ijss = SearchEngine.createJavaSearchScope(
          elements.toArray(new IJavaElement[elements.size()]),
          IJavaSearchScope.SOURCES);
      if (kind != null && kind.length() > 0) {
        types = findAllTypes(this.kind, elements);
      } else {
        types = new ArrayList<IType>();
      }
    } catch (CoreException e) {
      Activator.log(e);
      types = new ArrayList<IType>();
    }
  }

  private ArrayList<IType> findAllTypes(String ck,
      ArrayList<IJavaElement> elements) throws CoreException {
    SearchEngine eng = new SearchEngine();
    // AppSearchRequestor asr = new AppSearchRequestor();
    SpecialAppEngSeacrhRequestor sAsr = new SpecialAppEngSeacrhRequestor();

    SearchPattern patternFirst = SearchPattern.createPattern("*." + ck,
        IJavaSearchConstants.CLASS, IJavaSearchConstants.DECLARATIONS,
        SearchPattern.R_PATTERN_MATCH);

    eng.search(patternFirst, new SearchParticipant[] { SearchEngine
        .getDefaultSearchParticipant() }, ijss, sAsr,
        new NullProgressMonitor());
    ArrayList<IType> allTypes = sAsr.getFound();
    sAsr.clear();
    return allTypes;
  }

  public HashMap<String, String> findAllPossibleRelatedKindsForThisKind() {
    try {

      HashMap<String, String> full = new HashMap();
      if (types != null) {
        for (Iterator<IType> i = types.iterator(); i.hasNext();) {
          IType r = i.next();
          IField[] fields = r.getFields();
          for (IField f : fields) {
            IAnnotation iaJDO = isJDO(f);
            IAnnotation iaJPA = isJPA(f);

            if ((iaJDO != null && iaJDO.exists())
                || (iaJPA != null && iaJPA.exists())) {

              if (f instanceof IField) {
                IField sf = (IField) f;
                String s = sf.getTypeSignature();
                String name = Signature.toString(s);
                String[] ss = Signature.getTypeArguments(s);
                if (ss.length == 1) {
                  name = Signature.toString(ss[0]);
                }
                String valName = sf.getElementName();
                ArrayList<String> pch = null;
                if (iaJDO != null && iaJDO.exists()) {
                  pch = getPossibleRelatedKinds(
                      name,
                      ijss,
                      JDO_PERSISTENT_ANNOTATIONS_FOR_TYPES
                          .toArray(new String[JDO_PERSISTENT_ANNOTATIONS_FOR_TYPES
                              .size()]));
                } else if (iaJPA != null && iaJPA.exists()) {
                  pch = getPossibleRelatedKinds(
                      name,
                      ijss,
                      JPA_PERSISTENT_ANNOTATIONS_FOR_TYPES
                          .toArray(new String[JPA_PERSISTENT_ANNOTATIONS_FOR_TYPES
                              .size()]));
                }
                if (pch != null) {
                  for (Iterator<String> ii = pch.iterator(); ii
                      .hasNext();) {
                    String sss = ii.next();
                    full.put(valName, sss);
                  }
                }
              }
            }
          }
        }
      }
      return full;
    } catch (JavaModelException e) {
      Activator.log(e);
    }
    return new HashMap<String, String>();
  }

  private ArrayList<IJavaElement> prepareJavaElementSet()
      throws JavaModelException {
    ArrayList<IJavaElement> elements = new ArrayList<IJavaElement>();
    IPackageFragmentRoot[] elems = project.getAllPackageFragmentRoots();
    for (IPackageFragmentRoot ipfr : elems) {
      // if (ipfr.getKind() != IPackageFragmentRoot.K_SOURCE) {
      // continue;
      // }

      IJavaElement[] children = ipfr.getChildren();
      for (IJavaElement e : children) {
        elements.add(e);
      }
    }
    return elements;
  }

  private IAnnotation isJPA(IField f) {
    try {
      IAnnotation[] ia = f.getAnnotations();
      for (IAnnotation a : ia) {
        String name = a.getElementName();
        if (JPA_PERSISTENT_ANNOTATIONS_FOR_FIELDS.contains(name)
            && a.exists()) {
          return a;
        }
      }
    } catch (JavaModelException e) {
      e.printStackTrace();
    }

    return null;
  }

  private IAnnotation isJDO(IField f) {
    try {
      IAnnotation[] ia = f.getAnnotations();
      for (IAnnotation a : ia) {
        String name = a.getElementName();
        if (JDO_PERSISTENT_ANNOTATIONS_FOR_FIELDS.contains(name)
            && a.exists()) {
          return a;
        }
      }
    } catch (JavaModelException e) {
      e.printStackTrace();
    }

    return null;
  }

  protected class AnnotationSearchRequestor extends SearchRequestor {

    private ArrayList<String> entityName = new ArrayList();

    public ArrayList<String> getEntityName() {
      return entityName;
    }

    public void clear() {
      entityName.clear();
    }

    public void acceptSearchMatch(SearchMatch match) throws CoreException {
      Object element = match.getElement();
      if (element instanceof ResolvedSourceType) {
        ResolvedSourceType type = (ResolvedSourceType) element;
        String name = type.getElementName();
        entityName.add(name);
      }
      return;
    }

  }

  public String[] findAllPossibleKindsForProject() {
    try {
      SearchEngine engine = new SearchEngine();

      ArrayList<IJavaElement> elements = new ArrayList<IJavaElement>();
      IPackageFragmentRoot[] fragments = project
          .getPackageFragmentRoots();
      for (IPackageFragmentRoot fragment : fragments) {
        int elementType = fragment.getKind();
        /*
         * if (elementType != IPackageFragmentRoot.K_SOURCE) { continue;
         * }
         */

        IJavaElement[] children = fragment.getChildren();
        for (IJavaElement e : children) {
          elements.add(e);
        }
      }

      IJavaSearchScope ijss = SearchEngine.createJavaSearchScope(
          elements.toArray(new IJavaElement[elements.size()]),
          IJavaSearchScope.SOURCES);
      AnnotationSearchRequestor asr = new AnnotationSearchRequestor();

      SearchPattern patternFirst = SearchPattern.createPattern(
          "PersistenceCapable", IJavaSearchConstants.ANNOTATION_TYPE,
          IJavaSearchConstants.REFERENCES,
          SearchPattern.R_EXACT_MATCH);

      SearchPattern patternSecond = SearchPattern.createPattern("Entity",
          IJavaSearchConstants.ANNOTATION_TYPE,
          IJavaSearchConstants.REFERENCES,
          SearchPattern.R_EXACT_MATCH);

      engine.search(patternFirst, new SearchParticipant[] { SearchEngine
          .getDefaultSearchParticipant() }, ijss, asr,
          new NullProgressMonitor());
      ArrayList<String> full = new ArrayList<String>();
      full.addAll(asr.getEntityName());
      asr.clear();
      engine.search(patternSecond, new SearchParticipant[] { SearchEngine
          .getDefaultSearchParticipant() }, ijss, asr,
          new NullProgressMonitor());
      full.addAll(asr.getEntityName());
      return full.toArray(new String[full.size()]);

    } catch (JavaModelException e) {
      e.printStackTrace();
    } catch (CoreException e) {
      e.printStackTrace();
    }
    return null;
  }

  public HashMap<String, FieldInfo> getEmbeddedFields() {

    try {

      HashMap<String, FieldInfo> embeddedTypes = new HashMap();

      for (Iterator<IType> i = types.iterator(); i.hasNext();) {
        IType r = i.next();
        boolean isjdo = isJDO(r);
        boolean isjpa = isJPA(r);
        if (isjdo || isjpa) {
          IField[] fields = r.getFields();
          for (IField f : fields) {

            String name = Signature.toString(f.getTypeSignature());

            IAnnotation emb = isFieldEmbedded(f);
            if (emb != null && emb.exists()) {
              findAllRelatedFields(embeddedTypes, isjdo, f, name,
                  null);
            }
          }

          String key = isFieldsCompleted(embeddedTypes);
          while (key != null) {
            FieldInfo removed = embeddedTypes.remove(key);
            String name = removed.getFieldTypeName();
            String encType = removed.getEnclosingType();
            IField f = removed.getF();
            findAllRelatedFields(embeddedTypes, isjdo, f, name,
                encType);

            key = isFieldsCompleted(embeddedTypes);
          }

        }
      }
      return embeddedTypes;

    } catch (JavaModelException e) {
      e.printStackTrace();
    }
    return null;

  }

  private void findAllRelatedFields(HashMap<String, FieldInfo> embeddedTypes,
      boolean isjdo, IField f, String name, String encType) {
    HashMap<String, String> labels = null;
    HashMap<String, FieldInfo> res = null;
    if (isjdo) {

      labels = parseAnnotation(f, true);

      res = getPossibleEmbeddedTypeMembers(name, ijss,
          new String[] { "EmbeddedOnly" },
          new String[] { "Persistent" }, encType);

    } else {

      labels = parseAnnotation(f, false);
      res = getPossibleEmbeddedTypeMembers(name, ijss,
          new String[] { "Embeddable" }, new String[0], encType);

    }
    if (res != null) {
      if (labels != null && labels.size() != 0) {
        for (String l : labels.keySet()) {
          if (res.keySet().contains(l)) {
            FieldInfo e = res.get(l);

            String nn = labels.get(l);
            e.setName(nn);
            res.remove(l);

            res.put(nn, e);
          }
        }
      }
      embeddedTypes.putAll(res);
    }
  }

  private String isFieldsCompleted(Map<String, FieldInfo> fm) {
    for (String k : fm.keySet()) {
      FieldInfo fi = fm.get(k);
      if (fi.getState() == FieldInfo.INCOMPLETED) {
        return k;
      }
    }
    return null;
  }

  private HashMap<String, String> parseAnnotation(IField f, boolean isJdo) {
    IAnnotation emb = isFieldEmbedded(f);
    HashMap<String, String> elems = new HashMap();
    IAnnotation[] ias;
    if (isJdo) {
      try {
        ias = f.getAnnotations();

        String annotationSetName = "Embedded";
        String annotationName = "Persistent";
        String nameProp = "name";
        String colProp = "column";
        for (IAnnotation ia : ias) {
          if (ia.getElementName().equals(annotationSetName)) {
            Annotation a = (Annotation) ia;

            ICompilationUnit ic = a.getCompilationUnit();
            CompilationUnit cu = (CompilationUnit) ic;

            ASTParser astParser = ASTParser.newParser(AST.JLS3);
            astParser.setSource(cu.getContents());
            ASTNode node = astParser
                .createAST(new NullProgressMonitor());

            ASTNode aNode = a
                .findNode((org.eclipse.jdt.core.dom.CompilationUnit) node);
            if (aNode instanceof NormalAnnotation) {
              NormalAnnotation na = (NormalAnnotation) aNode;
              Expression exp = getAnnotationElement(na, "members");
              parseAnnotationListElement(elems, annotationName,
                  nameProp, colProp, exp);
            }
          }
        }
      } catch (JavaModelException e) {
        e.printStackTrace();
      }
    } else {
      try {
        ias = f.getAnnotations();
        String annotationSetName = "AttributeOverrides";
        String annotationName = "AttributeOverride";
        String nameProp = "name";
        String colProp = "column";

        for (IAnnotation ia : ias) {
          if (ia.getElementName().equals(annotationSetName)) {
            if (ia instanceof Annotation) {
              Annotation a = (Annotation) ia;

              ICompilationUnit ic = a.getCompilationUnit();
              CompilationUnit cu = (CompilationUnit) ic;

              ASTParser astParser = ASTParser.newParser(AST.JLS3);
              astParser.setSource(cu.getContents());
              ASTNode node = astParser
                  .createAST(new NullProgressMonitor());

              ASTNode aNode = a
                  .findNode((org.eclipse.jdt.core.dom.CompilationUnit) node);

              if (aNode instanceof SingleMemberAnnotation) {
                SingleMemberAnnotation sma = (SingleMemberAnnotation) aNode;
                Expression val = sma.getValue();
                parseAnnotationListElement(elems,
                    annotationName, nameProp, colProp, val);
              }
            }
          } else if (ia.getElementName().equals(annotationName)) {
            Annotation a = (Annotation) ia;

            ICompilationUnit ic = a.getCompilationUnit();
            CompilationUnit cu = (CompilationUnit) ic;

            ASTParser astParser = ASTParser.newParser(AST.JLS3);
            astParser.setSource(cu.getContents());
            ASTNode node = astParser
                .createAST(new NullProgressMonitor());

            ASTNode aNode = a
                .findNode((org.eclipse.jdt.core.dom.CompilationUnit) node);
            if (aNode instanceof NormalAnnotation) {
              parseAnnotationElement(elems, annotationName,
                  nameProp, colProp, aNode);
            }
          }
        }
      } catch (JavaModelException e) {
        e.printStackTrace();
      }
    }
    return elems;
  }

  protected void parseAnnotationListElement(HashMap<String, String> elems,
      String annotationName, String nameProp, String colProp,
      Expression exp) {
    if (exp instanceof ArrayInitializer) {
      ArrayInitializer ai = (ArrayInitializer) exp;
      List<Expression> expL = ai.expressions();
      for (Expression e : expL) {
        parseAnnotationElement(elems, annotationName, nameProp,
            colProp, e);
      }
    }
  }

  private void parseAnnotationElement(HashMap<String, String> elems,
      String annotationName, String nameProp, String colProp, ASTNode e) {
    if (e instanceof NormalAnnotation) {
      NormalAnnotation na = (NormalAnnotation) e;
      String naName = na.getTypeName().getFullyQualifiedName();
      if (naName.equals(annotationName)) {

        Expression nameEXP = getAnnotationElement(na, nameProp);
        Expression columnExp = getAnnotationElement(na, colProp);

        while (!(columnExp instanceof StringLiteral)) {
          columnExp = getAnnotationElement(columnExp, nameProp);
        }
        if (nameEXP instanceof StringLiteral
            && columnExp instanceof StringLiteral) {
          String nname = ((StringLiteral) nameEXP).getLiteralValue();
          String ccol = ((StringLiteral) columnExp).getLiteralValue();
          elems.put(nname, ccol);
        }

      }
    }
  }

  private Expression getAnnotationElement(Expression na, String name) {
    if (na instanceof StringLiteral) {
      return na;
    } else if (na instanceof NormalAnnotation) {
      NormalAnnotation nan = (NormalAnnotation) na;
      List val = nan.values();
      for (Object v : val) {
        if (v instanceof MemberValuePair) {
          MemberValuePair mvp = (MemberValuePair) v;
          if (mvp.getName().toString().startsWith(name)) {
            return mvp.getValue();
          }
        }
      }
    }
    return null;
  }

  private IAnnotation isFieldEmbedded(IField t) {

    for (String s : EMBEDDED_ANNOTATIONS_FOR_FIELDS) {
      IAnnotation emb = t.getAnnotation(s);
      if (emb != null && emb.exists()) {
        return emb;
      }
    }
    return null;
  }

  private boolean isJPA(IType t) {

    for (String s : JPA_PERSISTENT_ANNOTATIONS_FOR_TYPES) {
      IAnnotation iaJPA = t.getAnnotation(s);
      if (iaJPA != null && iaJPA.exists()) {
        return true;
      }
    }
    return false;
  }

  private boolean isJDO(IType t) {

    for (String s : JDO_PERSISTENT_ANNOTATIONS_FOR_TYPES) {
      IAnnotation iaJDO = t.getAnnotation(s);
      if (iaJDO != null && iaJDO.exists()) {
        return true;
      }
    }
    return false;
  }
}
TOP

Related Classes of com.onpositive.gae.baseviewer.ProjectMiner$AnnotationSearchRequestor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.