json/src/main/java/net/java/html/json/OnReceive.java
author Jaroslav Tulach <jtulach@netbeans.org>
Wed, 09 Dec 2015 21:39:13 +0100
changeset 1023 4f906bde3a2e
parent 940 bdec4103bdb2
permissions -rw-r--r--
#257039: @Model.instance() to allow storage of private (and non-JSON like) state in a model
jtulach@0
     1
/**
jaroslav@358
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
jtulach@0
     3
 *
jaroslav@551
     4
 * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
jtulach@0
     5
 *
jaroslav@358
     6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
jaroslav@358
     7
 * Other names may be trademarks of their respective owners.
jtulach@0
     8
 *
jaroslav@358
     9
 * The contents of this file are subject to the terms of either the GNU
jaroslav@358
    10
 * General Public License Version 2 only ("GPL") or the Common
jaroslav@358
    11
 * Development and Distribution License("CDDL") (collectively, the
jaroslav@358
    12
 * "License"). You may not use this file except in compliance with the
jaroslav@358
    13
 * License. You can obtain a copy of the License at
jaroslav@358
    14
 * http://www.netbeans.org/cddl-gplv2.html
jaroslav@358
    15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
jaroslav@358
    16
 * specific language governing permissions and limitations under the
jaroslav@358
    17
 * License.  When distributing the software, include this License Header
jaroslav@358
    18
 * Notice in each file and include the License file at
jaroslav@358
    19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
jaroslav@358
    20
 * particular file as subject to the "Classpath" exception as provided
jaroslav@358
    21
 * by Oracle in the GPL Version 2 section of the License file that
jaroslav@358
    22
 * accompanied this code. If applicable, add the following below the
jaroslav@358
    23
 * License Header, with the fields enclosed by brackets [] replaced by
jaroslav@358
    24
 * your own identifying information:
jaroslav@358
    25
 * "Portions Copyrighted [year] [name of copyright owner]"
jaroslav@358
    26
 *
jaroslav@358
    27
 * Contributor(s):
jaroslav@358
    28
 *
jaroslav@358
    29
 * The Original Software is NetBeans. The Initial Developer of the Original
jaroslav@551
    30
 * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
jaroslav@358
    31
 *
jaroslav@358
    32
 * If you wish your version of this file to be governed by only the CDDL
jaroslav@358
    33
 * or only the GPL Version 2, indicate your decision by adding
jaroslav@358
    34
 * "[Contributor] elects to include this software in this distribution
jaroslav@358
    35
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
jaroslav@358
    36
 * single choice of license, a recipient has the option to distribute
jaroslav@358
    37
 * your version of this file under either the CDDL, the GPL Version 2 or
jaroslav@358
    38
 * to extend the choice of license to its licensees as provided above.
jaroslav@358
    39
 * However, if you add GPL Version 2 code and therefore, elected the GPL
jaroslav@358
    40
 * Version 2 license, then the option applies only if the new code is
jaroslav@358
    41
 * made subject to such option by the copyright holder.
jtulach@0
    42
 */
jtulach@0
    43
package net.java.html.json;
jtulach@0
    44
jtulach@0
    45
import java.lang.annotation.ElementType;
jtulach@0
    46
import java.lang.annotation.Retention;
jtulach@0
    47
import java.lang.annotation.RetentionPolicy;
jtulach@0
    48
import java.lang.annotation.Target;
jtulach@0
    49
jaroslav@32
    50
