| // Copyright 2016 The Vanadium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package io.v.impl.google.lib.discovery; |
| |
| import com.google.common.base.Function; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableMap; |
| import com.google.common.collect.Maps; |
| import com.google.common.util.concurrent.Futures; |
| import com.google.common.util.concurrent.ListenableFuture; |
| |
| import java.util.Arrays; |
| import java.util.List; |
| |
| import io.v.v23.VFutures; |
| import io.v.v23.context.VContext; |
| import io.v.v23.discovery.AdId; |
| import io.v.v23.discovery.Advertisement; |
| import io.v.v23.discovery.Attachments; |
| import io.v.v23.discovery.Attributes; |
| import io.v.v23.discovery.Update; |
| import io.v.v23.verror.VException; |
| import io.v.v23.vom.VomUtil; |
| |
| import io.v.impl.google.ListenableFutureCallback; |
| |
| class UpdateImpl implements Update { |
| private final long nativeRef; |
| |
| private boolean lost; |
| private Advertisement ad; |
| private long timestampNs; |
| |
| private native void nativeAttachment( |
| long nativeRef, VContext ctx, String name, ListenableFutureCallback<byte[]> callback) |
| throws VException; |
| |
| private native void nativeFinalize(long nativeRef); |
| |
| private UpdateImpl(long nativeRef, boolean lost, Advertisement ad, long timestampNs) { |
| this.nativeRef = nativeRef; |
| this.lost = lost; |
| this.ad = ad; |
| this.timestampNs = timestampNs; |
| } |
| |
| @Override |
| public boolean isLost() { |
| return lost; |
| } |
| |
| @Override |
| public AdId getId() { |
| return ad.getId(); |
| } |
| |
| @Override |
| public String getInterfaceName() { |
| return ad.getInterfaceName(); |
| } |
| |
| @Override |
| public List<String> getAddresses() { |
| return ImmutableList.copyOf(ad.getAddresses()); |
| } |
| |
| @Override |
| public String getAttribute(String name) { |
| Attributes attributes = ad.getAttributes(); |
| if (attributes != null) { |
| return attributes.get(name); |
| } |
| return null; |
| } |
| |
| @Override |
| public ListenableFuture<byte[]> getAttachment(VContext ctx, final String name) |
| throws VException { |
| synchronized (ad) { |
| Attachments attachments = ad.getAttachments(); |
| if (attachments != null) { |
| if (attachments.containsKey(name)) { |
| byte[] data = attachments.get(name); |
| return Futures.immediateFuture(Arrays.copyOf(data, data.length)); |
| } |
| } |
| } |
| |
| ListenableFutureCallback<byte[]> callback = new ListenableFutureCallback<>(); |
| nativeAttachment(nativeRef, ctx, name, callback); |
| return VFutures.withUserLandChecks( |
| ctx, |
| Futures.transform( |
| callback.getVanillaFuture(), |
| new Function<byte[], byte[]>() { |
| @Override |
| public byte[] apply(byte[] data) { |
| synchronized (ad) { |
| Attachments attachments = ad.getAttachments(); |
| if (attachments == null) { |
| attachments = new Attachments(); |
| ad.setAttachments(attachments); |
| } |
| attachments.put(name, data); |
| return Arrays.copyOf(data, data.length); |
| } |
| } |
| })); |
| } |
| |
| @Override |
| public Advertisement getAdvertisement() { |
| return new Advertisement( |
| ad.getId(), |
| ad.getInterfaceName(), |
| ImmutableList.copyOf(ad.getAddresses()), |
| new Attributes(ImmutableMap.copyOf(ad.getAttributes())), |
| new Attachments( |
| Maps.transformValues( |
| ad.getAttachments(), |
| new Function<byte[], byte[]>() { |
| @Override |
| public byte[] apply(byte[] data) { |
| return Arrays.copyOf(data, data.length); |
| } |
| }))); |
| } |
| |
| @Override |
| public long getTimestampNs() { |
| return timestampNs; |
| } |
| |
| @Override |
| public String toString() { |
| return String.format( |
| "{%b %s %s %s %s}", |
| lost, |
| VomUtil.bytesToHexString(ad.getId().toPrimitiveArray()), |
| ad.getInterfaceName(), |
| ad.getAddresses(), |
| ad.getAttributes()); |
| } |
| |
| @Override |
| protected void finalize() throws Throwable { |
| super.finalize(); |
| nativeFinalize(nativeRef); |
| } |
| } |