All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.protostuff.runtime.ExplicitIdStrategy Maven / Gradle / Ivy

There is a newer version: 1.8.0
Show newest version
//================================================================================
//Copyright (c) 2012, David Yu
//All rights reserved.
//--------------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
// 3. Neither the name of protostuff nor the names of its contributors may be used
//    to endorse or promote products derived from this software without
//    specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//================================================================================

package io.protostuff.runtime;

import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.IdentityHashMap;
import java.util.Map;

import io.protostuff.CollectionSchema;
import io.protostuff.Input;
import io.protostuff.MapSchema;
import io.protostuff.Message;
import io.protostuff.Output;
import io.protostuff.Pipe;
import io.protostuff.Schema;

/**
 * Requires every messsage/pojo/enum/collection/map to be registered with unique ids.
 * 
 * @author David Yu
 * @created Mar 25, 2012
 */
public final class ExplicitIdStrategy extends NumericIdStrategy
{

    /**
     * This Registry is only way to register your pojos/enums/collections/maps/delegates.
     */
    public static class Registry implements NumericIdStrategy.Registry
    {

        public final ExplicitIdStrategy strategy;

        public Registry()
        {
            this(DEFAULT_FLAGS, null, 0, 10, 10, 10, 10, 10);
        }

        public Registry(
                int initialCollectionSize,
                int initialMapSize,
                int initialEnumSize,
                int initialPojoSize,
                int initialDelegateSize)
        {
            this(DEFAULT_FLAGS, null, 0,
                    initialCollectionSize,
                    initialMapSize,
                    initialEnumSize,
                    initialPojoSize,
                    initialDelegateSize);
        }

        public Registry(
                int flags, 
                IdStrategy primaryGroup, int groupId,
                int initialCollectionSize,
                int initialMapSize,
                int initialEnumSize,
                int initialPojoSize,
                int initialDelegateSize)
        {
            IdentityHashMap, RegisteredCollectionFactory> collectionMapping =
                    newMap(initialCollectionSize);

            ArrayList collections =
                    newList(initialCollectionSize + 1);

            IdentityHashMap, RegisteredMapFactory> mapMapping =
                    new IdentityHashMap, RegisteredMapFactory>(
                            initialMapSize);

            ArrayList maps = newList(initialMapSize);

            IdentityHashMap, RegisteredEnumIO> enumMapping =
                    newMap(initialEnumSize);

            ArrayList enums =
                    newList(initialEnumSize + 1);

            IdentityHashMap, BaseHS> pojoMapping =
                    newMap(initialPojoSize);

            ArrayList> pojos = newList(initialPojoSize + 1);

            IdentityHashMap, RegisteredDelegate> delegateMapping =
                    newMap(initialDelegateSize);

            ArrayList> delegates = newList(initialDelegateSize + 1);

            strategy = new ExplicitIdStrategy(
                    flags, 
                    primaryGroup, groupId,
                    collectionMapping, collections,
                    mapMapping, maps,
                    enumMapping, enums,
                    pojoMapping, pojos,
                    delegateMapping, delegates);
        }

        /**
         * Collection ids start at 1.
         */
        @Override
        public > Registry registerCollection(
                CollectionSchema.MessageFactory factory, int id)
        {
            if (id < 1)
                throw new IllegalArgumentException("collection ids start at 1.");

            if (id >= strategy.collections.size())
                grow(strategy.collections, id + 1);
            else if (strategy.collections.get(id) != null)
            {
                throw new IllegalArgumentException("Duplicate id registration: " + id +
                        " (" + factory.typeClass() + ")");
            }

            RegisteredCollectionFactory rf = new RegisteredCollectionFactory(id, factory);
            strategy.collections.set(id, rf);
            // just in case
            if (strategy.collectionMapping.put(factory.typeClass(), rf) != null)
                throw new IllegalArgumentException("Duplicate registration for: " + factory.typeClass());

            return this;
        }

