http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1f2be19d/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableContext.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableContext.java new file mode 100644 index 0000000..b19a855 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableContext.java @@ -0,0 +1,1089 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.portable; + +import org.apache.ignite.*; +import org.apache.ignite.internal.*; +import org.apache.ignite.internal.processors.cache.portable.*; +import org.apache.ignite.internal.util.*; +import org.apache.ignite.internal.util.lang.*; +import org.apache.ignite.internal.util.typedef.*; +import org.apache.ignite.internal.util.typedef.internal.*; +import org.apache.ignite.lang.*; +import org.apache.ignite.marshaller.*; +import org.apache.ignite.marshaller.optimized.*; +import org.apache.ignite.marshaller.portable.*; +import org.apache.ignite.portable.*; + +import org.jetbrains.annotations.*; +import org.jsr166.*; + +import java.io.*; +import java.math.*; +import java.net.*; +import java.sql.*; +import java.util.*; +import java.util.Date; +import java.util.concurrent.*; +import java.util.jar.*; + +/** + * Portable context. + */ +public class GridPortableContext implements Externalizable { + /** */ + private static final long serialVersionUID = 0L; + + /** */ + static final PortableIdMapper DFLT_ID_MAPPER = new IdMapperWrapper(null); + + /** */ + static final PortableIdMapper BASIC_CLS_ID_MAPPER = new BasicClassIdMapper(); + + /** */ + static final char[] LOWER_CASE_CHARS; + + /** */ + static final char MAX_LOWER_CASE_CHAR = 0x7e; + + /** + * + */ + static { + LOWER_CASE_CHARS = new char[MAX_LOWER_CASE_CHAR + 1]; + + for (char c = 0; c <= MAX_LOWER_CASE_CHAR; c++) + LOWER_CASE_CHARS[c] = Character.toLowerCase(c); + } + + /** */ + private final ConcurrentMap<Integer, Collection<Integer>> metaDataCache = new ConcurrentHashMap8<>(); + + /** */ + private final ConcurrentMap<Class<?>, GridPortableClassDescriptor> descByCls = new ConcurrentHashMap8<>(); + + /** */ + private final ConcurrentMap<Integer, GridPortableClassDescriptor> userTypes = new ConcurrentHashMap8<>(0); + + /** */ + private final Map<Integer, GridPortableClassDescriptor> predefinedTypes = new HashMap<>(); + + /** */ + private final Set<Class> predefinedClasses = new HashSet<>(); + + /** */ + private final Map<Class<? extends Collection>, Byte> colTypes = new HashMap<>(); + + /** */ + private final Map<Class<? extends Map>, Byte> mapTypes = new HashMap<>(); + + /** */ + private final Map<Integer, PortableIdMapper> mappers = new ConcurrentHashMap8<>(0); + + /** */ + private final Map<String, PortableIdMapper> typeMappers = new ConcurrentHashMap8<>(0); + + /** */ + private Map<Integer, Boolean> metaEnabled = new HashMap<>(0); + + /** */ + private Set<Integer> usingTs = new HashSet<>(); + + /** */ + private GridPortableMetaDataHandler metaHnd; + + /** */ + private MarshallerContext marshCtx; + + /** */ + private String gridName; + + /** */ + private PortableMarshaller marsh; + + /** */ + private final OptimizedMarshaller optmMarsh = new OptimizedMarshaller(); + + /** + * For {@link Externalizable}. + */ + public GridPortableContext() { + // No-op. + } + + /** + * @param metaHnd Meta data handler. + * @param gridName Grid name. + */ + public GridPortableContext(GridPortableMetaDataHandler metaHnd, @Nullable String gridName) { + assert metaHnd != null; + + this.metaHnd = metaHnd; + this.gridName = gridName; + + colTypes.put(ArrayList.class, GridPortableMarshaller.ARR_LIST); + colTypes.put(LinkedList.class, GridPortableMarshaller.LINKED_LIST); + colTypes.put(HashSet.class, GridPortableMarshaller.HASH_SET); + colTypes.put(LinkedHashSet.class, GridPortableMarshaller.LINKED_HASH_SET); + colTypes.put(TreeSet.class, GridPortableMarshaller.TREE_SET); + colTypes.put(ConcurrentSkipListSet.class, GridPortableMarshaller.CONC_SKIP_LIST_SET); + + mapTypes.put(HashMap.class, GridPortableMarshaller.HASH_MAP); + mapTypes.put(LinkedHashMap.class, GridPortableMarshaller.LINKED_HASH_MAP); + mapTypes.put(TreeMap.class, GridPortableMarshaller.TREE_MAP); + mapTypes.put(ConcurrentHashMap.class, GridPortableMarshaller.CONC_HASH_MAP); + mapTypes.put(ConcurrentHashMap8.class, GridPortableMarshaller.CONC_HASH_MAP); + mapTypes.put(Properties.class, GridPortableMarshaller.PROPERTIES_MAP); + + registerPredefinedType(Byte.class, GridPortableMarshaller.BYTE); + registerPredefinedType(Boolean.class, GridPortableMarshaller.BOOLEAN); + registerPredefinedType(Short.class, GridPortableMarshaller.SHORT); + registerPredefinedType(Character.class, GridPortableMarshaller.CHAR); + registerPredefinedType(Integer.class, GridPortableMarshaller.INT); + registerPredefinedType(Long.class, GridPortableMarshaller.LONG); + registerPredefinedType(Float.class, GridPortableMarshaller.FLOAT); + registerPredefinedType(Double.class, GridPortableMarshaller.DOUBLE); + registerPredefinedType(String.class, GridPortableMarshaller.STRING); + registerPredefinedType(BigDecimal.class, GridPortableMarshaller.DECIMAL); + registerPredefinedType(Date.class, GridPortableMarshaller.DATE); + registerPredefinedType(UUID.class, GridPortableMarshaller.UUID); + // TODO: How to handle timestamp? It has the same ID in .Net. + registerPredefinedType(Timestamp.class, GridPortableMarshaller.DATE); + + registerPredefinedType(byte[].class, GridPortableMarshaller.BYTE_ARR); + registerPredefinedType(short[].class, GridPortableMarshaller.SHORT_ARR); + registerPredefinedType(int[].class, GridPortableMarshaller.INT_ARR); + registerPredefinedType(long[].class, GridPortableMarshaller.LONG_ARR); + registerPredefinedType(float[].class, GridPortableMarshaller.FLOAT_ARR); + registerPredefinedType(double[].class, GridPortableMarshaller.DOUBLE_ARR); + registerPredefinedType(char[].class, GridPortableMarshaller.CHAR_ARR); + registerPredefinedType(boolean[].class, GridPortableMarshaller.BOOLEAN_ARR); + registerPredefinedType(BigDecimal[].class, GridPortableMarshaller.DECIMAL_ARR); + registerPredefinedType(String[].class, GridPortableMarshaller.STRING_ARR); + registerPredefinedType(UUID[].class, GridPortableMarshaller.UUID_ARR); + registerPredefinedType(Date[].class, GridPortableMarshaller.DATE_ARR); + registerPredefinedType(Object[].class, GridPortableMarshaller.OBJ_ARR); + + registerPredefinedType(ArrayList.class, 0); + registerPredefinedType(LinkedList.class, 0); + registerPredefinedType(HashSet.class, 0); + registerPredefinedType(LinkedHashSet.class, 0); + registerPredefinedType(TreeSet.class, 0); + registerPredefinedType(ConcurrentSkipListSet.class, 0); + + registerPredefinedType(HashMap.class, 0); + registerPredefinedType(LinkedHashMap.class, 0); + registerPredefinedType(TreeMap.class, 0); + registerPredefinedType(ConcurrentHashMap.class, 0); + registerPredefinedType(ConcurrentHashMap8.class, 0); + + registerPredefinedType(GridMapEntry.class, 60); + registerPredefinedType(IgniteBiTuple.class, 61); + registerPredefinedType(T2.class, 62); + + registerPredefinedType(GridPortableObjectImpl.class, 63); + + registerPredefinedType(GridPortableMetaDataImpl.class, 64); + +// TODO: IGNITE-1258 +// registerPredefinedType(DrSenderAttributes.class, 65); +// registerPredefinedType(DrSenderRemoteAttributes.class, 66); +// +// registerPredefinedType(InteropClusterNode.class, 67); +// registerPredefinedType(InteropClusterMetrics.class, 68); +// registerPredefinedType(InteropTransactionMetrics.class, 69); +// registerPredefinedType(InteropMetadata.class, 70); +// +// registerPredefinedType(InteropDotNetConfiguration.class, 71); +// registerPredefinedType(InteropDotNetPortableConfiguration.class, 72); +// registerPredefinedType(InteropDotNetPortableTypeConfiguration.class, 73); +// registerPredefinedType(InteropIgniteProxy.class, 74); +// registerPredefinedType(InteropCacheMetrics.class, 75); +// registerPredefinedType(InteropProductLicence.class, 78); + } + + /** + * @param marsh Portable marshaller. + * @throws PortableException In case of error. + */ + public void configure(PortableMarshaller marsh) throws PortableException { + if (marsh == null) + return; + + this.marsh = marsh; + marshCtx = marsh.getContext(); + + assert marshCtx != null; + + optmMarsh.setContext(marshCtx); + + PortableIdMapper globalIdMapper = marsh.getIdMapper(); + PortableSerializer globalSerializer = marsh.getSerializer(); + boolean globalUseTs = marsh.isUseTimestamp(); + boolean globalMetaDataEnabled = marsh.isMetaDataEnabled(); + boolean globalKeepDeserialized = marsh.isKeepDeserialized(); + + TypeDescriptors descs = new TypeDescriptors(); + + if (marsh.getClassNames() != null) { + PortableIdMapper idMapper = new IdMapperWrapper(globalIdMapper); + + for (String clsName : marsh.getClassNames()) { + if (clsName.endsWith(".*")) { // Package wildcard + String pkgName = clsName.substring(0, clsName.length() - 2); + + for (String clsName0 : classesInPackage(pkgName)) + descs.add(clsName0, idMapper, null, null, globalUseTs, globalMetaDataEnabled, + globalKeepDeserialized, true); + } + else // Regular single class + descs.add(clsName, idMapper, null, null, globalUseTs, globalMetaDataEnabled, + globalKeepDeserialized, true); + } + } + + if (marsh.getTypeConfigurations() != null) { + for (PortableTypeConfiguration typeCfg : marsh.getTypeConfigurations()) { + String clsName = typeCfg.getClassName(); + + if (clsName == null) + throw new PortableException("Class name is required for portable type configuration."); + + PortableIdMapper idMapper = globalIdMapper; + + if (typeCfg.getIdMapper() != null) + idMapper = typeCfg.getIdMapper(); + + idMapper = new IdMapperWrapper(idMapper); + + PortableSerializer serializer = globalSerializer; + + if (typeCfg.getSerializer() != null) + serializer = typeCfg.getSerializer(); + + boolean useTs = typeCfg.isUseTimestamp() != null ? typeCfg.isUseTimestamp() : globalUseTs; + boolean metaDataEnabled = typeCfg.isMetaDataEnabled() != null ? typeCfg.isMetaDataEnabled() : + globalMetaDataEnabled; + boolean keepDeserialized = typeCfg.isKeepDeserialized() != null ? typeCfg.isKeepDeserialized() : + globalKeepDeserialized; + + if (clsName.endsWith(".*")) { + String pkgName = clsName.substring(0, clsName.length() - 2); + + for (String clsName0 : classesInPackage(pkgName)) + descs.add(clsName0, idMapper, serializer, typeCfg.getAffinityKeyFieldName(), useTs, + metaDataEnabled, keepDeserialized, true); + } + else + descs.add(clsName, idMapper, serializer, typeCfg.getAffinityKeyFieldName(), useTs, + metaDataEnabled, keepDeserialized, false); + } + } + + for (TypeDescriptor desc : descs.descriptors()) + registerUserType(desc.clsName, desc.idMapper, desc.serializer, desc.affKeyFieldName, desc.useTs, + desc.metadataEnabled, desc.keepDeserialized); + } + + /** + * @param pkgName Package name. + * @return Class names. + */ + @SuppressWarnings("ConstantConditions") + private static Iterable<String> classesInPackage(String pkgName) { + assert pkgName != null; + + Collection<String> clsNames = new ArrayList<>(); + + ClassLoader ldr = U.gridClassLoader(); + + if (ldr instanceof URLClassLoader) { + String pkgPath = pkgName.replaceAll("\\.", "/"); + + URL[] urls = ((URLClassLoader)ldr).getURLs(); + + for (URL url : urls) { + String proto = url.getProtocol().toLowerCase(); + + if ("file".equals(proto)) { + try { + File cpElement = new File(url.toURI()); + + if (cpElement.isDirectory()) { + File pkgDir = new File(cpElement, pkgPath); + + if (pkgDir.isDirectory()) { + for (File file : pkgDir.listFiles()) { + String fileName = file.getName(); + + if (file.isFile() && fileName.toLowerCase().endsWith(".class")) + clsNames.add(pkgName + '.' + fileName.substring(0, fileName.length() - 6)); + } + } + } + else if (cpElement.isFile()) { + try { + JarFile jar = new JarFile(cpElement); + + Enumeration<JarEntry> entries = jar.entries(); + + while (entries.hasMoreElements()) { + String entry = entries.nextElement().getName(); + + if (entry.startsWith(pkgPath) && entry.endsWith(".class")) { + String clsName = entry.substring(pkgPath.length() + 1, entry.length() - 6); + + if (!clsName.contains("/") && !clsName.contains("\\")) + clsNames.add(pkgName + '.' + clsName); + } + } + } + catch (IOException ignored) { + // No-op. + } + } + } + catch (URISyntaxException ignored) { + // No-op. + } + } + } + } + + return clsNames; + } + + /** + * @param cls Class. + * @return Class descriptor. + * @throws PortableException In case of error. + */ + public GridPortableClassDescriptor descriptorForClass(Class<?> cls) + throws PortableException { + assert cls != null; + + GridPortableClassDescriptor desc = descByCls.get(cls); + + if (desc == null || !desc.isRegistered()) + desc = registerClassDescriptor(cls); + + return desc; + } + + /** + * @param userType User type or not. + * @param typeId Type ID. + * @param ldr Class loader. + * @return Class descriptor. + */ + public GridPortableClassDescriptor descriptorForTypeId(boolean userType, int typeId, ClassLoader ldr) { + assert typeId != GridPortableMarshaller.UNREGISTERED_TYPE_ID; + + GridPortableClassDescriptor desc = userType ? userTypes.get(typeId) : predefinedTypes.get(typeId); + + if (desc != null) + return desc; + + Class cls; + + try { + cls = marshCtx.getClass(typeId, ldr); + + desc = descByCls.get(cls); + } + catch (ClassNotFoundException e) { + throw new PortableInvalidClassException(e); + } + catch (IgniteCheckedException e) { + throw new PortableException("Failed resolve class for ID: " + typeId, e); + } + + if (desc == null) { + desc = registerClassDescriptor(cls); + + assert desc.typeId() == typeId; + } + + return desc; + } + + /** + * Creates and registers {@link GridPortableClassDescriptor} for the given {@code class}. + * + * @param cls Class. + * @return Class descriptor. + */ + private GridPortableClassDescriptor registerClassDescriptor(Class<?> cls) { + GridPortableClassDescriptor desc; + + String clsName = cls.getName(); + + if (marshCtx.isSystemType(clsName)) { + desc = new GridPortableClassDescriptor(this, + cls, + false, + clsName.hashCode(), + clsName, + BASIC_CLS_ID_MAPPER, + null, + marsh.isUseTimestamp(), + marsh.isMetaDataEnabled(), + marsh.isKeepDeserialized()); + + GridPortableClassDescriptor old = descByCls.putIfAbsent(cls, desc); + + if (old != null) + desc = old; + } + else + desc = registerUserClassDescriptor(cls); + + return desc; + } + + /** + * Creates and registers {@link GridPortableClassDescriptor} for the given user {@code class}. + * + * @param cls Class. + * @return Class descriptor. + */ + private GridPortableClassDescriptor registerUserClassDescriptor(Class<?> cls) { + GridPortableClassDescriptor desc; + + boolean registered; + + String typeName = typeName(cls.getName()); + + PortableIdMapper idMapper = idMapper(typeName); + + int typeId = idMapper.typeId(typeName); + + try { + registered = marshCtx.registerClass(typeId, cls); + + } catch (IgniteCheckedException e) { + throw new PortableException("Failed to register class.", e); + } + + desc = new GridPortableClassDescriptor(this, + cls, + true, + typeId, + typeName, + idMapper, + null, + marsh.isUseTimestamp(), + marsh.isMetaDataEnabled(), + marsh.isKeepDeserialized(), + registered); + + // perform put() instead of putIfAbsent() because "registered" flag may have been changed. + userTypes.put(typeId, desc); + descByCls.put(cls, desc); + + return desc; + } + + /** + * @param cls Collection class. + * @return Collection type ID. + */ + public byte collectionType(Class<? extends Collection> cls) { + assert cls != null; + + Byte type = colTypes.get(cls); + + if (type != null) + return type; + + return Set.class.isAssignableFrom(cls) ? GridPortableMarshaller.USER_SET : GridPortableMarshaller.USER_COL; + } + + /** + * @param cls Map class. + * @return Map type ID. + */ + public byte mapType(Class<? extends Map> cls) { + assert cls != null; + + Byte type = mapTypes.get(cls); + + return type != null ? type : GridPortableMarshaller.USER_COL; + } + + /** + * @param typeName Type name. + * @return Type ID. + */ + public int typeId(String typeName) { + int id; + + if (marshCtx.isSystemType(typeName)) + id = typeName.hashCode(); + + else { + typeName = typeName(typeName); + + id = idMapper(typeName).typeId(typeName); + } + + return id; + } + + /** + * @param cls Class. + * @return Type ID. + * @throws PortableException In case of error. + */ + public Type typeId(Class cls) throws PortableException { + String clsName = cls.getName(); + + if (marshCtx.isSystemType(clsName)) + return new Type(clsName.hashCode(), true); + + if (predefinedClasses.contains(cls)) + return new Type(DFLT_ID_MAPPER.typeId(typeName(clsName)), true); + + GridPortableClassDescriptor desc = descByCls.get(cls); + + boolean registered = desc != null && desc.isRegistered(); + + if (!registered) + // forces to register the class and fill up all required data structures + desc = registerUserClassDescriptor(cls); + + return new Type(desc.typeId(), desc.isRegistered()); + } + + /** + * @param typeId Type ID. + * @param fieldName Field name. + * @return Field ID. + */ + public int fieldId(int typeId, String fieldName) { + return idMapper(typeId).fieldId(typeId, fieldName); + } + + /** + * @param typeId Type ID. + * @return Instance of ID mapper. + */ + public PortableIdMapper idMapper(int typeId) { + PortableIdMapper idMapper = mappers.get(typeId); + + if (idMapper != null) + return idMapper; + + if (userTypes.containsKey(typeId) || predefinedTypes.containsKey(typeId)) + return DFLT_ID_MAPPER; + + return BASIC_CLS_ID_MAPPER; + } + + /** + * @param typeName Type name. + * @return Instance of ID mapper. + */ + private PortableIdMapper idMapper(String typeName) { + PortableIdMapper idMapper = typeMappers.get(typeName); + + return idMapper != null ? idMapper : DFLT_ID_MAPPER; + } + + /** {@inheritDoc} */ + @Override public void writeExternal(ObjectOutput out) throws IOException { + U.writeString(out, gridName); + } + + /** {@inheritDoc} */ + @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + gridName = U.readString(in); + } + + /** + * @return Portable context. + * @throws ObjectStreamException In case of error. + */ + protected Object readResolve() throws ObjectStreamException { + try { + IgniteKernal g = IgnitionEx.gridx(gridName); + + if (g == null) + throw new IllegalStateException("Failed to find grid for name: " + gridName); + + return ((CacheObjectPortableProcessorImpl)g.context().cacheObjects()).portableContext(); + } + catch (IllegalStateException e) { + throw U.withCause(new InvalidObjectException(e.getMessage()), e); + } + } + + /** + * @param cls Class. + * @param id Type ID. + * @return GridPortableClassDescriptor. + */ + private GridPortableClassDescriptor registerPredefinedType(Class<?> cls, int id) { + GridPortableClassDescriptor desc = new GridPortableClassDescriptor( + this, + cls, + false, + id, + typeName(cls.getName()), + DFLT_ID_MAPPER, + null, + false, + false, + false + ); + + predefinedClasses.add(cls); + + predefinedTypes.put(id, desc); + descByCls.put(cls, desc); + + return desc; + } + + /** + * @param clsName Class name. + * @param idMapper ID mapper. + * @param serializer Serializer. + * @param affKeyFieldName Affinity key field name. + * @param useTs Use timestamp flag. + * @param metaDataEnabled Metadata enabled flag. + * @param keepDeserialized Keep deserialized flag. + * @throws PortableException In case of error. + */ + @SuppressWarnings("ErrorNotRethrown") + public void registerUserType(String clsName, + PortableIdMapper idMapper, + @Nullable PortableSerializer serializer, + @Nullable String affKeyFieldName, + boolean useTs, + boolean metaDataEnabled, + boolean keepDeserialized) + throws PortableException { + assert idMapper != null; + + Class<?> cls = null; + + try { + cls = Class.forName(clsName); + } + catch (ClassNotFoundException | NoClassDefFoundError ignored) { + // No-op. + } + + int id = idMapper.typeId(clsName); + + if (mappers.put(id, idMapper) != null) + throw new PortableException("Duplicate type ID [clsName=" + clsName + ", id=" + id + ']'); + + if (useTs) + usingTs.add(id); + + String typeName = typeName(clsName); + + typeMappers.put(typeName, idMapper); + + metaEnabled.put(id, metaDataEnabled); + + Map<String, String> fieldsMeta = null; + + if (cls != null) { + GridPortableClassDescriptor desc = new GridPortableClassDescriptor( + this, + cls, + true, + id, + typeName, + idMapper, + serializer, + useTs, + metaDataEnabled, + keepDeserialized); + + fieldsMeta = desc.fieldsMeta(); + + userTypes.put(id, desc); + descByCls.put(cls, desc); + } + + metaHnd.addMeta(id, new GridPortableMetaDataImpl(typeName, fieldsMeta, affKeyFieldName)); + } + + /** + * @param typeId Type ID. + * @return Meta data. + * @throws PortableException In case of error. + */ + @Nullable public PortableMetadata metaData(int typeId) throws PortableException { + return metaHnd != null ? metaHnd.metadata(typeId) : null; + } + + /** + * @return Whether meta data is globally enabled. + */ + boolean isMetaDataEnabled() { + return marsh.isMetaDataEnabled(); + } + + /** + * @param typeId Type ID. + * @return Whether meta data is enabled. + */ + boolean isMetaDataEnabled(int typeId) { + Boolean enabled = metaEnabled.get(typeId); + + return enabled != null ? enabled : true; + } + + /** + * @param typeId Type ID. + * @param metaHashSum Meta data hash sum. + * @return Whether meta is changed. + */ + boolean isMetaDataChanged(int typeId, @Nullable Integer metaHashSum) { + if (metaHashSum == null) + return false; + + Collection<Integer> hist = metaDataCache.get(typeId); + + if (hist == null) { + Collection<Integer> old = metaDataCache.putIfAbsent(typeId, hist = new GridConcurrentHashSet<>()); + + if (old != null) + hist = old; + } + + return hist.add(metaHashSum); + } + + /** + * @param typeId Type ID. + * @param typeName Type name. + * @param fields Fields map. + * @throws PortableException In case of error. + */ + void updateMetaData(int typeId, String typeName, Map<String, String> fields) throws PortableException { + updateMetaData(typeId, new GridPortableMetaDataImpl(typeName, fields, null)); + } + + /** + * @param typeId Type ID. + * @param meta Meta data. + * @throws PortableException In case of error. + */ + public void updateMetaData(int typeId, GridPortableMetaDataImpl meta) throws PortableException { + metaHnd.addMeta(typeId, meta); + } + + /** + * @return Use timestamp flag. + */ + public boolean isUseTimestamp() { + return marsh.isUseTimestamp(); + } + + /** + * @param typeId Type ID. + * @return If timestamp used. + */ + public boolean isUseTimestamp(int typeId) { + return usingTs.contains(typeId); + } + + /** + * @return Whether to convert string to UTF8 bytes. + */ + public boolean isConvertString() { + return marsh.isConvertStringToBytes(); + } + + /** + * Returns whether {@code cls} is predefined in the context or not. + * + * @param cls Class. + * @return {@code true} if predefined, {@code false} otherwise. + */ + public boolean isPredefinedClass(Class<?> cls) { + return predefinedClasses.contains(cls); + } + + /** + * Returns instance of {@link OptimizedMarshaller}. + * + * @return Optimized marshaller. + */ + OptimizedMarshaller optimizedMarsh() { + return optmMarsh; + } + + /** + * @param clsName Class name. + * @return Type name. + */ + public static String typeName(String clsName) { + assert clsName != null; + + int idx = clsName.lastIndexOf('$'); + + String typeName; + + if (idx >= 0) { + typeName = clsName.substring(idx + 1); + + try { + Integer.parseInt(typeName); + + // This is an anonymous class. Don't cut off enclosing class name for it. + idx = -1; + } + catch (NumberFormatException e) { + return typeName; + } + } + + if (idx < 0) + idx = clsName.lastIndexOf('.'); + + return idx >= 0 ? clsName.substring(idx + 1) : clsName; + } + + /** + * @param str String. + * @return Hash code for given string converted to lower case. + */ + private static int lowerCaseHashCode(String str) { + int len = str.length(); + + int h = 0; + + for (int i = 0; i < len; i++) { + int c = str.charAt(i); + + c = c <= MAX_LOWER_CASE_CHAR ? LOWER_CASE_CHARS[c] : Character.toLowerCase(c); + + h = 31 * h + c; + } + + return h; + } + + /** + */ + private static class IdMapperWrapper implements PortableIdMapper { + /** */ + private final PortableIdMapper mapper; + + /** + * @param mapper Custom ID mapper. + */ + private IdMapperWrapper(@Nullable PortableIdMapper mapper) { + this.mapper = mapper; + } + + /** {@inheritDoc} */ + @Override public int typeId(String clsName) { + int id = 0; + + if (mapper != null) + id = mapper.typeId(clsName); + + return id != 0 ? id : lowerCaseHashCode(typeName(clsName)); + } + + /** {@inheritDoc} */ + @Override public int fieldId(int typeId, String fieldName) { + int id = 0; + + if (mapper != null) + id = mapper.fieldId(typeId, fieldName); + + return id != 0 ? id : lowerCaseHashCode(fieldName); + } + } + + private static class BasicClassIdMapper implements PortableIdMapper { + /** {@inheritDoc} */ + @Override public int typeId(String clsName) { + return clsName.hashCode(); + } + + /** {@inheritDoc} */ + @Override public int fieldId(int typeId, String fieldName) { + return lowerCaseHashCode(fieldName); + } + } + /** + * Type descriptors. + */ + private static class TypeDescriptors { + /** Descriptors map. */ + private final Map<String, TypeDescriptor> descs = new HashMap<>(); + + /** + * Add type descriptor. + * + * @param clsName Class name. + * @param idMapper ID mapper. + * @param serializer Serializer. + * @param affKeyFieldName Affinity key field name. + * @param useTs Use timestamp flag. + * @param metadataEnabled Metadata enabled flag. + * @param keepDeserialized Keep deserialized flag. + * @param canOverride Whether this descriptor can be override. + * @throws PortableException If failed. + */ + private void add(String clsName, + PortableIdMapper idMapper, + PortableSerializer serializer, + String affKeyFieldName, + boolean useTs, + boolean metadataEnabled, + boolean keepDeserialized, + boolean canOverride) + throws PortableException { + TypeDescriptor desc = new TypeDescriptor(clsName, + idMapper, + serializer, + affKeyFieldName, + useTs, + metadataEnabled, + keepDeserialized, + canOverride); + + TypeDescriptor oldDesc = descs.get(clsName); + + if (oldDesc == null) + descs.put(clsName, desc); + else + oldDesc.override(desc); + } + + /** + * Get all collected descriptors. + * + * @return Descriptors. + */ + private Iterable<TypeDescriptor> descriptors() { + return descs.values(); + } + } + + /** + * Type descriptor. + */ + private static class TypeDescriptor { + /** Class name. */ + private final String clsName; + + /** ID mapper. */ + private PortableIdMapper idMapper; + + /** Serializer. */ + private PortableSerializer serializer; + + /** Affinity key field name. */ + private String affKeyFieldName; + + /** Use timestamp flag. */ + private boolean useTs; + + /** Metadata enabled flag. */ + private boolean metadataEnabled; + + /** Keep deserialized flag. */ + private boolean keepDeserialized; + + /** Whether this descriptor can be override. */ + private boolean canOverride; + + /** + * Constructor. + * + * @param clsName Class name. + * @param idMapper ID mapper. + * @param serializer Serializer. + * @param affKeyFieldName Affinity key field name. + * @param useTs Use timestamp flag. + * @param metadataEnabled Metadata enabled flag. + * @param keepDeserialized Keep deserialized flag. + * @param canOverride Whether this descriptor can be override. + */ + private TypeDescriptor(String clsName, PortableIdMapper idMapper, PortableSerializer serializer, + String affKeyFieldName, boolean useTs, boolean metadataEnabled, boolean keepDeserialized, + boolean canOverride) { + this.clsName = clsName; + this.idMapper = idMapper; + this.serializer = serializer; + this.affKeyFieldName = affKeyFieldName; + this.useTs = useTs; + this.metadataEnabled = metadataEnabled; + this.keepDeserialized = keepDeserialized; + this.canOverride = canOverride; + } + + /** + * Override portable class descriptor. + * + * @param other Other descriptor. + * @throws PortableException If failed. + */ + private void override(TypeDescriptor other) throws PortableException { + assert clsName.equals(other.clsName); + + if (canOverride) { + idMapper = other.idMapper; + serializer = other.serializer; + affKeyFieldName = other.affKeyFieldName; + useTs = other.useTs; + metadataEnabled = other.metadataEnabled; + keepDeserialized = other.keepDeserialized; + canOverride = other.canOverride; + } + else if (!other.canOverride) + throw new PortableException("Duplicate explicit class definition in configuration: " + clsName); + } + } + + /** + * Type id wrapper. + */ + static class Type { + /** Type id*/ + private int id; + + /** Whether the following type is registered in a cache or not */ + private boolean registered; + + public Type(int id, boolean registered) { + this.id = id; + this.registered = registered; + } + + public int id() { + return id; + } + + public boolean registered() { + return registered; + } + } +}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1f2be19d/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableEnumArrayLazyValue.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableEnumArrayLazyValue.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableEnumArrayLazyValue.java new file mode 100644 index 0000000..2e76d86 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableEnumArrayLazyValue.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.portable; + +import org.apache.ignite.internal.util.typedef.internal.*; +import org.apache.ignite.portable.*; + +/** + * + */ +class GridPortableEnumArrayLazyValue extends GridPortableAbstractLazyValue { + /** */ + private final int len; + + /** */ + private final int compTypeId; + + /** */ + private final String clsName; + + /** + * @param reader Reader. + */ + protected GridPortableEnumArrayLazyValue(GridPortableBuilderReader reader) { + super(reader, reader.position() - 1); + + int typeId = reader.readInt(); + + if (typeId == GridPortableMarshaller.UNREGISTERED_TYPE_ID) { + clsName = reader.readString(); + + Class cls; + + try { + // TODO: GG-10396 - Is class loader needed here? + cls = U.forName(reader.readString(), null); + } + catch (ClassNotFoundException e) { + throw new PortableInvalidClassException("Failed to load the class: " + clsName, e); + } + + compTypeId = reader.portableContext().descriptorForClass(cls).typeId(); + } + else { + compTypeId = typeId; + clsName = null; + } + + int size = reader.readInt(); + + for (int i = 0; i < size; i++) + reader.skipValue(); + + len = reader.position() - valOff; + } + + /** {@inheritDoc} */ + @Override protected Object init() { + reader.position(valOff + 1); + + //skipping component type id + reader.readInt(); + + int size = reader.readInt(); + + GridPortableBuilderEnum[] res = new GridPortableBuilderEnum[size]; + + for (int i = 0; i < size; i++) { + byte flag = reader.readByte(); + + if (flag == GridPortableMarshaller.NULL) + continue; + + if (flag != GridPortableMarshaller.ENUM) + throw new PortableException("Invalid flag value: " + flag); + + res[i] = new GridPortableBuilderEnum(reader); + } + + return res; + } + + /** {@inheritDoc} */ + @Override public void writeTo(GridPortableWriterImpl writer, GridPortableBuilderSerializer ctx) { + if (val != null) { + if (clsName != null) + ctx.writeArray(writer, GridPortableMarshaller.ENUM_ARR, (Object[])val, clsName); + else + ctx.writeArray(writer, GridPortableMarshaller.ENUM_ARR, (Object[])val, compTypeId); + + return; + } + + writer.write(reader.array(), valOff, len); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1f2be19d/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyArrayList.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyArrayList.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyArrayList.java new file mode 100644 index 0000000..a3c1294 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyArrayList.java @@ -0,0 +1,156 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.portable; + +import java.util.*; + +/** + * + */ +class GridPortableLazyArrayList extends AbstractList<Object> implements GridPortableBuilderSerializationAware { + /** */ + private final GridPortableBuilderReader reader; + + /** */ + private final int off; + + /** */ + private List<Object> delegate; + + /** + * @param reader Reader. + * @param size Size, + */ + GridPortableLazyArrayList(GridPortableBuilderReader reader, int size) { + this.reader = reader; + off = reader.position() - 1/* flag */ - 4/* size */ - 1/* col type */; + + assert size >= 0; + + for (int i = 0; i < size; i++) + reader.skipValue(); + } + + /** + * + */ + private void ensureDelegateInit() { + if (delegate == null) { + int size = reader.readIntAbsolute(off + 1); + + reader.position(off + 1/* flag */ + 4/* size */ + 1/* col type */); + + delegate = new ArrayList<>(size); + + for (int i = 0; i < size; i++) + delegate.add(reader.parseValue()); + } + } + + /** {@inheritDoc} */ + @Override public Object get(int idx) { + ensureDelegateInit(); + + return GridPortableUtils.unwrapLazy(delegate.get(idx)); + } + + /** {@inheritDoc} */ + @Override public boolean add(Object o) { + ensureDelegateInit(); + + return delegate.add(o); + } + + /** {@inheritDoc} */ + @Override public void add(int idx, Object element) { + ensureDelegateInit(); + + delegate.add(idx, element); + } + + /** {@inheritDoc} */ + @Override public Object set(int idx, Object element) { + ensureDelegateInit(); + + return GridPortableUtils.unwrapLazy(delegate.set(idx, element)); + } + + /** {@inheritDoc} */ + @Override public Object remove(int idx) { + ensureDelegateInit(); + + return GridPortableUtils.unwrapLazy(delegate.remove(idx)); + } + + /** {@inheritDoc} */ + @Override public void clear() { + if (delegate == null) + delegate = new ArrayList<>(); + else + delegate.clear(); + } + + /** {@inheritDoc} */ + @Override public boolean addAll(int idx, Collection<?> c) { + return delegate.addAll(idx, c); + } + + /** {@inheritDoc} */ + @Override protected void removeRange(int fromIdx, int toIdx) { + ensureDelegateInit(); + + delegate.subList(fromIdx, toIdx).clear(); + } + + /** {@inheritDoc} */ + @Override public int size() { + if (delegate == null) + return reader.readIntAbsolute(off + 1); + + return delegate.size(); + } + + /** {@inheritDoc} */ + @Override public void writeTo(GridPortableWriterImpl writer, GridPortableBuilderSerializer ctx) { + if (delegate == null) { + int size = reader.readIntAbsolute(off + 1); + + int hdrSize = 1 /* flag */ + 4 /* size */ + 1 /* col type */; + + writer.write(reader.array(), off, hdrSize); + + reader.position(off + hdrSize); + + for (int i = 0; i < size; i++) { + Object o = reader.parseValue(); + + ctx.writeValue(writer, o); + } + } + else { + writer.writeByte(GridPortableMarshaller.COL); + writer.writeInt(delegate.size()); + + byte colType = reader.array()[off + 1 /* flag */ + 4 /* size */]; + writer.writeByte(colType); + + for (Object o : delegate) + ctx.writeValue(writer, o); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1f2be19d/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyLinkedList.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyLinkedList.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyLinkedList.java new file mode 100644 index 0000000..6483f15 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyLinkedList.java @@ -0,0 +1,210 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.portable; + +import java.util.*; + +/** + * + */ +class GridPortableLazyLinkedList extends AbstractList<Object> implements GridPortableBuilderSerializationAware { + /** */ + private final GridPortableBuilderReader reader; + + /** */ + private final int off; + + /** */ + private List<Object> delegate; + + /** + * @param reader Reader. + * @param size Size, + */ + GridPortableLazyLinkedList(GridPortableBuilderReader reader, int size) { + this.reader = reader; + off = reader.position() - 1/* flag */ - 4/* size */ - 1/* col type */; + + assert size >= 0; + + for (int i = 0; i < size; i++) + reader.skipValue(); + } + + /** + * + */ + private void ensureDelegateInit() { + if (delegate == null) { + int size = reader.readIntAbsolute(off + 1); + + reader.position(off + 1/* flag */ + 4/* size */ + 1/* col type */); + + delegate = new LinkedList<>(); + + for (int i = 0; i < size; i++) + delegate.add(reader.parseValue()); + } + } + + /** {@inheritDoc} */ + @Override public Object get(int idx) { + ensureDelegateInit(); + + return GridPortableUtils.unwrapLazy(delegate.get(idx)); + } + + /** {@inheritDoc} */ + @Override public boolean add(Object o) { + ensureDelegateInit(); + + return delegate.add(o); + } + + /** {@inheritDoc} */ + @Override public void add(int idx, Object element) { + ensureDelegateInit(); + + delegate.add(idx, element); + } + + /** {@inheritDoc} */ + @Override public Object set(int idx, Object element) { + ensureDelegateInit(); + + return GridPortableUtils.unwrapLazy(delegate.set(idx, element)); + } + + /** {@inheritDoc} */ + @Override public Object remove(int idx) { + ensureDelegateInit(); + + return GridPortableUtils.unwrapLazy(delegate.remove(idx)); + } + + /** {@inheritDoc} */ + @Override public void clear() { + if (delegate == null) + delegate = new LinkedList<>(); + else + delegate.clear(); + } + + /** {@inheritDoc} */ + @Override public boolean addAll(int idx, Collection<?> c) { + ensureDelegateInit(); + + return delegate.addAll(idx, c); + } + + /** {@inheritDoc} */ + @Override protected void removeRange(int fromIdx, int toIdx) { + ensureDelegateInit(); + + delegate.subList(fromIdx, toIdx).clear(); + } + + /** {@inheritDoc} */ + @Override public int size() { + if (delegate == null) + return reader.readIntAbsolute(off + 1); + + return delegate.size(); + } + + /** {@inheritDoc} */ + @Override public ListIterator<Object> listIterator(final int idx) { + ensureDelegateInit(); + + return new ListIterator<Object>() { + /** */ + private final ListIterator<Object> delegate = GridPortableLazyLinkedList.super.listIterator(idx); + + @Override public boolean hasNext() { + return delegate.hasNext(); + } + + @Override public Object next() { + return GridPortableUtils.unwrapLazy(delegate.next()); + } + + @Override public boolean hasPrevious() { + return delegate.hasPrevious(); + } + + @Override public Object previous() { + return GridPortableUtils.unwrapLazy(delegate.previous()); + } + + @Override public int nextIndex() { + return delegate.nextIndex(); + } + + @Override public int previousIndex() { + return delegate.previousIndex(); + } + + @Override public void remove() { + delegate.remove(); + } + + @Override public void set(Object o) { + delegate.set(o); + } + + @Override public void add(Object o) { + delegate.add(o); + } + }; + } + + /** {@inheritDoc} */ + @Override public Iterator<Object> iterator() { + ensureDelegateInit(); + + return GridPortableUtils.unwrapLazyIterator(super.iterator()); + } + + /** {@inheritDoc} */ + @Override public void writeTo(GridPortableWriterImpl writer, GridPortableBuilderSerializer ctx) { + if (delegate == null) { + int size = reader.readIntAbsolute(off + 1); + + int hdrSize = 1 /* flag */ + 4 /* size */ + 1 /* col type */; + writer.write(reader.array(), off, hdrSize); + + reader.position(off + hdrSize); + + for (int i = 0; i < size; i++) { + Object o = reader.parseValue(); + + ctx.writeValue(writer, o); + } + } + else { + writer.writeByte(GridPortableMarshaller.COL); + writer.writeInt(delegate.size()); + + byte colType = reader.array()[off + 1 /* flag */ + 4 /* size */]; + writer.writeByte(colType); + + for (Object o : delegate) + ctx.writeValue(writer, o); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1f2be19d/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyMap.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyMap.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyMap.java new file mode 100644 index 0000000..51cf777 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyMap.java @@ -0,0 +1,214 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.portable; + +import org.jetbrains.annotations.*; + +import java.util.*; + +/** + * + */ +class GridPortableLazyMap extends AbstractMap<Object, Object> implements GridPortableBuilderSerializationAware { + /** */ + private final GridPortableBuilderReader reader; + + /** */ + private final int off; + + /** */ + private Map<Object, Object> delegate; + + /** + * @param reader Reader. + * @param off Offset. + */ + private GridPortableLazyMap(GridPortableBuilderReader reader, int off) { + this.reader = reader; + this.off = off; + } + + /** + * @param reader Reader. + * @return GridPortableLazyMap. + */ + @Nullable public static GridPortableLazyMap parseMap(GridPortableBuilderReader reader) { + int off = reader.position() - 1; + + int size = reader.readInt(); + + reader.skip(1); // map type. + + for (int i = 0; i < size; i++) { + reader.skipValue(); // skip key + reader.skipValue(); // skip value + } + + return new GridPortableLazyMap(reader, off); + } + + /** + * + */ + private void ensureDelegateInit() { + if (delegate == null) { + int size = reader.readIntAbsolute(off + 1); + + reader.position(off + 1/* flag */ + 4/* size */ + 1/* col type */); + + delegate = new LinkedHashMap<>(); + + for (int i = 0; i < size; i++) + delegate.put(GridPortableUtils.unwrapLazy(reader.parseValue()), reader.parseValue()); + } + } + + /** {@inheritDoc} */ + @Override public void writeTo(GridPortableWriterImpl writer, GridPortableBuilderSerializer ctx) { + if (delegate == null) { + int size = reader.readIntAbsolute(off + 1); + + int hdrSize = 1 /* flag */ + 4 /* size */ + 1 /* col type */; + writer.write(reader.array(), off, hdrSize); + + reader.position(off + hdrSize); + + for (int i = 0; i < size; i++) { + ctx.writeValue(writer, reader.parseValue()); // key + ctx.writeValue(writer, reader.parseValue()); // value + } + } + else { + writer.writeByte(GridPortableMarshaller.MAP); + writer.writeInt(delegate.size()); + + byte colType = reader.array()[off + 1 /* flag */ + 4 /* size */]; + + writer.writeByte(colType); + + for (Entry<Object, Object> entry : delegate.entrySet()) { + ctx.writeValue(writer, entry.getKey()); + ctx.writeValue(writer, entry.getValue()); + } + } + } + + /** {@inheritDoc} */ + @Override public int size() { + if (delegate == null) + return reader.readIntAbsolute(off + 1); + + return delegate.size(); + } + + /** {@inheritDoc} */ + @Override public boolean containsKey(Object key) { + ensureDelegateInit(); + + return delegate.containsKey(key); + } + + /** {@inheritDoc} */ + @Override public boolean containsValue(Object val) { + return values().contains(val); + } + + /** {@inheritDoc} */ + @Override public Set<Object> keySet() { + ensureDelegateInit(); + + return delegate.keySet(); + } + + /** {@inheritDoc} */ + @Override public void clear() { + if (delegate == null) + delegate = new LinkedHashMap<>(); + else + delegate.clear(); + } + + /** {@inheritDoc} */ + @Override public Object get(Object key) { + ensureDelegateInit(); + + return GridPortableUtils.unwrapLazy(delegate.get(key)); + } + + /** {@inheritDoc} */ + @Override public Object put(Object key, Object val) { + ensureDelegateInit(); + + return GridPortableUtils.unwrapLazy(delegate.put(key, val)); + } + + /** {@inheritDoc} */ + @Override public Object remove(Object key) { + ensureDelegateInit(); + + return GridPortableUtils.unwrapLazy(delegate.remove(key)); + } + + /** {@inheritDoc} */ + @Override public Set<Entry<Object, Object>> entrySet() { + ensureDelegateInit(); + + return new AbstractSet<Entry<Object, Object>>() { + @Override public boolean contains(Object o) { + throw new UnsupportedOperationException(); + } + + @Override public Iterator<Entry<Object, Object>> iterator() { + return new Iterator<Entry<Object, Object>>() { + /** */ + private final Iterator<Entry<Object, Object>> itr = delegate.entrySet().iterator(); + + @Override public boolean hasNext() { + return itr.hasNext(); + } + + @Override public Entry<Object, Object> next() { + Entry<Object, Object> res = itr.next(); + + final Object val = res.getValue(); + + if (val instanceof GridPortableLazyValue) { + return new SimpleEntry<Object, Object>(res.getKey(), val) { + private static final long serialVersionUID = 0L; + + @Override public Object getValue() { + return ((GridPortableLazyValue)val).value(); + } + }; + } + + return res; + } + + @Override public void remove() { + itr.remove(); + } + }; + } + + @Override public int size() { + return delegate.size(); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1f2be19d/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyMapEntry.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyMapEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyMapEntry.java new file mode 100644 index 0000000..169a667 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyMapEntry.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.portable; + +import java.util.*; + +/** + * + */ +class GridPortableLazyMapEntry implements Map.Entry<Object, Object>, GridPortableBuilderSerializationAware { + /** */ + private final Object key; + + /** */ + private Object val; + + /** + * @param reader GridMutablePortableReader + */ + GridPortableLazyMapEntry(GridPortableBuilderReader reader) { + key = reader.parseValue(); + val = reader.parseValue(); + } + + /** {@inheritDoc} */ + @Override public Object getKey() { + return GridPortableUtils.unwrapLazy(key); + } + + /** {@inheritDoc} */ + @Override public Object getValue() { + return GridPortableUtils.unwrapLazy(val); + } + + /** {@inheritDoc} */ + @Override public Object setValue(Object val) { + Object res = getValue(); + + this.val = val; + + return res; + } + + /** {@inheritDoc} */ + @Override public void writeTo(GridPortableWriterImpl writer, GridPortableBuilderSerializer ctx) { + writer.writeByte(GridPortableMarshaller.MAP_ENTRY); + + ctx.writeValue(writer, key); + ctx.writeValue(writer, val); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1f2be19d/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazySet.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazySet.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazySet.java new file mode 100644 index 0000000..ef3780d --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazySet.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.portable; + +import org.apache.ignite.internal.util.typedef.internal.*; + +import java.util.*; + +/** + * + */ +class GridPortableLazySet extends GridPortableAbstractLazyValue { + /** */ + private final int off; + + /** + * @param reader Reader. + * @param size Size. + */ + GridPortableLazySet(GridPortableBuilderReader reader, int size) { + super(reader, reader.position() - 1); + + off = reader.position() - 1/* flag */ - 4/* size */ - 1/* col type */; + + assert size >= 0; + + for (int i = 0; i < size; i++) + reader.skipValue(); + } + + /** {@inheritDoc} */ + @Override public void writeTo(GridPortableWriterImpl writer, GridPortableBuilderSerializer ctx) { + if (val == null) { + int size = reader.readIntAbsolute(off + 1); + + int hdrSize = 1 /* flag */ + 4 /* size */ + 1 /* col type */; + writer.write(reader.array(), off, hdrSize); + + reader.position(off + hdrSize); + + for (int i = 0; i < size; i++) { + Object o = reader.parseValue(); + + ctx.writeValue(writer, o); + } + } + else { + Collection<Object> c = (Collection<Object>)val; + + writer.writeByte(GridPortableMarshaller.COL); + writer.writeInt(c.size()); + + byte colType = reader.array()[off + 1 /* flag */ + 4 /* size */]; + writer.writeByte(colType); + + for (Object o : c) + ctx.writeValue(writer, o); + } + } + + /** {@inheritDoc} */ + @Override protected Object init() { + int size = reader.readIntAbsolute(off + 1); + + reader.position(off + 1/* flag */ + 4/* size */ + 1/* col type */); + + Set<Object> res = U.newLinkedHashSet(size); + + for (int i = 0; i < size; i++) + res.add(GridPortableUtils.unwrapLazy(reader.parseValue())); + + return res; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1f2be19d/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyValue.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyValue.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyValue.java new file mode 100644 index 0000000..6dbef93 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableLazyValue.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.portable; + +/** + * + */ +interface GridPortableLazyValue extends GridPortableBuilderSerializationAware { + /** + * @return Value. + */ + public Object value(); +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1f2be19d/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableMarshaller.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableMarshaller.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableMarshaller.java new file mode 100644 index 0000000..9015425 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableMarshaller.java @@ -0,0 +1,304 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.portable; + +import org.apache.ignite.internal.processors.portable.*; +import org.apache.ignite.portable.*; + +import org.jetbrains.annotations.*; + +/** + * Portable objects marshaller. + */ +public class GridPortableMarshaller { + /** */ + public static final ThreadLocal<Boolean> KEEP_PORTABLES = new ThreadLocal<Boolean>() { + @Override protected Boolean initialValue() { + return true; + } + }; + + /** */ + static final byte OPTM_MARSH = -2; + + /** */ + public static final byte BYTE = 1; + + /** */ + public static final byte SHORT = 2; + + /** */ + public static final byte INT = 3; + + /** */ + public static final byte LONG = 4; + + /** */ + public static final byte FLOAT = 5; + + /** */ + public static final byte DOUBLE = 6; + + /** */ + public static final byte CHAR = 7; + + /** */ + public static final byte BOOLEAN = 8; + + /** */ + public static final byte DECIMAL = 30; + + /** */ + public static final byte STRING = 9; + + /** */ + public static final byte UUID = 10; + + /** */ + public static final byte DATE = 11; + + /** */ + public static final byte BYTE_ARR = 12; + + /** */ + public static final byte SHORT_ARR = 13; + + /** */ + public static final byte INT_ARR = 14; + + /** */ + public static final byte LONG_ARR = 15; + + /** */ + public static final byte FLOAT_ARR = 16; + + /** */ + public static final byte DOUBLE_ARR = 17; + + /** */ + public static final byte CHAR_ARR = 18; + + /** */ + public static final byte BOOLEAN_ARR = 19; + + /** */ + public static final byte DECIMAL_ARR = 31; + + /** */ + public static final byte STRING_ARR = 20; + + /** */ + public static final byte UUID_ARR = 21; + + /** */ + public static final byte DATE_ARR = 22; + + /** */ + public static final byte OBJ_ARR = 23; + + /** */ + public static final byte COL = 24; + + /** */ + public static final byte MAP = 25; + + /** */ + public static final byte MAP_ENTRY = 26; + + /** */ + public static final byte PORTABLE_OBJ = 27; + + /** */ + public static final byte ENUM = 28; + + /** */ + public static final byte ENUM_ARR = 29; + + /** */ + public static final byte CLASS = 32; + + /** */ + public static final byte NULL = (byte)101; + + /** */ + public static final byte HANDLE = (byte)102; + + /** */ + public static final byte OBJ = (byte)103; + + /** */ + static final byte USER_SET = -1; + + /** */ + static final byte USER_COL = 0; + + /** */ + static final byte ARR_LIST = 1; + + /** */ + static final byte LINKED_LIST = 2; + + /** */ + static final byte HASH_SET = 3; + + /** */ + static final byte LINKED_HASH_SET = 4; + + /** */ + static final byte TREE_SET = 5; + + /** */ + static final byte CONC_SKIP_LIST_SET = 6; + + /** */ + static final byte HASH_MAP = 1; + + /** */ + static final byte LINKED_HASH_MAP = 2; + + /** */ + static final byte TREE_MAP = 3; + + /** */ + static final byte CONC_HASH_MAP = 4; + + /** */ + static final byte PROPERTIES_MAP = 5; + + /** */ + static final int OBJECT_TYPE_ID = -1; + + /** */ + static final int UNREGISTERED_TYPE_ID = 0; + + /** */ + static final int TYPE_ID_POS = 2; + + /** */ + static final int HASH_CODE_POS = 6; + + /** */ + static final int TOTAL_LEN_POS = 10; + + /** */ + static final byte RAW_DATA_OFF_POS = 14; + + /** */ + static final int CLS_NAME_POS = 18; + + /** */ + static final byte DFLT_HDR_LEN = 18; + + /** */ + private final GridPortableContext ctx; + + /** + * @param ctx Context. + */ + public GridPortableMarshaller(GridPortableContext ctx) { + this.ctx = ctx; + } + + /** + * @param obj Object to marshal. + * @param off Offset. + * @return Byte array. + * @throws PortableException In case of error. + */ + public byte[] marshal(@Nullable Object obj, int off) throws PortableException { + if (obj == null) + return new byte[] { NULL }; + + try (GridPortableWriterImpl writer = new GridPortableWriterImpl(ctx, off)) { + writer.marshal(obj, false); + + return writer.array(); + } + } + + /** + * @param bytes Bytes array. + * @return Portable object. + * @throws PortableException In case of error. + */ + @SuppressWarnings("unchecked") + @Nullable public <T> T unmarshal(byte[] bytes, @Nullable ClassLoader clsLdr) throws PortableException { + assert bytes != null; + + GridGridPortableReaderImpl reader = new GridGridPortableReaderImpl(ctx, bytes, 0, clsLdr); + + return (T)reader.unmarshal(); + } + + /** + * @param in Input stream. + * @return Portable object. + * @throws PortableException In case of error. + */ + @SuppressWarnings("unchecked") + @Nullable public <T> T unmarshal(GridPortableInputStream in) throws PortableException { + return (T)reader(in).unmarshal(); + } + + /** + * @param arr Byte array. + * @param ldr Class loader. + * @return Deserialized object. + * @throws PortableException In case of error. + */ + @SuppressWarnings("unchecked") + @Nullable public <T> T deserialize(byte[] arr, @Nullable ClassLoader ldr) throws PortableException { + assert arr != null; + assert arr.length > 0; + + if (arr[0] == NULL) + return null; + + GridGridPortableReaderImpl reader = new GridGridPortableReaderImpl(ctx, arr, 0, ldr); + + return (T)reader.deserialize(); + } + + /** + * Gets writer for the given output stream. + * + * @param out Output stream. + * @return Writer. + */ + public GridPortableWriterImpl writer(GridPortableOutputStream out) { + return new GridPortableWriterImpl(ctx, out, 0); + } + + /** + * Gets reader for the given input stream. + * + * @param in Input stream. + * @return Reader. + */ + public GridGridPortableReaderImpl reader(GridPortableInputStream in) { + // TODO: GG-10396 - Is class loader needed here? + return new GridGridPortableReaderImpl(ctx, in, in.position(), null); + } + + /** + * @return Context. + */ + public GridPortableContext context() { + return ctx; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1f2be19d/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableMetaDataCollector.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableMetaDataCollector.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableMetaDataCollector.java new file mode 100644 index 0000000..db651df --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableMetaDataCollector.java @@ -0,0 +1,253 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.portable; + +import org.apache.ignite.portable.*; + +import org.jetbrains.annotations.*; + +import java.lang.reflect.*; +import java.math.*; +import java.sql.*; +import java.util.*; +import java.util.Date; + +/** + * Writer for meta data collection. + */ +class GridPortableMetaDataCollector implements PortableWriter { + /** */ + private final Map<String, String> meta = new HashMap<>(); + + /** */ + private final String typeName; + + /** + * @param typeName Type name. + */ + GridPortableMetaDataCollector(String typeName) { + this.typeName = typeName; + } + + /** + * @return Field meta data. + */ + Map<String, String> meta() { + return meta; + } + + /** {@inheritDoc} */ + @Override public void writeByte(String fieldName, byte val) throws PortableException { + add(fieldName, byte.class); + } + + /** {@inheritDoc} */ + @Override public void writeShort(String fieldName, short val) throws PortableException { + add(fieldName, short.class); + } + + /** {@inheritDoc} */ + @Override public void writeInt(String fieldName, int val) throws PortableException { + add(fieldName, int.class); + } + + /** {@inheritDoc} */ + @Override public void writeLong(String fieldName, long val) throws PortableException { + add(fieldName, long.class); + } + + /** {@inheritDoc} */ + @Override public void writeFloat(String fieldName, float val) throws PortableException { + add(fieldName, float.class); + } + + /** {@inheritDoc} */ + @Override public void writeDouble(String fieldName, double val) throws PortableException { + add(fieldName, double.class); + } + + /** {@inheritDoc} */ + @Override public void writeChar(String fieldName, char val) throws PortableException { + add(fieldName, char.class); + } + + /** {@inheritDoc} */ + @Override public void writeBoolean(String fieldName, boolean val) throws PortableException { + add(fieldName, boolean.class); + } + + /** {@inheritDoc} */ + @Override public void writeDecimal(String fieldName, @Nullable BigDecimal val) throws PortableException { + add(fieldName, GridPortableClassDescriptor.Mode.DECIMAL.typeName()); + } + + /** {@inheritDoc} */ + @Override public void writeString(String fieldName, @Nullable String val) throws PortableException { + add(fieldName, String.class); + } + + /** {@inheritDoc} */ + @Override public void writeUuid(String fieldName, @Nullable UUID val) throws PortableException { + add(fieldName, UUID.class); + } + + /** {@inheritDoc} */ + @Override public void writeDate(String fieldName, @Nullable Date val) throws PortableException { + add(fieldName, Date.class); + } + + /** {@inheritDoc} */ + @Override public void writeTimestamp(String fieldName, @Nullable Timestamp val) throws PortableException { + add(fieldName, Timestamp.class); + } + + /** {@inheritDoc} */ + @Override public <T extends Enum<?>> void writeEnum(String fieldName, T val) throws PortableException { + add(fieldName, Enum.class); + } + + /** {@inheritDoc} */ + @Override public <T extends Enum<?>> void writeEnumArray(String fieldName, T[] val) throws PortableException { + add(fieldName, Enum[].class); + } + + /** {@inheritDoc} */ + @Override public void writeObject(String fieldName, @Nullable Object obj) throws PortableException { + add(fieldName, Object.class); + } + + /** {@inheritDoc} */ + @Override public void writeByteArray(String fieldName, @Nullable byte[] val) throws PortableException { + add(fieldName, byte[].class); + } + + /** {@inheritDoc} */ + @Override public void writeShortArray(String fieldName, @Nullable short[] val) throws PortableException { + add(fieldName, short[].class); + } + + /** {@inheritDoc} */ + @Override public void writeIntArray(String fieldName, @Nullable int[] val) throws PortableException { + add(fieldName, int[].class); + } + + /** {@inheritDoc} */ + @Override public void writeLongArray(String fieldName, @Nullable long[] val) throws PortableException { + add(fieldName, long[].class); + } + + /** {@inheritDoc} */ + @Override public void writeFloatArray(String fieldName, @Nullable float[] val) throws PortableException { + add(fieldName, float[].class); + } + + /** {@inheritDoc} */ + @Override public void writeDoubleArray(String fieldName, @Nullable double[] val) throws PortableException { + add(fieldName, double[].class); + } + + /** {@inheritDoc} */ + @Override public void writeCharArray(String fieldName, @Nullable char[] val) throws PortableException { + add(fieldName, char[].class); + } + + /** {@inheritDoc} */ + @Override public void writeBooleanArray(String fieldName, @Nullable boolean[] val) throws PortableException { + add(fieldName, boolean[].class); + } + + /** {@inheritDoc} */ + @Override public void writeDecimalArray(String fieldName, @Nullable BigDecimal[] val) throws PortableException { + add(fieldName, GridPortableClassDescriptor.Mode.DECIMAL_ARR.typeName()); + } + + /** {@inheritDoc} */ + @Override public void writeStringArray(String fieldName, @Nullable String[] val) throws PortableException { + add(fieldName, String[].class); + } + + /** {@inheritDoc} */ + @Override public void writeUuidArray(String fieldName, @Nullable UUID[] val) throws PortableException { + add(fieldName, UUID[].class); + } + + /** {@inheritDoc} */ + @Override public void writeDateArray(String fieldName, @Nullable Date[] val) throws PortableException { + add(fieldName, Date[].class); + } + + /** {@inheritDoc} */ + @Override public void writeObjectArray(String fieldName, @Nullable Object[] val) throws PortableException { + add(fieldName, Object[].class); + } + + /** {@inheritDoc} */ + @Override public <T> void writeCollection(String fieldName, @Nullable Collection<T> col) + throws PortableException { + add(fieldName, Collection.class); + } + + /** {@inheritDoc} */ + @Override public <K, V> void writeMap(String fieldName, @Nullable Map<K, V> map) throws PortableException { + add(fieldName, Map.class); + } + + /** {@inheritDoc} */ + @Override public PortableRawWriter rawWriter() { + return (PortableRawWriter)Proxy.newProxyInstance(getClass().getClassLoader(), + new Class<?>[] { GridPortableRawWriter.class }, + new InvocationHandler() { + @Override public Object invoke(Object proxy, Method mtd, Object[] args) throws Throwable { + return null; + } + }); + } + + /** + * @param name Field name. + * @param fieldType Field type. + * @throws PortableException In case of error. + */ + private void add(String name, Class<?> fieldType) throws PortableException { + assert fieldType != null; + + add(name, fieldType.getSimpleName()); + } + + /** + * @param name Field name. + * @param fieldTypeName Field type name. + * @throws PortableException In case of error. + */ + private void add(String name, String fieldTypeName) throws PortableException { + assert name != null; + + String oldFieldTypeName = meta.put(name, fieldTypeName); + + if (oldFieldTypeName != null && !oldFieldTypeName.equals(fieldTypeName)) { + throw new PortableException( + "Field is written twice with different types [" + + "typeName=" + typeName + + ", fieldName=" + name + + ", fieldTypeName1=" + oldFieldTypeName + + ", fieldTypeName2=" + fieldTypeName + + ']' + ); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/1f2be19d/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableMetaDataHandler.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableMetaDataHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableMetaDataHandler.java new file mode 100644 index 0000000..d0d8671 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableMetaDataHandler.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.portable; + +import org.apache.ignite.portable.*; + +/** + * Portable meta data handler. + */ +public interface GridPortableMetaDataHandler { + /** + * Adds meta data. + * + * @param typeId Type ID. + * @param meta Meta data. + * @throws PortableException In case of error. + */ + public void addMeta(int typeId, GridPortableMetaDataImpl meta) throws PortableException; + + /** + * Gets meta data for provided type ID. + * + * @param typeId Type ID. + * @return Meta data. + * @throws PortableException In case of error. + */ + public PortableMetadata metadata(int typeId) throws PortableException; +}