001package io.ebean.enhance.querybean;
002
003import java.util.Arrays;
004
005/**
006 * Detects if a class is a query bean.
007 * <p>
008 * Used by enhancement to detect when GETFIELD access on query beans should be replaced by
009 * appropriate method calls.
010 * </p>
011 */
012public class DetectQueryBean {
013
014  private final String[] entityPackages;
015
016  DetectQueryBean(String[] entityPackages) {
017    this.entityPackages = entityPackages;
018  }
019
020  @Override
021  public String toString() {
022    return Arrays.toString(entityPackages);
023  }
024
025  /**
026  * Return true if there are no known packages.
027  */
028  public boolean isEmpty() {
029    return entityPackages.length == 0;
030  }
031
032  /**
033  * Return the packages that entity beans are expected.
034  * Query beans are expected to be in a query sub-package.
035  */
036  String[] getEntityPackages() {
037    return entityPackages;
038  }
039
040  /**
041  * Return true if this class is a query bean using naming conventions for query beans.
042  */
043  public boolean isQueryBean(String owner) {
044
045    int subPackagePos = owner.lastIndexOf("/query/");
046    if (subPackagePos > -1) {
047      String suffix = owner.substring(subPackagePos);
048      if (isQueryBeanSuffix(suffix)) {
049        String domainPackage = owner.substring(0, subPackagePos + 1);
050        return isQueryBeanPackage(domainPackage);
051      }
052    }
053    return false;
054  }
055
056  /**
057  * Check that the class is in an expected package (sub package of a package containing entity beans).
058  */
059  private boolean isQueryBeanPackage(String domainPackage) {
060    for (String aPackage : entityPackages) {
061      if (domainPackage.startsWith(aPackage)) {
062        return true;
063      }
064    }
065    return false;
066  }
067
068  /**
069  * Check that the class follows query bean naming convention.
070  */
071  private boolean isQueryBeanSuffix(String suffix) {
072    return (suffix.startsWith("/query/Q") || suffix.startsWith("/query/assoc/Q"));
073  }
074}