Return-Path: X-Original-To: apmail-ignite-commits-archive@minotaur.apache.org Delivered-To: apmail-ignite-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 0A09210516 for ; Thu, 4 Dec 2014 23:24:44 +0000 (UTC) Received: (qmail 49216 invoked by uid 500); 4 Dec 2014 23:24:44 -0000 Delivered-To: apmail-ignite-commits-archive@ignite.apache.org Received: (qmail 49148 invoked by uid 500); 4 Dec 2014 23:24:43 -0000 Mailing-List: contact commits-help@ignite.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ignite.incubator.apache.org Delivered-To: mailing list commits@ignite.incubator.apache.org Received: (qmail 49122 invoked by uid 99); 4 Dec 2014 23:24:43 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 04 Dec 2014 23:24:43 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED,T_RP_MATCHES_RCVD X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO mail.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with SMTP; Thu, 04 Dec 2014 23:24:19 +0000 Received: (qmail 47435 invoked by uid 99); 4 Dec 2014 23:23:55 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 04 Dec 2014 23:23:55 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 35513A1D508; Thu, 4 Dec 2014 23:23:55 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: sboikov@apache.org To: commits@ignite.incubator.apache.org Date: Thu, 04 Dec 2014 23:24:33 -0000 Message-Id: <6d594270f75e403ca27ac27f998dfcdc@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [41/53] [abbrv] incubator-ignite git commit: # gg-9470-rename X-Virus-Checked: Checked by ClamAV on apache.org # gg-9470-rename Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/3dcb5222 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/3dcb5222 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/3dcb5222 Branch: refs/heads/master Commit: 3dcb5222d5ac243e5f347498e80ea14301cb0bc7 Parents: 4e32727 Author: sboikov Authored: Thu Dec 4 22:38:26 2014 +0300 Committer: sboikov Committed: Thu Dec 4 22:38:26 2014 +0300 ---------------------------------------------------------------------- .../java/org/apache/ignite/IgnitePortables.java | 358 +++++++++++++++++++ .../grid/cache/store/GridCacheStore.java | 2 +- .../gridgain/grid/kernal/GridPortablesImpl.java | 3 +- .../VisorPortableMetadataCollectorTask.java | 1 + .../grid/portables/GridPortableBuilder.java | 6 +- .../grid/portables/GridPortableMetadata.java | 2 +- .../grid/portables/GridPortableObject.java | 2 +- .../grid/portables/IgnitePortables.java | 357 ------------------ 8 files changed, 367 insertions(+), 364 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/3dcb5222/modules/core/src/main/java/org/apache/ignite/IgnitePortables.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/IgnitePortables.java b/modules/core/src/main/java/org/apache/ignite/IgnitePortables.java new file mode 100644 index 0000000..7e8a069 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/IgnitePortables.java @@ -0,0 +1,358 @@ +/* @java.file.header */ + +/* _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +package org.apache.ignite; + +import org.gridgain.grid.cache.*; +import org.gridgain.grid.cache.query.*; +import org.gridgain.grid.portables.*; +import org.jetbrains.annotations.*; + +import java.sql.*; +import java.util.*; +import java.util.Date; + +/** + * Defines portable objects functionality. With portable objects you are able to: + *
    + *
  • Seamlessly interoperate between Java, .NET, and C++.
  • + *
  • Make any object portable with zero code change to your existing code.
  • + *
  • Nest portable objects within each other.
  • + *
  • Automatically handle {@code circular} or {@code null} references.
  • + *
  • Automatically convert collections and maps between Java, .NET, and C++.
  • + *
  • + * Optionally avoid deserialization of objects on the server side + * (objects are stored in {@link org.gridgain.grid.portables.GridPortableObject} format). + *
  • + *
  • Avoid need to have concrete class definitions on the server side.
  • + *
  • Dynamically change structure of the classes without having to restart the cluster.
  • + *
  • Index into portable objects for querying purposes.
  • + *
+ *

Working With Portables Directly

+ * Once an object is defined as portable, + * GridGain will always store it in memory in the portable (i.e. binary) format. + * User can choose to work either with the portable format or with the deserialized form + * (assuming that class definitions are present in the classpath). + *