/** Static methods in classes annotated by {@link Model}
jtulach@940
    51
 * can be marked by this annotation to establish a
jtulach@0
    52
 * <a href="http://en.wikipedia.org/wiki/JSON">JSON</a>
jtulach@647
    53
 * communication point. The first argument should be the
jtulach@647
    54
 * associated {@link Model} class. The second argument can
jtulach@647
    55
 * be another class generated by {@link Model} annotation,
jtulach@647
    56
 * or array of such classes or (since 0.8.1 version) a
jtulach@647
    57
 * {@link java.util.List} of such classes.
jaroslav@32
    58
 * The associated model class then gets new method to invoke a network
jtulach@647
    59
 * connection asynchronously. Example follows:
jtulach@940
    60
 *
jtulach@0
    61
 * <pre>
jaroslav@32
    62
 * {@link Model @Model}(className="MyModel", properties={
jtulach@0
    63
 *   {@link Property @Property}(name = "people", type=Person.class, array=true)
jtulach@0
    64
 * })
jtulach@0
    65
 * class MyModelImpl {
jtulach@0
    66
 *   {@link Model @Model}(className="Person", properties={
jtulach@0
    67
 *     {@link Property @Property}(name = "firstName", type=String.class),
jtulach@0
    68
 *     {@link Property @Property}(name = "lastName", type=String.class)
jtulach@0
    69
 *   })
jtulach@0
    70
 *   static class PersonImpl {
jtulach@0
    71
 *     {@link ComputedProperty @ComputedProperty}
jtulach@0
    72
 *     static String fullName(String firstName, String lastName) {
jtulach@0
    73
 *       return firstName + " " + lastName;
jtulach@0
    74
 *     }
jtulach@0
    75
 *   }
jtulach@940
    76
 *
jtulach@0
    77
 *   {@link OnReceive @OnReceive}(url = "{protocol}://your.server.com/person/{name}")
jtulach@0
    78
 *   static void getANewPerson(MyModel m, Person p) {
jaroslav@600
    79
 *     System.out.println("Adding " + p.getFullName() + '!');
jtulach@0
    80
 *     m.getPeople().add(p);
jtulach@0
    81
 *   }
jtulach@940
    82
 *
jtulach@0
    83
 *   // the above will generate method <code>getANewPerson</code> in class <code>MyModel</code>.
jtulach@0
    84
 *   // with <code>protocol</code> and <code>name</code> arguments
jtulach@0
    85
 *   // which asynchronously contacts the server and in case of success calls
jtulach@0
    86
 *   // your {@link OnReceive @OnReceive} with parsed in data
jtulach@940
    87
 *
jaroslav@32
    88
 *   {@link Function @Function}
jtulach@0
    89
 *   static void requestSmith(MyModel m) {
jtulach@0
    90
 *     m.getANewPerson("http", "Smith");
jtulach@0
    91
 *   }
jtulach@0
    92
 * }
jtulach@0
    93
 * </pre>
jtulach@0
    94
 * When the server returns <code>{ "firstName" : "John", "lastName" : "Smith" }</code>
jtulach@940
    95
 * the system will print a message <em>Adding John Smith!</em>. It is not
jaroslav@613
    96
 * necessary to fully describe the server message - enumerate only the fields
jaroslav@613
    97
 * in the response you are interested in. The others will be discarded. So,
jaroslav@613
    98
 * if the server <code>{ "firstName" : "John", "lastName" : "Smith", "age" : 33 }</code>
jaroslav@613
    99
 * the above code will behave the same (e.g. ignore the <code>age</code>
jaroslav@613
   100
 * value).
jaroslav@291
   101
 * <p>
jaroslav@291
   102
 * One can use this method to communicate with the server
jaroslav@291
   103
 * via <a href="doc-files/websockets.html">WebSocket</a> protocol since version 0.6.
jaroslav@291
   104
 * Read the <a href="doc-files/websockets.html">tutorial</a> to see how.
jtulach@1023
   105
 * The method shall be non-private
jtulach@1023
   106
 * and unless {@link Model#instance() instance mode} is on also static.
jaroslav@549
   107
 * <p>
jaroslav@549
   108
 * Visit an <a target="_blank" href="http://dew.apidesign.org/dew/#7138581">on-line demo</a>
jaroslav@549
   109
 * to see REST access via {@link OnReceive} annotation.
jtulach@940
   110
 *
jtulach@790
   111
 * @author Jaroslav Tulach
jaroslav@292
   112
 * @since 0.3
jtulach@0
   113
 */
jtulach@0
   114
@Retention(RetentionPolicy.SOURCE)
jtulach@0
   115
@Target(ElementType.METHOD)
jtulach@0
   116
