/* * 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.datastructures; import java.io.Externalizable; import java.io.IOException; import java.io.InvalidObjectException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.ObjectStreamException; import java.util.Collection; import java.util.Iterator; import java.util.concurrent.TimeUnit; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteQueue; import org.apache.ignite.internal.GridKernalContext; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheGateway; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteBiTuple; import org.apache.ignite.lang.IgniteCallable; import org.apache.ignite.lang.IgniteRunnable; import org.jetbrains.annotations.Nullable; /** * Cache queue proxy. */ public class GridCacheQueueProxy<T> implements IgniteQueue<T>, Externalizable { /** */ private static final long serialVersionUID = 0L; /** Deserialization stash. */ private static final ThreadLocal<IgniteBiTuple<GridKernalContext, String>> stash = new ThreadLocal<IgniteBiTuple<GridKernalContext, String>>() { @Override protected IgniteBiTuple<GridKernalContext, String> initialValue() { return new IgniteBiTuple<>(); } }; /** Delegate queue. */ private GridCacheQueueAdapter<T> delegate; /** Cache context. */ private GridCacheContext cctx; /** Cache gateway. */ private GridCacheGateway gate; /** * Required by {@link Externalizable}. */ public GridCacheQueueProxy() { // No-op. } /** * @param cctx Cache context. * @param delegate Delegate queue. */ public GridCacheQueueProxy(GridCacheContext cctx, GridCacheQueueAdapter<T> delegate) { this.cctx = cctx; this.delegate = delegate; gate = cctx.gate(); } /** * @return Delegate queue. */ public GridCacheQueueAdapter<T> delegate() { return delegate; } /** {@inheritDoc} */ @Override public boolean add(final T item) { gate.enter(); try { return delegate.add(item); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public boolean offer(final T item) { gate.enter(); try { return delegate.offer(item); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public boolean addAll(final Collection<? extends T> items) { gate.enter(); try { return delegate.addAll(items); } finally { gate.leave(); } } /** {@inheritDoc} */ @SuppressWarnings("SuspiciousMethodCalls") @Override public boolean contains(final Object item) { gate.enter(); try { return delegate.contains(item); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public boolean containsAll(final Collection<?> items) { gate.enter(); try { return delegate.containsAll(items); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public void clear() { gate.enter(); try { delegate.clear(); } finally { gate.leave(); } } /** {@inheritDoc} */ @SuppressWarnings("SuspiciousMethodCalls") @Override public boolean remove(final Object item) { gate.enter(); try { return delegate.remove(item); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public boolean removeAll(final Collection<?> items) { gate.enter(); try { return delegate.removeAll(items); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public boolean isEmpty() { gate.enter(); try { return delegate.isEmpty(); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public Iterator<T> iterator() { gate.enter(); try { return delegate.iterator(); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public Object[] toArray() { gate.enter(); try { return delegate.toArray(); } finally { gate.leave(); } } /** {@inheritDoc} */ @SuppressWarnings("SuspiciousToArrayCall") @Override public <T1> T1[] toArray(final T1[] a) { gate.enter(); try { return delegate.toArray(a); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public boolean retainAll(final Collection<?> items) { gate.enter(); try { return delegate.retainAll(items); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public int size() { gate.enter(); try { return delegate.size(); } finally { gate.leave(); } } /** {@inheritDoc} */ @Nullable @Override public T poll() { gate.enter(); try { return delegate.poll(); } finally { gate.leave(); } } /** {@inheritDoc} */ @Nullable @Override public T peek() { gate.enter(); try { return delegate.peek(); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public void clear(final int batchSize) { gate.enter(); try { delegate.clear(batchSize); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public int remainingCapacity() { gate.enter(); try { return delegate.remainingCapacity(); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public int drainTo(final Collection<? super T> c) { gate.enter(); try { return delegate.drainTo(c); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public int drainTo(final Collection<? super T> c, final int maxElements) { gate.enter(); try { return delegate.drainTo(c, maxElements); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public T remove() { gate.enter(); try { return delegate.remove(); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public T element() { gate.enter(); try { return delegate.element(); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public void put(final T item) { gate.enter(); try { delegate.put(item); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public boolean offer(final T item, final long timeout, final TimeUnit unit) { gate.enter(); try { return delegate.offer(item, timeout, unit); } finally { gate.leave(); } } /** {@inheritDoc} */ @Nullable @Override public T take() { gate.enter(); try { return delegate.take(); } finally { gate.leave(); } } /** {@inheritDoc} */ @Nullable @Override public T poll(final long timeout, final TimeUnit unit) { gate.enter(); try { return delegate.poll(timeout, unit); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public void close() { gate.enter(); try { delegate.close(); } finally { gate.leave(); } } /** {@inheritDoc} */ @Override public String name() { return delegate.name(); } /** {@inheritDoc} */ @Override public int capacity() { return delegate.capacity(); } /** {@inheritDoc} */ @Override public boolean bounded() { return delegate.bounded(); } /** {@inheritDoc} */ @Override public boolean collocated() { return delegate.collocated(); } /** {@inheritDoc} */ @Override public boolean removed() { return delegate.removed(); } /** {@inheritDoc} */ @Override public void affinityRun(final IgniteRunnable job) { delegate.affinityRun(job); } /** {@inheritDoc} */ @Override public <R> R affinityCall(final IgniteCallable<R> job) { return delegate.affinityCall(job); } /** {@inheritDoc} */ @Override public int hashCode() { return delegate.hashCode(); } /** {@inheritDoc} */ @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; GridCacheQueueProxy that = (GridCacheQueueProxy)o; return delegate.equals(that.delegate); } /** {@inheritDoc} */ @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(cctx.kernalContext()); U.writeString(out, name()); } /** {@inheritDoc} */ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { IgniteBiTuple<GridKernalContext, String> t = stash.get(); t.set1((GridKernalContext)in.readObject()); t.set2(U.readString(in)); } /** * Reconstructs object on unmarshalling. * * @return Reconstructed object. * @throws ObjectStreamException Thrown in case of unmarshalling error. */ protected Object readResolve() throws ObjectStreamException { try { IgniteBiTuple<GridKernalContext, String> t = stash.get(); return t.get1().dataStructures().queue(t.get2(), 0, null); } catch (IgniteCheckedException e) { throw U.withCause(new InvalidObjectException(e.getMessage()), e); } finally { stash.remove(); } } /** {@inheritDoc} */ @Override public String toString() { return delegate.toString(); } }