+ * To work with the portable format directly, user should create a special cache projection + * using {@link GridCacheProjection#keepPortable()} method and then retrieve individual fields as needed: + *

+ * GridCacheProjection<GridPortableObject.class, GridPortableObject.class> prj = cache.keepPortable();
+ *
+ * // Convert instance of MyKey to portable format.
+ * // We could also use GridPortableBuilder to create
+ * // the key in portable format directly.
+ * GridPortableObject key = grid.portables().toPortable(new MyKey());
+ *
+ * GridPortableObject val = prj.get(key);
+ *
+ * String field = val.field("myFieldName");
+ * 
+ * Alternatively, if we have class definitions in the classpath, we may choose to work with deserialized + * typed objects at all times. In this case we do incur the deserialization cost, however, + * GridGain will only deserialize on the first access and will cache the deserialized object, + * so it does not have to be deserialized again: + *
+ * GridCacheProjection<MyKey.class, MyValue.class> prj =
+ *     cache.projection(MyKey.class, MyValue.class);
+ *
+ * MyValue val = prj.get(new MyKey());
+ *
+ * // Normal java getter.
+ * String fieldVal = val.getMyFieldName();
+ * 
+ * If we used, for example, one of the automatically handled portable types for a key, like integer, + * and still wanted to work with binary portable format for values, then we would declare cache projection + * as follows: + *
+ * GridCacheProjection<Integer.class, GridPortableObject.class> prj = cache.keepPortable();
+ * 
+ *

Automatic Portable Types

+ * Note that only portable classes are converted to {@link org.gridgain.grid.portables.GridPortableObject} format. Following + * classes are never converted (e.g., {@link #toPortable(Object)} method will return original + * object, and instances of these classes will be stored in cache without changes): + *
    + *
  • All primitives (byte, int, ...) and there boxed versions (Byte, Integer, ...)
  • + *
  • Arrays of primitives (byte[], int[], ...)
  • + *
  • {@link String} and array of {@link String}s
  • + *
  • {@link UUID} and array of {@link UUID}s
  • + *
  • {@link Date} and array of {@link Date}s
  • + *
  • {@link Timestamp} and array of {@link Timestamp}s
  • + *
  • Enums and array of enums
  • + *
  • + * Maps, collections and array of objects (but objects inside + * them will still be converted if they are portable) + *
  • + *
+ *

Working With Maps and Collections

+ * All maps and collections in the portable objects are serialized automatically. When working + * with different platforms, e.g. C++ or .NET, GridGain will automatically pick the most + * adequate collection or map in either language. For example, {@link ArrayList} in Java will become + * {@code List} in C#, {@link LinkedList} in Java is {@link LinkedList} in C#, {@link HashMap} + * in Java is {@code Dictionary} in C#, and {@link TreeMap} in Java becomes {@code SortedDictionary} + * in C#, etc. + *

Building Portable Objects

+ * GridGain comes with {@link org.gridgain.grid.portables.GridPortableBuilder} which allows to build portable objects dynamically: + *
+ * GridPortableBuilder builder = GridGain.grid().portables().builder();
+ *
+ * builder.typeId("MyObject");
+ *
+ * builder.stringField("fieldA", "A");
+ * build.intField("fieldB", "B");
+ *
+ * GridPortableObject portableObj = builder.build();
+ * 
+ * For the cases when class definition is present + * in the class path, it is also possible to populate a standard POJO and then + * convert it to portable format, like so: + *
+ * MyObject obj = new MyObject();
+ *
+ * obj.setFieldA("A");
+ * obj.setFieldB(123);
+ *
+ * GridPortableObject portableObj = GridGain.grid().portables().toPortable(obj);
+ * 
+ * NOTE: you don't need to convert typed objects to portable format before storing + * them in cache, GridGain will do that automatically. + *

Portable Metadata

+ * Even though GridGain portable protocol only works with hash codes for type and field names + * to achieve better performance, GridGain provides metadata for all portable types which + * can be queried ar runtime via any of the {@link IgnitePortables#metadata(Class) GridPortables.metadata(...)} + * methods. Having metadata also allows for proper formatting of {@code GridPortableObject.toString()} method, + * even when portable objects are kept in binary format only, which may be necessary for audit reasons. + *

Dynamic Structure Changes

+ * Since objects are always cached in the portable binary format, server does not need to + * be aware of the class definitions. Moreover, if class definitions are not present or not + * used on the server, then clients can continuously change the structure of the portable + * objects without having to restart the cluster. For example, if one client stores a + * certain class with fields A and B, and another client stores the same class with + * fields B and C, then the server-side portable object will have the fields A, B, and C. + * As the structure of a portable object changes, the new fields become available for SQL queries + * automatically. + *

Configuration

+ * To make any object portable, you have to specify it in {@link org.gridgain.grid.portables.GridPortableConfiguration} + * at startup. The only requirement GridGain imposes is that your object has an empty + * constructor. Note, that since server side does not have to know the class definition, + * you only need to list portable objects in configuration on the client side. However, if you + * list them on the server side as well, then you get the ability to deserialize portable objects + * into concrete types on the server as well as on the client. + *

+ * Here is an example of portable configuration (note that star (*) notation is supported): + *

+ * ...
+ * <!-- Portable objects configuration. -->
+ * <property name="portableConfiguration">
+ *     <bean class="org.gridgain.grid.portables.GridPortableConfiguration">
+ *         <property name="classNames">
+ *             <list>
+ *                 <value>my.package.for.portable.objects.*</value>
+ *                 <value>org.gridgain.examples.client.portable.Employee</value>
+ *             </list>
+ *         </property>
+ *     </bean>
+ * </property>
+ * ...
+ * 
+ * or from code: + *
+ * GridConfiguration gridCfg = new GridConfiguration();
+ *
+ * GridPortableConfiguration portCfg = new GridPortableConfiguration();
+ *
+ * portCfg.setClassNames(Arrays.asList(
+ *     Employee.class.getName(),
+ *     Address.class.getName())
+ * );
+ *
+ * gridCfg.setPortableConfiguration(portCfg);
+ * 
+ * You can also specify class name for a portable object via {@link org.gridgain.grid.portables.GridPortableTypeConfiguration}. + * Do it in case if you need to override other configuration properties on per-type level, like + * ID-mapper, or serializer. + *

Custom Affinity Keys

+ * Often you need to specify an alternate key (not the cache key) for affinity routing whenever + * storing objects in cache. For example, if you are caching {@code Employee} object with + * {@code Organization}, and want to colocate employees with organization they work for, + * so you can process them together, you need to specify an alternate affinity key. + * With portable objects you would have to do it as following: + *
+ * <property name="portableConfiguration">
+ *     <bean class="org.gridgain.grid.portables.GridPortableConfiguration">
+ *         ...
+ *         <property name="typeConfigurations">
+ *             <list>
+ *                 <bean class="org.gridgain.grid.portables.GridPortableTypeConfiguration">
+ *                     <property name="className" value="org.gridgain.examples.client.portable.EmployeeKey"/>
+ *                     <property name="affinityKeyFieldName" value="organizationId"/>
+ *                 </bean>
+ *             </list>
+ *         </property>
+ *         ...
+ *     </bean>
+ * </property>
+ * 
+ *

Serialization

+ * Once portable object is specified in {@link org.gridgain.grid.portables.GridPortableConfiguration}, GridGain will + * be able to serialize and deserialize it. However, you can provide your own custom + * serialization logic by optionally implementing {@link org.gridgain.grid.portables.GridPortableMarshalAware} interface, like so: + *
+ * public class Address implements GridPortableMarshalAware {
+ *     private String street;
+ *     private int zip;
+ *
+ *     // Empty constructor required for portable deserialization.
+ *     public Address() {}
+ *
+ *     @Override public void writePortable(GridPortableWriter writer) throws GridPortableException {
+ *         writer.writeString("street", street);
+ *         writer.writeInt("zip", zip);
+ *     }
+ *
+ *     @Override public void readPortable(GridPortableReader reader) throws GridPortableException {
+ *         street = reader.readString("street");
+ *         zip = reader.readInt("zip");
+ *     }
+ * }
+ * 
+ * Alternatively, if you cannot change class definitions, you can provide custom serialization + * logic in {@link org.gridgain.grid.portables.GridPortableSerializer} either globally in {@link org.gridgain.grid.portables.GridPortableConfiguration} or + * for a specific type via {@link org.gridgain.grid.portables.GridPortableTypeConfiguration} instance. + *

+ * Similar to java serialization you can use {@code writeReplace()} and {@code readResolve()} methods. + *

    + *
  • + * {@code readResolve} is defined as follows: {@code ANY-ACCESS-MODIFIER Object readResolve()}. + * It may be used to replace the de-serialized object by another one of your choice. + *
  • + *
  • + * {@code writeReplace} is defined as follows: {@code ANY-ACCESS-MODIFIER Object writeReplace()}. This method allows the + * developer to provide a replacement object that will be serialized instead of the original one. + *
  • + *
+ * + *

Custom ID Mappers

+ * GridGain implementation uses name hash codes to generate IDs for class names or field names + * internally. However, in cases when you want to provide your own ID mapping schema, + * you can provide your own {@link org.gridgain.grid.portables.GridPortableIdMapper} implementation. + *

+ * ID-mapper may be provided either globally in {@link org.gridgain.grid.portables.GridPortableConfiguration}, + * or for a specific type via {@link org.gridgain.grid.portables.GridPortableTypeConfiguration} instance. + *

Query Indexing

+ * Portable objects can be indexed for querying by specifying index fields in + * {@link GridCacheQueryTypeMetadata} inside of specific {@link GridCacheConfiguration} instance, + * like so: + *
+ * ...
+ * <bean class="org.gridgain.grid.cache.GridCacheConfiguration">
+ *     ...
+ *     <property name="queryConfiguration">
+ *         <bean class="org.gridgain.grid.cache.query.GridCacheQueryConfiguration">
+ *             <property name="typeMetadata">
+ *                 <list>
+ *                     <bean class="org.gridgain.grid.cache.query.GridCacheQueryTypeMetadata">
+ *                         <property name="type" value="Employee"/>
+ *
+ *                         <!-- Fields to index in ascending order. -->
+ *                         <property name="ascendingFields">
+ *                             <map>
+ *                             	<entry key="name" value="java.lang.String"/>
+ *
+ *                                 <!-- Nested portable objects can also be indexed. -->
+ *                                 <entry key="address.zip" value="java.lang.Integer"/>
+ *                             </map>
+ *                         </property>
+ *                     </bean>
+ *                 </list>
+ *             </property>
+ *         </bean>
+ *     </property>
+ * </bean>
+ * 
+ */ +public interface IgnitePortables { + /** + * Gets type ID for given type name. + * + * @param typeName Type name. + * @return Type ID. + */ + public int typeId(String typeName); + + /** + * Converts provided object to instance of {@link org.gridgain.grid.portables.GridPortableObject}. + *

+ * Note that object's type needs to be configured in {@link org.gridgain.grid.portables.GridPortableConfiguration}. + * + * @param obj Object to convert. + * @return Converted object. + * @throws org.gridgain.grid.portables.GridPortableException In case of error. + */ + public T toPortable(@Nullable Object obj) throws GridPortableException; + + /** + * Creates new portable builder. + * + * @param typeId ID of the type. + * @return Newly portable builder. + */ + public GridPortableBuilder builder(int typeId); + + /** + * Creates new portable builder. + * + * @param typeName Type name. + * @return Newly portable builder. + */ + public GridPortableBuilder builder(String typeName); + + /** + * Creates portable builder initialized by existing portable object. + * + * @param portableObj Portable object to initialize builder. + * @return Portable builder. + */ + public GridPortableBuilder builder(GridPortableObject portableObj); + + /** + * Gets metadata for provided class. + * + * @param cls Class. + * @return Metadata. + * @throws GridPortableException In case of error. + */ + @Nullable public GridPortableMetadata metadata(Class cls) throws GridPortableException; + + /** + * Gets metadata for provided class name. + * + * @param typeName Type name. + * @return Metadata. + * @throws GridPortableException In case of error. + */ + @Nullable public GridPortableMetadata metadata(String typeName) throws GridPortableException; + + /** + * Gets metadata for provided type ID. + * + * @param typeId Type ID. + * @return Metadata. + * @throws GridPortableException In case of error. + */ + @Nullable public GridPortableMetadata metadata(int typeId) throws GridPortableException; + + /** + * Gets metadata for all known types. + * + * @return Metadata. + * @throws GridPortableException In case of error. + */ + public Collection metadata() throws GridPortableException; +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/3dcb5222/modules/core/src/main/java/org/gridgain/grid/cache/store/GridCacheStore.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/gridgain/grid/cache/store/GridCacheStore.java b/modules/core/src/main/java/org/gridgain/grid/cache/store/GridCacheStore.java index c257015..e054e18 100644 --- a/modules/core/src/main/java/org/gridgain/grid/cache/store/GridCacheStore.java +++ b/modules/core/src/main/java/org/gridgain/grid/cache/store/GridCacheStore.java @@ -88,7 +88,7 @@ import java.util.Date; * * * - * @see org.gridgain.grid.portables.IgnitePortables + * @see org.apache.ignite.IgnitePortables */ public interface GridCacheStore { /** http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/3dcb5222/modules/core/src/main/java/org/gridgain/grid/kernal/GridPortablesImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/GridPortablesImpl.java b/modules/core/src/main/java/org/gridgain/grid/kernal/GridPortablesImpl.java index 29f36dd..146cf62 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/GridPortablesImpl.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/GridPortablesImpl.java @@ -9,6 +9,7 @@ package org.gridgain.grid.kernal; +import org.apache.ignite.*; import org.gridgain.grid.kernal.processors.portable.*; import org.gridgain.grid.portables.*; import org.jetbrains.annotations.*; @@ -16,7 +17,7 @@ import org.jetbrains.annotations.*; import java.util.*; /** - * {@link org.gridgain.grid.portables.IgnitePortables} implementation. + * {@link org.apache.ignite.IgnitePortables} implementation. */ public class GridPortablesImpl implements IgnitePortables { /** */ http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/3dcb5222/modules/core/src/main/java/org/gridgain/grid/kernal/visor/portable/VisorPortableMetadataCollectorTask.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/visor/portable/VisorPortableMetadataCollectorTask.java b/modules/core/src/main/java/org/gridgain/grid/kernal/visor/portable/VisorPortableMetadataCollectorTask.java index 76744b0..938c8e5 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/visor/portable/VisorPortableMetadataCollectorTask.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/visor/portable/VisorPortableMetadataCollectorTask.java @@ -9,6 +9,7 @@ package org.gridgain.grid.kernal.visor.portable; +import org.apache.ignite.*; import org.apache.ignite.lang.*; import org.gridgain.grid.*; import org.gridgain.grid.kernal.processors.task.*; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/3dcb5222/modules/core/src/main/java/org/gridgain/grid/portables/GridPortableBuilder.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/gridgain/grid/portables/GridPortableBuilder.java b/modules/core/src/main/java/org/gridgain/grid/portables/GridPortableBuilder.java index 4201fd3..813acf8 100644 --- a/modules/core/src/main/java/org/gridgain/grid/portables/GridPortableBuilder.java +++ b/modules/core/src/main/java/org/gridgain/grid/portables/GridPortableBuilder.java @@ -53,9 +53,9 @@ import org.jetbrains.annotations.*; * String city = personPortableObj.getField("address").getField("city"); * * - * @see IgnitePortables#builder(int) - * @see IgnitePortables#builder(String) - * @see IgnitePortables#builder(GridPortableObject) + * @see org.apache.ignite.IgnitePortables#builder(int) + * @see org.apache.ignite.IgnitePortables#builder(String) + * @see org.apache.ignite.IgnitePortables#builder(GridPortableObject) */ public interface GridPortableBuilder { /** http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/3dcb5222/modules/core/src/main/java/org/gridgain/grid/portables/GridPortableMetadata.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/gridgain/grid/portables/GridPortableMetadata.java b/modules/core/src/main/java/org/gridgain/grid/portables/GridPortableMetadata.java index f7103c9..59dff2b 100644 --- a/modules/core/src/main/java/org/gridgain/grid/portables/GridPortableMetadata.java +++ b/modules/core/src/main/java/org/gridgain/grid/portables/GridPortableMetadata.java @@ -15,7 +15,7 @@ import java.util.*; /** * Portable type meta data. Metadata for portable types can be accessed from any of the - * {@link IgnitePortables#metadata(String) GridPortables.metadata(...)} methods. + * {@link org.apache.ignite.IgnitePortables#metadata(String) GridPortables.metadata(...)} methods. * Having metadata also allows for proper formatting of {@code GridPortableObject.toString()} method, * even when portable objects are kept in binary format only, which may be necessary for audit reasons. */ http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/3dcb5222/modules/core/src/main/java/org/gridgain/grid/portables/GridPortableObject.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/gridgain/grid/portables/GridPortableObject.java b/modules/core/src/main/java/org/gridgain/grid/portables/GridPortableObject.java index c201e7b..952c5c8 100644 --- a/modules/core/src/main/java/org/gridgain/grid/portables/GridPortableObject.java +++ b/modules/core/src/main/java/org/gridgain/grid/portables/GridPortableObject.java @@ -105,7 +105,7 @@ import java.util.*; *

Portable Metadata

* Even though GridGain portable protocol only works with hash codes for type and field names * to achieve better performance, GridGain provides metadata for all portable types which - * can be queried ar runtime via any of the {@link IgnitePortables#metadata(Class) GridPortables.metadata(...)} + * can be queried ar runtime via any of the {@link org.apache.ignite.IgnitePortables#metadata(Class) GridPortables.metadata(...)} * methods. Having metadata also allows for proper formatting of {@code GridPortableObject.toString()} method, * even when portable objects are kept in binary format only, which may be necessary for audit reasons. */ http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/3dcb5222/modules/core/src/main/java/org/gridgain/grid/portables/IgnitePortables.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/gridgain/grid/portables/IgnitePortables.java b/modules/core/src/main/java/org/gridgain/grid/portables/IgnitePortables.java deleted file mode 100644 index 6471551..0000000 --- a/modules/core/src/main/java/org/gridgain/grid/portables/IgnitePortables.java +++ /dev/null @@ -1,357 +0,0 @@ -/* @java.file.header */ - -/* _________ _____ __________________ _____ - * __ ____/___________(_)______ /__ ____/______ ____(_)_______ - * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ - * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / - * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ - */ - -package org.gridgain.grid.portables; - -import org.gridgain.grid.cache.*; -import org.gridgain.grid.cache.query.*; -import org.jetbrains.annotations.*; - -import java.sql.*; -import java.util.*; -import java.util.Date; - -/** - * Defines portable objects functionality. With portable objects you are able to: - *
    - *
  • Seamlessly interoperate between Java, .NET, and C++.
  • - *
  • Make any object portable with zero code change to your existing code.
  • - *
  • Nest portable objects within each other.
  • - *
  • Automatically handle {@code circular} or {@code null} references.
  • - *
  • Automatically convert collections and maps between Java, .NET, and C++.
  • - *
  • - * Optionally avoid deserialization of objects on the server side - * (objects are stored in {@link GridPortableObject} format). - *
  • - *
  • Avoid need to have concrete class definitions on the server side.
  • - *
  • Dynamically change structure of the classes without having to restart the cluster.
  • - *
  • Index into portable objects for querying purposes.
  • - *
- *

Working With Portables Directly

- * Once an object is defined as portable, - * GridGain will always store it in memory in the portable (i.e. binary) format. - * User can choose to work either with the portable format or with the deserialized form - * (assuming that class definitions are present in the classpath). - *

- * To work with the portable format directly, user should create a special cache projection - * using {@link GridCacheProjection#keepPortable()} method and then retrieve individual fields as needed: - *

- * GridCacheProjection<GridPortableObject.class, GridPortableObject.class> prj = cache.keepPortable();
- *
- * // Convert instance of MyKey to portable format.
- * // We could also use GridPortableBuilder to create
- * // the key in portable format directly.
- * GridPortableObject key = grid.portables().toPortable(new MyKey());
- *
- * GridPortableObject val = prj.get(key);
- *
- * String field = val.field("myFieldName");
- * 
- * Alternatively, if we have class definitions in the classpath, we may choose to work with deserialized - * typed objects at all times. In this case we do incur the deserialization cost, however, - * GridGain will only deserialize on the first access and will cache the deserialized object, - * so it does not have to be deserialized again: - *
- * GridCacheProjection<MyKey.class, MyValue.class> prj =
- *     cache.projection(MyKey.class, MyValue.class);
- *
- * MyValue val = prj.get(new MyKey());
- *
- * // Normal java getter.
- * String fieldVal = val.getMyFieldName();
- * 
- * If we used, for example, one of the automatically handled portable types for a key, like integer, - * and still wanted to work with binary portable format for values, then we would declare cache projection - * as follows: - *
- * GridCacheProjection<Integer.class, GridPortableObject.class> prj = cache.keepPortable();
- * 
- *

Automatic Portable Types

- * Note that only portable classes are converted to {@link GridPortableObject} format. Following - * classes are never converted (e.g., {@link #toPortable(Object)} method will return original - * object, and instances of these classes will be stored in cache without changes): - *
    - *
  • All primitives (byte, int, ...) and there boxed versions (Byte, Integer, ...)
  • - *
  • Arrays of primitives (byte[], int[], ...)
  • - *
  • {@link String} and array of {@link String}s
  • - *
  • {@link UUID} and array of {@link UUID}s
  • - *
  • {@link Date} and array of {@link Date}s
  • - *
  • {@link Timestamp} and array of {@link Timestamp}s
  • - *
  • Enums and array of enums
  • - *
  • - * Maps, collections and array of objects (but objects inside - * them will still be converted if they are portable) - *
  • - *
- *

Working With Maps and Collections

- * All maps and collections in the portable objects are serialized automatically. When working - * with different platforms, e.g. C++ or .NET, GridGain will automatically pick the most - * adequate collection or map in either language. For example, {@link ArrayList} in Java will become - * {@code List} in C#, {@link LinkedList} in Java is {@link LinkedList} in C#, {@link HashMap} - * in Java is {@code Dictionary} in C#, and {@link TreeMap} in Java becomes {@code SortedDictionary} - * in C#, etc. - *

Building Portable Objects

- * GridGain comes with {@link GridPortableBuilder} which allows to build portable objects dynamically: - *
- * GridPortableBuilder builder = GridGain.grid().portables().builder();
- *
- * builder.typeId("MyObject");
- *
- * builder.stringField("fieldA", "A");
- * build.intField("fieldB", "B");
- *
- * GridPortableObject portableObj = builder.build();
- * 
- * For the cases when class definition is present - * in the class path, it is also possible to populate a standard POJO and then - * convert it to portable format, like so: - *
- * MyObject obj = new MyObject();
- *
- * obj.setFieldA("A");
- * obj.setFieldB(123);
- *
- * GridPortableObject portableObj = GridGain.grid().portables().toPortable(obj);
- * 
- * NOTE: you don't need to convert typed objects to portable format before storing - * them in cache, GridGain will do that automatically. - *

Portable Metadata

- * Even though GridGain portable protocol only works with hash codes for type and field names - * to achieve better performance, GridGain provides metadata for all portable types which - * can be queried ar runtime via any of the {@link IgnitePortables#metadata(Class) GridPortables.metadata(...)} - * methods. Having metadata also allows for proper formatting of {@code GridPortableObject.toString()} method, - * even when portable objects are kept in binary format only, which may be necessary for audit reasons. - *

Dynamic Structure Changes

- * Since objects are always cached in the portable binary format, server does not need to - * be aware of the class definitions. Moreover, if class definitions are not present or not - * used on the server, then clients can continuously change the structure of the portable - * objects without having to restart the cluster. For example, if one client stores a - * certain class with fields A and B, and another client stores the same class with - * fields B and C, then the server-side portable object will have the fields A, B, and C. - * As the structure of a portable object changes, the new fields become available for SQL queries - * automatically. - *

Configuration

- * To make any object portable, you have to specify it in {@link GridPortableConfiguration} - * at startup. The only requirement GridGain imposes is that your object has an empty - * constructor. Note, that since server side does not have to know the class definition, - * you only need to list portable objects in configuration on the client side. However, if you - * list them on the server side as well, then you get the ability to deserialize portable objects - * into concrete types on the server as well as on the client. - *

- * Here is an example of portable configuration (note that star (*) notation is supported): - *

- * ...
- * <!-- Portable objects configuration. -->
- * <property name="portableConfiguration">
- *     <bean class="org.gridgain.grid.portables.GridPortableConfiguration">
- *         <property name="classNames">
- *             <list>
- *                 <value>my.package.for.portable.objects.*</value>
- *                 <value>org.gridgain.examples.client.portable.Employee</value>
- *             </list>
- *         </property>
- *     </bean>
- * </property>
- * ...
- * 
- * or from code: - *
- * GridConfiguration gridCfg = new GridConfiguration();
- *
- * GridPortableConfiguration portCfg = new GridPortableConfiguration();
- *
- * portCfg.setClassNames(Arrays.asList(
- *     Employee.class.getName(),
- *     Address.class.getName())
- * );
- *
- * gridCfg.setPortableConfiguration(portCfg);
- * 
- * You can also specify class name for a portable object via {@link GridPortableTypeConfiguration}. - * Do it in case if you need to override other configuration properties on per-type level, like - * ID-mapper, or serializer. - *

Custom Affinity Keys

- * Often you need to specify an alternate key (not the cache key) for affinity routing whenever - * storing objects in cache. For example, if you are caching {@code Employee} object with - * {@code Organization}, and want to colocate employees with organization they work for, - * so you can process them together, you need to specify an alternate affinity key. - * With portable objects you would have to do it as following: - *
- * <property name="portableConfiguration">
- *     <bean class="org.gridgain.grid.portables.GridPortableConfiguration">
- *         ...
- *         <property name="typeConfigurations">
- *             <list>
- *                 <bean class="org.gridgain.grid.portables.GridPortableTypeConfiguration">
- *                     <property name="className" value="org.gridgain.examples.client.portable.EmployeeKey"/>
- *                     <property name="affinityKeyFieldName" value="organizationId"/>
- *                 </bean>
- *             </list>
- *         </property>
- *         ...
- *     </bean>
- * </property>
- * 
- *

Serialization

- * Once portable object is specified in {@link GridPortableConfiguration}, GridGain will - * be able to serialize and deserialize it. However, you can provide your own custom - * serialization logic by optionally implementing {@link GridPortableMarshalAware} interface, like so: - *
- * public class Address implements GridPortableMarshalAware {
- *     private String street;
- *     private int zip;
- *
- *     // Empty constructor required for portable deserialization.
- *     public Address() {}
- *
- *     @Override public void writePortable(GridPortableWriter writer) throws GridPortableException {
- *         writer.writeString("street", street);
- *         writer.writeInt("zip", zip);
- *     }
- *
- *     @Override public void readPortable(GridPortableReader reader) throws GridPortableException {
- *         street = reader.readString("street");
- *         zip = reader.readInt("zip");
- *     }
- * }
- * 
- * Alternatively, if you cannot change class definitions, you can provide custom serialization - * logic in {@link GridPortableSerializer} either globally in {@link GridPortableConfiguration} or - * for a specific type via {@link GridPortableTypeConfiguration} instance. - *

- * Similar to java serialization you can use {@code writeReplace()} and {@code readResolve()} methods. - *

    - *
  • - * {@code readResolve} is defined as follows: {@code ANY-ACCESS-MODIFIER Object readResolve()}. - * It may be used to replace the de-serialized object by another one of your choice. - *
  • - *
  • - * {@code writeReplace} is defined as follows: {@code ANY-ACCESS-MODIFIER Object writeReplace()}. This method allows the - * developer to provide a replacement object that will be serialized instead of the original one. - *
  • - *
- * - *

Custom ID Mappers

- * GridGain implementation uses name hash codes to generate IDs for class names or field names - * internally. However, in cases when you want to provide your own ID mapping schema, - * you can provide your own {@link GridPortableIdMapper} implementation. - *

- * ID-mapper may be provided either globally in {@link GridPortableConfiguration}, - * or for a specific type via {@link GridPortableTypeConfiguration} instance. - *

Query Indexing

- * Portable objects can be indexed for querying by specifying index fields in - * {@link GridCacheQueryTypeMetadata} inside of specific {@link GridCacheConfiguration} instance, - * like so: - *
- * ...
- * <bean class="org.gridgain.grid.cache.GridCacheConfiguration">
- *     ...
- *     <property name="queryConfiguration">
- *         <bean class="org.gridgain.grid.cache.query.GridCacheQueryConfiguration">
- *             <property name="typeMetadata">
- *                 <list>
- *                     <bean class="org.gridgain.grid.cache.query.GridCacheQueryTypeMetadata">
- *                         <property name="type" value="Employee"/>
- *
- *                         <!-- Fields to index in ascending order. -->
- *                         <property name="ascendingFields">
- *                             <map>
- *                             	<entry key="name" value="java.lang.String"/>
- *
- *                                 <!-- Nested portable objects can also be indexed. -->
- *                                 <entry key="address.zip" value="java.lang.Integer"/>
- *                             </map>
- *                         </property>
- *                     </bean>
- *                 </list>
- *             </property>
- *         </bean>
- *     </property>
- * </bean>
- * 
- */ -public interface IgnitePortables { - /** - * Gets type ID for given type name. - * - * @param typeName Type name. - * @return Type ID. - */ - public int typeId(String typeName); - - /** - * Converts provided object to instance of {@link GridPortableObject}. - *

- * Note that object's type needs to be configured in {@link GridPortableConfiguration}. - * - * @param obj Object to convert. - * @return Converted object. - * @throws GridPortableException In case of error. - */ - public T toPortable(@Nullable Object obj) throws GridPortableException; - - /** - * Creates new portable builder. - * - * @param typeId ID of the type. - * @return Newly portable builder. - */ - public GridPortableBuilder builder(int typeId); - - /** - * Creates new portable builder. - * - * @param typeName Type name. - * @return Newly portable builder. - */ - public GridPortableBuilder builder(String typeName); - - /** - * Creates portable builder initialized by existing portable object. - * - * @param portableObj Portable object to initialize builder. - * @return Portable builder. - */ - public GridPortableBuilder builder(GridPortableObject portableObj); - - /** - * Gets metadata for provided class. - * - * @param cls Class. - * @return Metadata. - * @throws GridPortableException In case of error. - */ - @Nullable public GridPortableMetadata metadata(Class cls) throws GridPortableException; - - /** - * Gets metadata for provided class name. - * - * @param typeName Type name. - * @return Metadata. - * @throws GridPortableException In case of error. - */ - @Nullable public GridPortableMetadata metadata(String typeName) throws GridPortableException; - - /** - * Gets metadata for provided type ID. - * - * @param typeId Type ID. - * @return Metadata. - * @throws GridPortableException In case of error. - */ - @Nullable public GridPortableMetadata metadata(int typeId) throws GridPortableException; - - /** - * Gets metadata for all known types. - * - * @return Metadata. - * @throws GridPortableException In case of error. - */ - public Collection metadata() throws GridPortableException; -}