public @interface OnReceive {
jtulach@0
   117
    /** The URL to connect to. Can contain variable names surrounded by '{' and '}'.
jtulach@940
   118
     * Those names will then become parameters of the associated method.
jtulach@940
   119
     *
jtulach@0
   120
     * @return the (possibly parametrized) url to connect to
jtulach@0
   121
     */
jtulach@0
   122
    String url();
jtulach@940
   123
jtulach@940
   124
    /** Specifies HTTP request headers. Array of header lines
jtulach@940
   125
     * can contain variable names surrounded by '{' and '}'.
jtulach@940
   126
     * Those names will then become parameters of the associated method
jtulach@940
   127
     * (in addition to those added by {@link #url()} specification)
jtulach@940
   128
     * and can only be used with plain JSON(P) requests.
jtulach@940
   129
     * Headers are currently <b>not</b> supported by the
jtulach@940
   130
     * <a href="doc-files/websockets.html">WebSockets protocol</a>.
jtulach@940
   131
     * A sample follows. If you want to transmit <b>X-Birthday</b> header,
jtulach@940
   132
     * you can do it like this:
jtulach@940
   133
     * <pre>
jtulach@940
   134
     * {@code @}{@link OnReceive}(url="http://your.server.org", headers = {
jtulach@940
   135
     *   "X-Birthday: {dayOfBirth}"
jtulach@940
   136
     * })
jtulach@940
   137
     * <b>static void</b> knowingTheBirth({@link Model YourModel} model) {
jtulach@940
   138
     *   // handle the reply
jtulach@940
   139
     * }</pre>
jtulach@940
   140
     * a method <b>knowingTheBirth</b> is generated in
jtulach@940
   141
     * <code>YourModel</code> class with the <code>dayOfBirth</code> argument
jtulach@940
   142
     * which can be called like this:
jtulach@940
   143
     * <pre>
jtulach@940
   144
     * yourModel.knowingTheBirth("10. 12. 1973");
jtulach@940
   145
     * </pre>
jtulach@940
   146
     *
jtulach@940
   147
     * @return array of header lines - each line should be plain text with
jtulach@940
   148
     *   a header name, followed by ":" and value usually specified as
jtulach@940
   149
     *   '{' and '}' surrounded variable. The line shouldn't contain
jtulach@940
   150
     *   newline or other control characters
jtulach@940
   151
     * @since 1.2
jtulach@940
   152
     */
jtulach@940
   153
    String[] headers() default {};
jtulach@940
   154
jtulach@0
   155
    /** Support for <a href="http://en.wikipedia.org/wiki/JSONP">JSONP</a> requires
jtulach@0
   156
     * a callback from the server generated page to a function defined in the
jtulach@0
   157
     * system. The name of such function is usually specified as a property
jtulach@0
   158
     * (of possibly different names). By defining the <code>jsonp</code> attribute
jtulach@940
   159
     * one turns on the <a href="http://en.wikipedia.org/wiki/JSONP">JSONP</a>
jtulach@0
   160
     * transmission and specifies the name of the property. The property should
jtulach@0
   161
     * also be used in the {@link #url()} attribute on appropriate place.
jtulach@940
   162
     *
jtulach@0
   163
     * @return name of a property to carry the name of <a href="http://en.wikipedia.org/wiki/JSONP">JSONP</a>
jtulach@0
   164
     *    callback function.
jtulach@0
   165
     */
jtulach@0
   166
    String jsonp() default "";
jtulach@940
   167
jaroslav@70
   168
    /** The model class to be send to the server as JSON data.
jaroslav@70
   169
     * By default no data are sent. However certain {@link #method() transport methods}
jtulach@940
   170
     * (like <code>"PUT"</code> and <code>"POST"</code>) require the
jaroslav@70
   171
     * data to be specified.
jtulach@940
   172
     *
jaroslav@70
   173
     * @return name of a class generated using {@link Model @Model} annotation
jaroslav@70
   174
     * @since 0.3
jaroslav@70
   175
     */
jaroslav@70
   176
    Class<?> data() default Object.class;
jtulach@940
   177
jaroslav@70
   178
    /** The HTTP transfer method to use. Defaults to <code>"GET"</code>.
jtulach@940
   179
     * Other typical methods include <code>"HEAD"</code>,
jaroslav@70
   180
     * <code>"DELETE"</code>, <code>"POST"</code>, <code>"PUT"</code>.
jaroslav@70
   181
     * The last two mentioned methods require {@link #data()} to be specified.
jaroslav@70
   182
     * <p>
jtulach@940
   183
     * When {@link #jsonp() JSONP} transport is requested, the method
jaroslav@70
   184
     * has to be <code>"GET"</code>.
jaroslav@292
   185
     * <p>
jaroslav@292
   186
     * Since version 0.5 one can specify "<a href="doc-files/websockets.html">WebSocket</a>"
jaroslav@292
   187
     * as the communication method.
jtulach@940
   188
     *
jaroslav@70
   189
     * @return name of the HTTP transfer method
jaroslav@70
   190
     * @since 0.3
jaroslav@70
   191
     */
jaroslav@70
   192
    String method() default "GET";
jtulach@940
   193
jtulach@940
   194
    /** Name of a method in this class which should be called in case of
jtulach@940
   195
     * an error. The method has to be non-private and take one model and
jtulach@940
   196
     * one {@link Exception}
jaroslav@245
   197
     * parameter. If this method is not specified, the exception is just
jaroslav@245
   198
     * printed to console.
jtulach@940
   199
     *
jaroslav@245
   200
     * @return name of method in this class
jaroslav@245
   201
     * @since 0.5
jaroslav@245
   202
     */
jtulach@940
   203
    public String onError() default "";
jtulach@0
   204
}