package clear.cdb.extjs.annotations; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Is used to generate descendants of the <code>Clear.data.DirectStore</code> with specific <code>model</code> and <code>api</code> config properties. * <p> * By default, package and name of the generated store class is derived from the transfer type (see below) of the method by adding a <code>Store</code> suffix. * For instance, if transfer type is <code>com.farata.example.dto.CompanyDTO</code> , generated store will be <code>store.com.farata.example.CompanyStore</code> * You can change the naming schema of the generated store by playing with the value of * the APT parameter <code>com.faratasystems.cdbjs.store.class-name-transformer</code> located in <code>.settings/org.eclipse.apt.core.prefs</code>: * <table class="innertable" width="100%"> * <tr> * <th>Setting</th><th>Java Class Name</th><th>Model Name</th> * </tr> * <tr> * <td><code>MyApp.store</code></td><td>com.farata.dto.UserDTO</td><td>MyApp.store.com.farata.dto.UserDTO</td> * </tr> * <tr> * <td><code>MyApp.store.$1$3<<^com.farata.((\w+\.)*)dto.(\w+)DTO$</code></td><td><code>com.farata.example.dto.UserDTO</code></td><td><code>MyApp.store.example.User</code></td> * </tr> * <tr> * <td><code>MyApp.store.$1$3Store<<^com.farata.((\w+\.)*)dto.(\w+)DTO$</code></td><td><code>com.farata.example.dto.UserDTO</code></td><td><code>MyApp.store.example.UserStore</code></td> * </tr> * </table> * </> * </p> * <p>Transfer type gets determined in the following order: * <li>if return type of the annotated method is not raw and does not contain a wildcard then the base type of the collection becomes the * transfer type;</li> * <li>if the method is annotated with <code>@JSJPQLMethod</code> annotation with the <code>transferInfo</code> parameter, the <code>type</code> subparameter of * the <code>transferInfo</code> becomes the transfer type;</li> * <li>if none of the above conditions are met, transfer type remains unknown</li> * </p> * <p>If transfer type is not known, developer has to explicitly provide the value of the <code>storeType</code> parameter, otherwise no collection * will be generated at all. A special care has to be taken of the related @JSOneToMany annotations preceding getters of such transfer type: developer has to * explicitly provide the same value of the <code>storeType</code> there as well. * </p> * <p> * Example 1: When the transfer type is known, it is recommended to rely on default naming of the generated store. Here, based on the * known transfer type - <code>com.farata.test.entity.Company</code> - code generator will create <code>store.com.farata.test.entity.CompanyStore</code>: * <pre> * @JSGenerateStore * @JSJPQLMethod( * query="SELECT c FROM Company c" * ) * List<com.farata.test.entity.Company> getCompanies(); * </pre> * </p> * <p> * Example 2: When the transfer type is not known, <code>storeType</code> has to be provided by the developer explicitly: * <pre> * @JSGenerateStore(storeType="store.com.farata.CompanyStore") * @JSJPQLMethod( * query="SELECT c FROM Company c" * ) * List<?> getCompanies(); * </pre> * </p> * <p> * Example 3: In relation with Example 2, <code>@JSOneToMany</code> annotation of the <code>companyAssociates</code> property * in the <code>com.farata.test.entity.Company</code> class has to explicitly specify the <code>storeType</code> to match * that of the related <code>@JSGenerateStore</code> annotation: * <pre> * @JSOneToMany(foreignKey="companyId", storeType="store.com.farata.CompanyStore") * public List<CompanyAssociate> companyAssociates; * </pre> * </p> */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface JSGenerateStore { /** * Fully qualified name of the DataCollection descendant, i.e. "com.farata.test.collections.CompanyCollection". * @return */ String storeType() default ""; }