/**
* Copyright (c) 2009 Farata Systems http://www.faratasystems.com
*
* Licensed under The MIT License
* Re-distributions of files must retain the above copyright notice.
*
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*
*/
package com.farata.dto2extjs.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
/**
* Is used to translate the Java class into a matching Ext JS model
* <p>
* <table class="innertable">
* <tr>
* <th>Parameter</th><th>Type</th><th>Required</th><th>Description</th>
* </tr>
* <tr>
* <td><code>value</code></td><td>String</td><td>Optional</td>
* <td>A (fully qualified) name of the model (class). This is a default annotation parameter.
* If you omit this parameter the (fully qualified) Java name is taken verbatim and transformed
* according to the value of the APT option
<code>-Acom.faratasystems.dto2extjs.class-name-transformer</code> (see below)
* </td>
* </tr>
* <tr>
* <td><code>kind</code></td><td>JSClassKind</td><td>Optional.</td>
* <td>May be deprecate in the future. Do not use.</td>
* </tr>
* <tr>
* <td><code>ignoreSuperClasses</code></td><td>Class<?>[]</td><td>Optional</td>
* <td>Array of classes and interfaces in the Java inheritance chain that should be exempt from
* translation. By design every ancestor class and every interface implemented by a class annotated as @JSClass must in turn
* be annotated as @JSClass unless it is exempt via <code>ignoreSuperClasses</code>. Current version expects that developer
* will exempt all interfaces. In the future interfaces will be added as mixins.
* </td>
* </tr>
* </table>
*
* <p><b>Two Generated Classes per One Source</b>
* </p>
<p>
Each Java source is translated into a pair of base model class and it's subclass:
<li> a subclass model is reserved for manual changes and is regenerated only if you wipe out its file</i>;
<li> a base model is regenerated on every change of the Java source; you should not modify it</li>
</p>
<p>Assume that you annotated Java class <code>com.farata.clear.dto.UserDTO</code> with <code>@JSClass</code>. Let's also
say that the Ext JS application prefix is <code>MyApp</code> and you used APT paremeters (see below) to so that the output model name is <code>MyApp.model.clear.User</code>.
Then DTO2ExtJS will make two models: <code>MyApp.model.clear.User</code> extending <code>Myapp.model.clear.generated._User</code>. Your application
should make direct references only to <code>MyApp.model.clear.User</code>.
* </p>
* <p>
* The annotated Java is below. Keep in mind that parameter <code>-Acom.faratasystems.dto2extjs.class-name-transformer</code> is set to <code>MyApp.model.$1$3<<^com.farata.((\w+\.)*)dto.(\w+)DTO$</code></code>:
* <pre>
* package clear.dto;
* import com.farata.dto2extjs.annotations.JSClass;
* @JSClass
public class UserDTO {
public String id;
public Double salary;
private Date dob;
public Date getDob() {
return dob;
}
public void setDob(Date value) {
dob = value;
}
@JSOneToMany(foreignKey="userId", getter="getTickets")
public List<TicketDTO> tickets;
}
* </pre>
* </p>
* <p>
* First we show the base model - <code>MyApp.model.clear.generated._User</code>. Your
* code should not contain direct references to it:
* </p>
* <pre>// Generated by DTO2EXTJS from MyApp.model.clear.dto.UserDTO.java on 2012-02-16T20:45:29-05:00
Ext.define('MyApp.model.clear.generated._User', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.Types',
'MyApp.model.clear.Ticket'
],
fields: [
{
name: 'id',
type: Ext.data.Types.STRING,
useNull: true
},
{
name: 'salary',
type: Ext.data.Types.NUMBER,
useNull: true
},
{
name: 'dob',
type: Ext.data.Types.DATE,
useNull: true
}
],
hasMany: [
{
model: 'MyApp.model.clear.Ticket',
name: 'getTickets',
primaryKey:'id',
foreignKey:'userId',
autoLoad: true,
storeType:'MyApp.store.clear.TicketStore'
}
]
}
*</pre>
* <p>
* And here is subclass. This is the model to be used in your application, feel free to
* modify it with computer properties, etc.:
<pre>Ext.define('MyApp.model.clear.User, {
extend: 'MyApp.model.clear.generated._User'
});
</pre>
</p>
* <p>
* Base model carries a field for every Java public variable or getter/setter pair which
* has not been excluded by <a href="http://help.faratasystems.com/en_US/cleartoolkit/reference/java/extjs/com/farata/dto2extjs/annotations/JSIgnore.html">@JSIgnore</a>
* annotation.
* </p>
* <p><b>Downloading and Using DTO2ExtJS Annotation Processor in Eclipse Plugin</b></p>
* <p>
* <li>Copy into your <code>eclipse/plugins folder the jar downloaded from
* <a href="http://www.cleartoolkit.com/downloads/plugins/extjs/dto2extjs/com.farata.dto2extjs.asap_4.6.0.jar">http://www.cleartoolkit.com/downloads/plugins/extjs/dto2extjs/com.farata.dto2extjs.asap_4.6.0.jar</a></li>
* <li>Copy into <code>WebContent/lib</code> folder of your Dynamic Web Project annotations jar downloaded from
* <a href="http://www.cleartoolkit.com/downloads/plugins/extjs/dto2extjs/com.farata.dto2extjs.annotations.jar">http://www.cleartoolkit.com/downloads/plugins/extjs/dto2extjs/com.farata.dto2extjs.annotations.jar</a></li>
* <li>Use APT parameters to control placement and naming of the generated models as described below in in sections
<b>Placement of the Generated Models</b> and <b>Class Names of the Generated Models</b>.
* </li>
* </p>
* <p><b>Placement of the Generated Models</b>
* </p>
* <p>Location of the generated models depends on two APT parameters:
* <li><code>-Acom.faratasystems.dto2extjs.output</code> determines the root folder to place generated classes into. Expects path: absolute or relative to
* Eclipse workspace, such as <code>c:/dev/MyProject/web</code> or <code>MyProject/WebContent</code></li>
The <li><code>-Acom.faratasystems.dto2extjs.package-path-transformer</code> determines mapping between application namespace and root subfolder. If you
assign AM:app the classes will be created in the <code>WebContent/app</code> and they will belong to <code>AM</code> namespace, starting with <code>Ext.define("AM...</code></li>
</p>
* <p><b>Class Names of the Generated Models</b>
* </p>
* <p>Fully qualified name of the generated model is determined in two steps:
* <li>Unless you specify a JavaScript classname as the value or <code>@JSClass</code> it is taken verbatim from the Java source.</li>
* <li>Value of the annotation parameter <code>-Acom.faratasystems.dto2extjs.class-name-transformer</code>
* is used to transform it further:
* <table class="innertable" width="100%">
* <tr>
* <th>Setting</th><th>Java Class Name</th><th>Model Name</th>
* </tr>
* <tr>
* <td><code>AM.model</code></td><td>clear.dto.UserDTO</td><td>AM.model.clear.dto.UserDTO</td>
* </tr>
* <tr>
* <td><code>AM.model.$1$3<<^com.farata.((\w+\.)*)dto.(\w+)DTO$</code></td><td><code>com.farata.clear.dto.UserDTO</code></td><td><code>AM.model.clear.User</code></td>
* </tr>
* </table>
* </li>
* </p>
* <p>To inspect/modify APT parameters in Eclipse go to <i>Project Properties->Java Compiler->Annotation Processing->Processor Options</i>.
* </p>
* <p><b>Downloading and Using Clear Components for Ext JS </b></p>
* <p>
* To take full advantage of @JSOneToMany you need to use <a href="http://www.cleartoolkit.com/dokuwiki/doku.php?id=clearwiki:40.clear_components_ext">Clear Components for ExtJS</a>.
* In this case you get:
* <li> automatic injection of reference to the parent record to all "many" associated records on load;</li>
* <li> automatic batching of associated changes during <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.AbstractStore-method-sync">sync()</a>
* of the parent store, i.e. "deep sync".</li>
* </p>
* <p>
* To plug in Clear Components for Ext JS to your Ext JS MVC application copy the contents of ClearJS/src into the web root
* of your application and make sure that the main application script starts similar to the following:
<PRE>// app.js
Ext.Loader.setConfig({
disableCaching: false,
enabled: true,
paths : {
MyApp: 'app', Clear:'clear'
}
});
Ext.application({
name: 'MyApp',
requires: ['Clear.override.ExtJSOverrider'],
controllers: [
. . .
],
autoCreateViewport: true
});
</PRE>
* </p>
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface JSClass {
String value() default "";
JSClassKind kind() default JSClassKind.DEFAULT;
Class<?>[] ignoreSuperclasses() default {};
}