001package com.avaje.ebean;
002
003import org.jetbrains.annotations.Nullable;
004
005import java.util.List;
006
007/**
008 * Intended to be used as a base class for 'Finder' implementations that can then
009 * be injected or used as public static fields on the associated entity bean.
010 * <p>
011 * These 'finders' are a place to organise all the finder methods for that bean type
012 * and specific finder methods are expected to be added (find by unique properties etc).
013 * </p>
014 *
015 * <h3>Testing</h3>
016 * <p>
017 *   For testing the mocki-ebean project has the ability to replace the finder implementation
018 *
019 * </p>
020 * <pre>{@code
021 *
022 * public class CustomerFinder extends Finder<Customer> {
023 *
024 *   public CustomerFinder() {
025 *     super(Customer.class);
026 *   }
027 *
028 *   // Add your customer finder methods ...
029 *
030 *   public Customer byName(String name) {
031 *     return query().eq("name", name).findUnique();
032 *   }
033 *
034 *   public List<Customer> findNew() {
035 *     return query()
036 *       .eq("status", Customer.Status.NEW)
037 *       .orderBy("name")
038 *       .findList()
039 *   }
040 * }
041 *
042 * @Entity
043 * public class Customer extends BaseModel {
044 *
045 *   public static final CustomerFinder find = new CustomerFinder();
046 *   ...
047 *
048 * }</pre>
049 */
050public class Finder<I, T> {
051
052  /**
053   * The entity bean type.
054   */
055  private final Class<T> type;
056
057  /**
058   * The name of the EbeanServer, null for the default server.
059   */
060  private final String serverName;
061
062  /**
063   * Create with the type of the entity bean.
064   *
065   * <pre>{@code
066   *
067   * public class CustomerFinder extends Finder<Customer> {
068   *
069   *   public CustomerFinder() {
070   *     super(Customer.class);
071   *   }
072   *
073   *   // ... add extra customer specific finder methods
074   * }
075   *
076   * @Entity
077   * public class Customer extends BaseModel {
078   *
079   *   public static final CustomerFinder find = new CustomerFinder();
080   *   ...
081   *
082   * }</pre>
083   */
084  public Finder(Class<T> type) {
085    this.type = type;
086    this.serverName = null;
087  }
088
089  /**
090   * Create with the type of the entity bean and specific server name.
091   */
092  public Finder(Class<T> type, String serverName) {
093    this.type = type;
094    this.serverName = serverName;
095  }
096
097  /**
098   * Return the underlying 'default' EbeanServer.
099   *
100   * <p>
101   * This provides full access to the API such as explicit transaction demarcation etc.
102   *
103   */
104  public EbeanServer db() {
105    return Ebean.getServer(serverName);
106  }
107
108  /**
109   * Return typically a different EbeanServer to the default.
110   * <p>
111   * This is equivalent to {@link Ebean#getServer(String)}
112   *
113   * @param server
114   *          The name of the EbeanServer. If this is null then the default EbeanServer is
115   *          returned.
116   */
117  public EbeanServer db(String server) {
118    return Ebean.getServer(server);
119  }
120
121  /**
122   * Creates an entity reference for this ID.
123   *
124   * <p>
125   * Equivalent to {@link EbeanServer#getReference(Class, Object)}
126   */
127  public T ref(I id) {
128    return db().getReference(type, id);
129  }
130
131  /**
132   * Retrieves an entity by ID.
133   *
134   * <p>
135   * Equivalent to {@link EbeanServer#find(Class, Object)}
136   */
137  @Nullable
138  public T byId(I id) {
139    return db().find(type, id);
140  }
141
142  /**
143   * Delete a bean by Id.
144   * <p>
145   * Equivalent to {@link EbeanServer#delete(Class, Object)}
146   */
147  public void deleteById(I id) {
148    db().delete(type, id);
149  }
150
151  /**
152   * Retrieves all entities of the given type.
153   */
154  public List<T> all() {
155    return query().findList();
156  }
157
158  /**
159   * Creates a query.
160   * <p>
161   * Equivalent to {@link EbeanServer#find(Class)}
162   */
163  public Query<T> query() {
164    return db().find(type);
165  }
166
167}