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 true if this class is a query bean using naming conventions for query beans.
034   */
035  public boolean isQueryBean(String owner) {
036
037    int subPackagePos = owner.lastIndexOf("/query/");
038    if (subPackagePos > -1) {
039      String suffix = owner.substring(subPackagePos);
040      if (isQueryBeanSuffix(suffix)) {
041        String domainPackage = owner.substring(0, subPackagePos + 1);
042        return isQueryBeanPackage(domainPackage);
043      }
044    }
045    return false;
046  }
047
048  /**
049   * Check that the class is in an expected package (sub package of a package containing entity beans).
050   */
051  private boolean isQueryBeanPackage(String domainPackage) {
052    for (String aPackage : entityPackages) {
053      if (domainPackage.startsWith(aPackage)) {
054        return true;
055      }
056    }
057    return false;
058  }
059
060  /**
061   * Check that the class follows query bean naming convention.
062   */
063  private boolean isQueryBeanSuffix(String suffix) {
064    return (suffix.startsWith("/query/Q") || suffix.startsWith("/query/assoc/Q"));
065  }
066}