/* * 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.processors.cache; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.Map; import org.apache.ignite.cache.affinity.AffinityKeyMapper; import org.apache.ignite.internal.GridKernalContext; import org.apache.ignite.internal.binary.BinaryUtils; import org.apache.ignite.internal.processors.cacheobject.IgniteCacheObjectProcessor; import org.apache.ignite.internal.util.typedef.F; /** * */ @SuppressWarnings("TypeMayBeWeakened") public class CacheObjectContext { /** */ private GridKernalContext kernalCtx; /** */ private IgniteCacheObjectProcessor proc; /** */ private String cacheName; /** */ private AffinityKeyMapper dfltAffMapper; /** */ private boolean cpyOnGet; /** */ private boolean storeVal; /** */ private boolean p2pEnabled; /** */ private boolean addDepInfo; /** * @param kernalCtx Kernal context. * @param dfltAffMapper Default affinity mapper. * @param cpyOnGet Copy on get flag. * @param storeVal {@code True} if should store unmarshalled value in cache. * @param addDepInfo {@code true} if deployment info should be associated with the objects of this cache. */ public CacheObjectContext(GridKernalContext kernalCtx, String cacheName, AffinityKeyMapper dfltAffMapper, boolean cpyOnGet, boolean storeVal, boolean addDepInfo) { this.kernalCtx = kernalCtx; this.cacheName = cacheName; this.dfltAffMapper = dfltAffMapper; this.cpyOnGet = cpyOnGet; this.storeVal = storeVal; this.addDepInfo = addDepInfo; p2pEnabled = kernalCtx.config().isPeerClassLoadingEnabled(); proc = kernalCtx.cacheObjects(); } /** * @return Cache name. */ public String cacheName() { return cacheName; } /** * @return {@code True} if peer class loading is enabled. */ public boolean p2pEnabled() { return p2pEnabled; } /** * @return {@code True} if deployment info should be associated with the objects of this cache. */ public boolean addDeploymentInfo() { return addDepInfo; } /** * @return Copy on get flag. */ public boolean copyOnGet() { return cpyOnGet; } /** * @return {@code True} if should store unmarshalled value in cache. */ public boolean storeValue() { return storeVal; } /** * @return Default affinity mapper. */ public AffinityKeyMapper defaultAffMapper() { return dfltAffMapper; } /** * @return Kernal context. */ public GridKernalContext kernalContext() { return kernalCtx; } /** * @return Processor. */ public IgniteCacheObjectProcessor processor() { return proc; } /** * @param o Object to unwrap. * @param keepBinary Keep binary flag. * @return Unwrapped object. */ public Object unwrapBinaryIfNeeded(Object o, boolean keepBinary) { return unwrapBinaryIfNeeded(o, keepBinary, true); } /** * @param o Object to unwrap. * @param keepBinary Keep binary flag. * @param cpy Copy value flag. * @return Unwrapped object. */ public Object unwrapBinaryIfNeeded(Object o, boolean keepBinary, boolean cpy) { if (o == null) return null; return unwrapBinary(o, keepBinary, cpy); } /** * @param col Collection of objects to unwrap. * @param keepBinary Keep binary flag. * @return Unwrapped collection. */ public Collection<Object> unwrapBinariesIfNeeded(Collection<Object> col, boolean keepBinary) { return unwrapBinariesIfNeeded(col, keepBinary, true); } /** * @param col Collection to unwrap. * @param keepBinary Keep binary flag. * @param cpy Copy value flag. * @return Unwrapped collection. */ public Collection<Object> unwrapBinariesIfNeeded(Collection<Object> col, boolean keepBinary, boolean cpy) { Collection<Object> col0 = BinaryUtils.newKnownCollection(col); if (col0 == null) col0 = new ArrayList<>(col.size()); for (Object obj : col) col0.add(unwrapBinary(obj, keepBinary, cpy)); return col0; } /** * @param col Collection to unwrap. * @param keepBinary Keep binary flag. * @param cpy Copy flag. * @return Unwrapped collection. */ private Collection<Object> unwrapKnownCollection(Collection<Object> col, boolean keepBinary, boolean cpy) { Collection<Object> col0 = BinaryUtils.newKnownCollection(col); for (Object obj : col) col0.add(unwrapBinary(obj, keepBinary, cpy)); return col0; } /** * Unwrap array of binaries if needed. * * @param arr Array. * @param keepBinary Keep binary flag. * @param cpy Copy. * @return Result. */ public Object[] unwrapBinariesInArrayIfNeeded(Object[] arr, boolean keepBinary, boolean cpy) { if (BinaryUtils.knownArray(arr)) return arr; Object[] res = new Object[arr.length]; for (int i = 0; i < arr.length; i++) res[i] = unwrapBinary(arr[i], keepBinary, cpy); return res; } /** * Unwraps map. * * @param map Map to unwrap. * @param keepBinary Keep binary flag. * @return Unwrapped collection. */ private Map<Object, Object> unwrapBinariesIfNeeded(Map<Object, Object> map, boolean keepBinary, boolean cpy) { if (keepBinary) return map; Map<Object, Object> map0 = BinaryUtils.newMap(map); for (Map.Entry<Object, Object> e : map.entrySet()) map0.put(unwrapBinary(e.getKey(), keepBinary, cpy), unwrapBinary(e.getValue(), keepBinary, cpy)); return map0; } /** * @param o Object to unwrap. * @return Unwrapped object. */ private Object unwrapBinary(Object o, boolean keepBinary, boolean cpy) { if (o instanceof Map.Entry) { Map.Entry entry = (Map.Entry)o; Object key = entry.getKey(); Object uKey = unwrapBinary(key, keepBinary, cpy); Object val = entry.getValue(); Object uVal = unwrapBinary(val, keepBinary, cpy); return (key != uKey || val != uVal) ? F.t(uKey, uVal) : o; } else if (BinaryUtils.knownCollection(o)) return unwrapKnownCollection((Collection<Object>)o, keepBinary, cpy); else if (BinaryUtils.knownMap(o)) return unwrapBinariesIfNeeded((Map<Object, Object>)o, keepBinary, cpy); else if (o instanceof Object[]) return unwrapBinariesInArrayIfNeeded((Object[])o, keepBinary, cpy); else if (o instanceof CacheObject) { CacheObject co = (CacheObject)o; if (!keepBinary || co.isPlatformType()) return unwrapBinary(co.value(this, cpy), keepBinary, cpy); } return o; } /** * @param o Object to test. * @return True if collection should be recursively unwrapped. */ private boolean knownCollection(Object o) { Class<?> cls = o == null ? null : o.getClass(); return cls == ArrayList.class || cls == LinkedList.class || cls == HashSet.class; } /** * @param o Object to test. * @return True if map should be recursively unwrapped. */ private boolean knownMap(Object o) { Class<?> cls = o == null ? null : o.getClass(); return cls == HashMap.class || cls == LinkedHashMap.class; } }