        /**
         * Map ids start at 1.
         */
        @Override
        public > Registry registerMap(
                MapSchema.MessageFactory factory, int id)
        {
            if (id < 1)
                throw new IllegalArgumentException("map ids start at 1.");

            if (id >= strategy.maps.size())
                grow(strategy.maps, id + 1);
            else if (strategy.maps.get(id) != null)
            {
                throw new IllegalArgumentException("Duplicate id registration: " + id +
                        " (" + factory.typeClass() + ")");
            }

            RegisteredMapFactory rf = new RegisteredMapFactory(id, factory);
            strategy.maps.set(id, rf);
            // just in case
            if (strategy.mapMapping.put(factory.typeClass(), rf) != null)
                throw new IllegalArgumentException("Duplicate registration for: " + factory.typeClass());

            return this;
        }

        /**
         * Enum ids start at 1.
         */
        @Override
        public > Registry registerEnum(Class clazz, int id)
        {
            if (id < 1)
                throw new IllegalArgumentException("enum ids start at 1.");

            if (id >= strategy.enums.size())
                grow(strategy.enums, id + 1);
            else if (strategy.enums.get(id) != null)
            {
                throw new IllegalArgumentException("Duplicate id registration: " + id +
                        " (" + clazz.getName() + ")");
            }

            EnumIO eio = EnumIO.newEnumIO(clazz, strategy);
            RegisteredEnumIO reio = new RegisteredEnumIO(id, eio);
            strategy.enums.set(id, reio);

            // just in case
            if (strategy.enumMapping.put(clazz, reio) != null)
                throw new IllegalArgumentException("Duplicate registration for: " + clazz);

            return this;
        }

        /**
         * Enum ids start at 1.
         */
        @Override
        public Registry registerEnum(EnumIO eio, int id)
        {
            if (id < 1)
                throw new IllegalArgumentException("enum ids start at 1.");

            if (id >= strategy.enums.size())
                grow(strategy.enums, id + 1);
            else if (strategy.enums.get(id) != null)
            {
                throw new IllegalArgumentException("Duplicate id registration: " + id +
                        " (" + eio.enumClass.getName() + ")");
            }

            RegisteredEnumIO reio = new RegisteredEnumIO(id, eio);
            strategy.enums.set(id, reio);

            // just in case
            if (strategy.enumMapping.put(eio.enumClass, reio) != null)
                throw new IllegalArgumentException("Duplicate registration for: " + eio.enumClass);

            return this;
        }

        /**
         * Pojo ids start at 1.
         */
        @Override
        public  Registry registerPojo(Class clazz, int id)
        {
            if (clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers()))
                throw new IllegalArgumentException("Not a concrete class: " + clazz);

            if (id < 1)
                throw new IllegalArgumentException("pojo ids start at 1.");

            if (id >= strategy.pojos.size())
                grow(strategy.pojos, id + 1);
            else if (strategy.pojos.get(id) != null)
            {
                throw new IllegalArgumentException("Duplicate id registration: " + id +
                        " (" + clazz.getName() + ")");
            }

            if (strategy.pojoMapping.containsKey(clazz))
                throw new IllegalArgumentException("Duplicate registration for: " + clazz);

            BaseHS wrapper = new Lazy(id, clazz, strategy);
            strategy.pojos.set(id, wrapper);

            strategy.pojoMapping.put(clazz, wrapper);

            return this;
        }

        /**
         * Pojo ids start at 1.
         */
        @Override
        public  Registry registerPojo(Schema schema, Pipe.Schema pipeSchema,
                int id)
        {
            if (id >= strategy.pojos.size())
                grow(strategy.pojos, id + 1);
            else if (strategy.pojos.get(id) != null)
            {
                throw new IllegalArgumentException("Duplicate id registration: " + id +
                        " (" + schema.typeClass().getName() + ")");
            }

            if (strategy.pojoMapping.containsKey(schema.typeClass()))
                throw new IllegalArgumentException("Duplicate registration for: " + schema.typeClass());

            Registered wrapper = new Registered(id, schema, pipeSchema, strategy);
            strategy.pojos.set(id, wrapper);

            strategy.pojoMapping.put(schema.typeClass(), wrapper);

            return this;
        }

        /**
         * If you are sure that you are only using a single implementation of your interface/abstract class, then it
         * makes sense to map it directly to its impl class to avoid writing the type.
         * 

* Note that the type is always written when your field is {@link java.lang.Object}. *

* Pojo ids start at 1. */ @Override public Registry mapPojo(Class baseClass, Class implClass) { if (strategy.pojoMapping.containsKey(baseClass)) throw new IllegalArgumentException("Duplicate registration for: " + baseClass); BaseHS wrapper = strategy.pojoMapping.get(implClass); if (wrapper == null) throw new IllegalArgumentException("Must register the impl class first. " + implClass); strategy.pojoMapping.put(baseClass, wrapper); return this; } /** * Register a {@link Delegate} and assign an id. *

* Delegate ids start at 1. */ @Override public Registry registerDelegate(Delegate delegate, int id) { if (id < 1) throw new IllegalArgumentException("delegate ids start at 1."); if (id >= strategy.delegates.size()) grow(strategy.delegates, id + 1); else if (strategy.delegates.get(id) != null) { throw new IllegalArgumentException("Duplicate id registration: " + id + " (" + delegate.typeClass() + ")"); } RegisteredDelegate rd = new RegisteredDelegate(id, delegate, strategy); strategy.delegates.set(id, rd); // just in case if (strategy.delegateMapping.put(delegate.typeClass(), rd) != null) throw new IllegalArgumentException("Duplicate registration for: " + delegate.typeClass()); return this; } } final IdentityHashMap, RegisteredCollectionFactory> collectionMapping; final ArrayList collections; final IdentityHashMap, RegisteredMapFactory> mapMapping; final ArrayList maps; final IdentityHashMap, RegisteredEnumIO> enumMapping; final ArrayList enums; final IdentityHashMap, BaseHS> pojoMapping; final ArrayList> pojos; final IdentityHashMap, RegisteredDelegate> delegateMapping; final ArrayList> delegates; public ExplicitIdStrategy( IdentityHashMap, RegisteredCollectionFactory> collectionMapping, ArrayList collections, IdentityHashMap, RegisteredMapFactory> mapMapping, ArrayList maps, IdentityHashMap, RegisteredEnumIO> enumMapping, ArrayList enums, IdentityHashMap, BaseHS> pojoMapping, ArrayList> pojos, IdentityHashMap, RegisteredDelegate> delegateMapping, ArrayList> delegates) { this(DEFAULT_FLAGS, null, 0, collectionMapping, collections, mapMapping, maps, enumMapping, enums, pojoMapping, pojos, delegateMapping, delegates); } public ExplicitIdStrategy(final int flags, IdStrategy primaryGroup, int groupId, IdentityHashMap, RegisteredCollectionFactory> collectionMapping, ArrayList collections, IdentityHashMap, RegisteredMapFactory> mapMapping, ArrayList maps, IdentityHashMap, RegisteredEnumIO> enumMapping, ArrayList enums, IdentityHashMap, BaseHS> pojoMapping, ArrayList> pojos, IdentityHashMap, RegisteredDelegate> delegateMapping, ArrayList> delegates) { super(flags, primaryGroup, groupId); this.collectionMapping = collectionMapping; this.collections = collections; this.mapMapping = mapMapping; this.maps = maps; this.enumMapping = enumMapping; this.enums = enums; this.pojoMapping = pojoMapping; this.pojos = pojos; this.delegateMapping = delegateMapping; this.delegates = delegates; } @Override public boolean isRegistered(Class typeClass) { return pojoMapping.containsKey(typeClass); } @Override @SuppressWarnings("unchecked") public HasSchema getSchemaWrapper(Class typeClass, boolean create) { final BaseHS wrapper = (BaseHS) pojoMapping.get(typeClass); if (wrapper == null && create) throw new UnknownTypeException("pojo: " + typeClass); return wrapper; } @Override protected EnumIO> getEnumIO(Class enumClass) { final RegisteredEnumIO reio = enumMapping.get(enumClass); if (reio == null) throw new UnknownTypeException("enum: " + enumClass); return reio.eio; } @Override protected CollectionSchema.MessageFactory getCollectionFactory(Class clazz) { final RegisteredCollectionFactory rf = collectionMapping.get(clazz); if (rf == null) { if (clazz.getName().startsWith("java.util")) return CollectionSchema.MessageFactories.valueOf(clazz.getSimpleName()); throw new UnknownTypeException("collection: " + clazz); } return rf; } @Override protected MapSchema.MessageFactory getMapFactory(Class clazz) { final RegisteredMapFactory rf = mapMapping.get(clazz); if (rf == null) { if (clazz.getName().startsWith("java.util")) return MapSchema.MessageFactories.valueOf(clazz.getSimpleName()); throw new UnknownTypeException("map: " + clazz); } return rf; } @Override protected void writeCollectionIdTo(Output output, int fieldNumber, Class clazz) throws IOException { final RegisteredCollectionFactory factory = collectionMapping.get(clazz); if (factory == null) throw new UnknownTypeException("collection: " + clazz); output.writeUInt32(fieldNumber, factory.id, false); } @Override protected void transferCollectionId(Input input, Output output, int fieldNumber) throws IOException { output.writeUInt32(fieldNumber, input.readUInt32(), false); } @Override protected CollectionSchema.MessageFactory resolveCollectionFrom(Input input) throws IOException { final int id = input.readUInt32(); final CollectionSchema.MessageFactory factory = id < collections.size() ? collections.get(id) : null; if (factory == null) throw new UnknownTypeException("collection id: " + id + " (Outdated registry)"); return factory; } @Override protected void writeMapIdTo(Output output, int fieldNumber, Class clazz) throws IOException { final RegisteredMapFactory factory = mapMapping.get(clazz); if (factory == null) throw new UnknownTypeException("map: " + clazz); output.writeUInt32(fieldNumber, factory.id, false); } @Override protected void transferMapId(Input input, Output output, int fieldNumber) throws IOException { output.writeUInt32(fieldNumber, input.readUInt32(), false); } @Override protected MapSchema.MessageFactory resolveMapFrom(Input input) throws IOException { final int id = input.readUInt32(); final MapSchema.MessageFactory factory = id < maps.size() ? maps.get(id) : null; if (factory == null) throw new UnknownTypeException("map id: " + id + " (Outdated registry)"); return factory; } @Override protected void writeEnumIdTo(Output output, int fieldNumber, Class clazz) throws IOException { final RegisteredEnumIO reio = enumMapping.get(clazz); if (reio == null) throw new UnknownTypeException("enum: " + clazz); output.writeUInt32(fieldNumber, reio.id, false); } @Override protected void transferEnumId(Input input, Output output, int fieldNumber) throws IOException { output.writeUInt32(fieldNumber, input.readUInt32(), false); } @Override protected EnumIO resolveEnumFrom(Input input) throws IOException { final int id = input.readUInt32(); final RegisteredEnumIO reio = id < enums.size() ? enums.get(id) : null; if (reio == null) throw new UnknownTypeException("enum id: " + id + " (Outdated registry)"); return reio.eio; } @Override public boolean isDelegateRegistered(Class typeClass) { return delegateMapping.containsKey(typeClass); } @Override @SuppressWarnings("unchecked") public Delegate getDelegate(Class typeClass) { final RegisteredDelegate rd = (RegisteredDelegate) delegateMapping.get( typeClass); return rd == null ? null : rd.delegate; } @Override @SuppressWarnings("unchecked") public HasDelegate getDelegateWrapper(Class typeClass) { return (HasDelegate) delegateMapping.get(typeClass); } @Override @SuppressWarnings("unchecked") protected HasDelegate tryWriteDelegateIdTo(Output output, int fieldNumber, Class clazz) throws IOException { final RegisteredDelegate rd = (RegisteredDelegate) delegateMapping.get( clazz); if (rd == null) return null; output.writeUInt32(fieldNumber, rd.id, false); return rd; } @Override @SuppressWarnings("unchecked") protected HasDelegate transferDelegateId(Input input, Output output, int fieldNumber) throws IOException { final int id = input.readUInt32(); final RegisteredDelegate rd = id < delegates.size() ? (RegisteredDelegate) delegates.get(id) : null; if (rd == null) throw new UnknownTypeException("delegate id: " + id + " (Outdated registry)"); output.writeUInt32(fieldNumber, id, false); return rd; } @Override @SuppressWarnings("unchecked") protected HasDelegate resolveDelegateFrom(Input input) throws IOException { final int id = input.readUInt32(); final RegisteredDelegate rd = id < delegates.size() ? (RegisteredDelegate) delegates.get(id) : null; if (rd == null) throw new UnknownTypeException("delegate id: " + id + " (Outdated registry)"); return rd; } @Override @SuppressWarnings("unchecked") protected HasSchema tryWritePojoIdTo(Output output, int fieldNumber, Class clazz, boolean registered) throws IOException { final BaseHS wrapper = (BaseHS) pojoMapping.get(clazz); if (wrapper != null) output.writeUInt32(fieldNumber, wrapper.id, false); return wrapper; } @Override @SuppressWarnings("unchecked") protected HasSchema writePojoIdTo(Output output, int fieldNumber, Class clazz) throws IOException { final BaseHS wrapper = (BaseHS) pojoMapping.get(clazz); if (wrapper == null) throw new UnknownTypeException("pojo: " + clazz); output.writeUInt32(fieldNumber, wrapper.id, false); return wrapper; } @Override @SuppressWarnings("unchecked") protected HasSchema transferPojoId(Input input, Output output, int fieldNumber) throws IOException { final int id = input.readUInt32(); final BaseHS wrapper = (BaseHS) pojos.get(id); if (wrapper == null) throw new UnknownTypeException("pojo id: " + id + " (Outdated registry)"); output.writeUInt32(fieldNumber, id, false); return wrapper; } @Override @SuppressWarnings("unchecked") protected HasSchema resolvePojoFrom(Input input, int fieldNumber) throws IOException { final int id = input.readUInt32(); final BaseHS wrapper = id < pojos.size() ? (BaseHS) pojos.get(id) : null; if (wrapper == null) throw new UnknownTypeException("pojo id: " + id + " (Outdated registry)"); return wrapper; } @Override @SuppressWarnings("unchecked") protected Schema writeMessageIdTo(Output output, int fieldNumber, Message message) throws IOException { final BaseHS wrapper = (BaseHS) pojoMapping.get(message.getClass()); if (wrapper == null) throw new UnknownTypeException("pojo: " + message.getClass()); output.writeUInt32(fieldNumber, wrapper.id, false); // TODO allow the wrapper to return an override schema? return message.cachedSchema(); } @Override protected Class collectionClass(int id) { final RegisteredCollectionFactory factory = id < collections.size() ? collections.get(id) : null; if (factory == null) { throw new UnknownTypeException("collection id: " + id + " (Outdated registry)"); } return factory.typeClass(); } @Override protected Class mapClass(int id) { final RegisteredMapFactory factory = id < maps.size() ? maps.get(id) : null; if (factory == null) { throw new UnknownTypeException("map id: " + id + " (Outdated registry)"); } return factory.typeClass(); } @Override protected Class enumClass(int id) { final RegisteredEnumIO reio = id < enums.size() ? enums.get(id) : null; if (reio == null) { throw new UnknownTypeException("enum id: " + id + " (Outdated registry)"); } return reio.eio.enumClass; } @Override protected Class delegateClass(int id) { final RegisteredDelegate rd = id < delegates.size() ? delegates.get(id) : null; return rd == null ? null : rd.delegate.typeClass(); } @Override protected Class pojoClass(int id) { final BaseHS wrapper = id < pojos.size() ? pojos.get(id) : null; if (wrapper == null) { throw new UnknownTypeException("pojo id: " + id + " (Outdated registry)"); } return wrapper.getSchema().typeClass(); } @Override protected RegisteredDelegate getRegisteredDelegate(Class clazz) { return delegateMapping.get(clazz); } @Override protected int getEnumId(Class clazz) { final RegisteredEnumIO reio = enumMapping.get(clazz); if (reio == null) throw new UnknownTypeException("enum: " + clazz); return (reio.id << 5) | CID_ENUM; } @Override protected int getId(Class clazz) { if (Message.class.isAssignableFrom(clazz)) { final BaseHS wrapper = pojoMapping.get(clazz); if (wrapper == null) throw new UnknownTypeException("pojo: " + clazz); return (wrapper.id << 5) | CID_POJO; } if (Map.class.isAssignableFrom(clazz)) return EnumMap.class.isAssignableFrom(clazz) ? CID_ENUM_MAP : mapId(clazz); if (Collection.class.isAssignableFrom(clazz)) return EnumSet.class.isAssignableFrom(clazz) ? CID_ENUM_SET : collectionId(clazz); final BaseHS wrapper = pojoMapping.get(clazz); if (wrapper == null) throw new UnknownTypeException("pojo: " + clazz); return (wrapper.id << 5) | CID_POJO; } private int collectionId(Class clazz) { final RegisteredCollectionFactory factory = collectionMapping.get(clazz); if (factory == null) throw new UnknownTypeException("collection: " + clazz); return (factory.id << 5) | CID_COLLECTION; } private int mapId(Class clazz) { final RegisteredMapFactory factory = mapMapping.get(clazz); if (factory == null) throw new UnknownTypeException("map: " + clazz); return (factory.id << 5) | CID_MAP; } static IdentityHashMap newMap(int size) { return new IdentityHashMap(size); } static final class RegisteredCollectionFactory implements CollectionSchema.MessageFactory { final int id; final CollectionSchema.MessageFactory factory; public RegisteredCollectionFactory(int id, CollectionSchema.MessageFactory factory) { this.id = id; this.factory = factory; } @Override public Collection newMessage() { return factory.newMessage(); } @Override public Class typeClass() { return factory.typeClass(); } } static final class RegisteredMapFactory implements MapSchema.MessageFactory { final int id; final MapSchema.MessageFactory factory; public RegisteredMapFactory(int id, MapSchema.MessageFactory factory) { this.id = id; this.factory = factory; } @Override public Map newMessage() { return factory.newMessage(); } @Override public Class typeClass() { return factory.typeClass(); } } static final class RegisteredEnumIO { final int id; final EnumIO eio; public RegisteredEnumIO(int id, EnumIO eio) { this.id = id; this.eio = eio; } } static abstract class BaseHS extends HasSchema { final int id; BaseHS(int id, IdStrategy strategy) { super(strategy); this.id = id; } } static final class Registered extends BaseHS { final Schema schema; final Pipe.Schema pipeSchema; Registered(int id, Schema schema, Pipe.Schema pipeSchema, IdStrategy strategy) { super(id, strategy); this.schema = schema; this.pipeSchema = pipeSchema; } @Override public Schema getSchema() { return schema; } @Override public io.protostuff.Pipe.Schema getPipeSchema() { return pipeSchema; } } static final class Lazy extends BaseHS { final Class typeClass; private volatile Schema schema; private volatile Pipe.Schema pipeSchema; Lazy(int id, Class typeClass, IdStrategy strategy) { super(id, strategy); this.typeClass = typeClass; } @Override @SuppressWarnings("unchecked") public Schema getSchema() { Schema schema = this.schema; if (schema == null) { synchronized (this) { if ((schema = this.schema) == null) { if (Message.class.isAssignableFrom(typeClass)) { // use the message's schema. final Message m = (Message) createMessageInstance(typeClass); this.schema = schema = m.cachedSchema(); } else { // create new this.schema = schema = strategy.newSchema(typeClass); } } } } return schema; } @Override public Pipe.Schema getPipeSchema() { Pipe.Schema pipeSchema = this.pipeSchema; if (pipeSchema == null) { synchronized (this) { if ((pipeSchema = this.pipeSchema) == null) { this.pipeSchema = pipeSchema = RuntimeSchema.resolvePipeSchema( getSchema(), typeClass, true); } } } return pipeSchema; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy