Is there any way to pass Observable<String> into AbstractInputStreamContent? - arrays

I'm working on uploading a text file to Google Drive
ByteArrayContent content = new ByteArrayContent("text/csv", fileContent.getBytes(Charset.forName("UTF-8")));
Drive.Files.Insert request = drive.files().insert(file, content);
where type(fileContent) = String
I'd like to refactor and change type of fileContent to Observable<String>, is there any nice workaround to pass it to that insert() function (which takes AbstractInputStreamContent as a second argument)?
Thanks

Here is a general Flowable -> InputStream bridge you can delegate to:
import java.io.*;
import java.nio.charset.Charset;
import java.util.concurrent.atomic.AtomicReference;
import org.reactivestreams.*;
import io.reactivex.FlowableSubscriber;
import io.reactivex.internal.subscriptions.SubscriptionHelper;
public final class FlowableStringInputStream {
private FlowableStringInputStream() {
throw new IllegalStateException("No instances!");
}
public static InputStream createInputStream(
Publisher<String> source, Charset charset) {
StringInputStream parent = new StringInputStream(charset);
source.subscribe(parent);
return parent;
}
static final class StringInputStream extends InputStream
implements FlowableSubscriber<String> {
final AtomicReference<Subscription> upstream;
final Charset charset;
volatile byte[] bytes;
int index;
volatile boolean done;
Throwable error;
StringInputStream(Charset charset) {
this.charset = charset;
upstream = new AtomicReference<>();
}
#Override
public void onSubscribe(Subscription s) {
if (SubscriptionHelper.setOnce(upstream, s)) {
s.request(1);
}
}
#Override
public void onNext(String t) {
bytes = t.getBytes(charset);
synchronized (this) {
notifyAll();
}
}
#Override
public void onError(Throwable t) {
error = t;
done = true;
synchronized (this) {
notifyAll();
}
}
#Override
public void onComplete() {
done = true;
synchronized (this) {
notifyAll();
}
}
#Override
public int read() throws IOException {
for (;;) {
byte[] a = awaitBufferIfNecessary();
if (a == null) {
Throwable ex = error;
if (ex != null) {
if (ex instanceof IOException) {
throw (IOException)ex;
}
throw new IOException(ex);
}
return -1;
}
int idx = index;
if (idx == a.length) {
index = 0;
bytes = null;
upstream.get().request(1);
} else {
int result = a[idx] & 0xFF;
index = idx + 1;
return result;
}
}
}
byte[] awaitBufferIfNecessary() throws IOException {
byte[] a = bytes;
if (a == null) {
synchronized (this) {
for (;;) {
boolean d = done;
a = bytes;
if (a != null) {
break;
}
if (d || upstream.get() == SubscriptionHelper.CANCELLED) {
break;
}
try {
wait();
} catch (InterruptedException ex) {
if (upstream.get() != SubscriptionHelper.CANCELLED) {
InterruptedIOException exc = new InterruptedIOException();
exc.initCause(ex);
throw exc;
}
break;
}
}
}
}
return a;
}
#Override
public int read(byte[] b, int off, int len) throws IOException {
if (off < 0 || len < 0 || off >= b.length || off + len > b.length) {
throw new IndexOutOfBoundsException(
"b.length=" + b.length + ", off=" + off + ", len=" + len);
}
for (;;) {
byte[] a = awaitBufferIfNecessary();
if (a == null) {
Throwable ex = error;
if (ex != null) {
if (ex instanceof IOException) {
throw (IOException)ex;
}
throw new IOException(ex);
}
return -1;
}
int idx = index;
if (idx == a.length) {
index = 0;
bytes = null;
upstream.get().request(1);
} else {
int r = 0;
while (idx < a.length && len > 0) {
b[off] = a[idx];
idx++;
off++;
r++;
len--;
}
index = idx;
return r;
}
}
}
#Override
public int available() throws IOException {
byte[] a = bytes;
int idx = index;
return a != null ? Math.max(0, a.length - idx) : 0;
}
#Override
public void close() throws IOException {
SubscriptionHelper.cancel(upstream);
synchronized (this) {
notifyAll();
}
}
}
}
Usage:
#Test(timeout = 10000)
public void async() throws Exception {
AtomicInteger calls = new AtomicInteger();
Flowable<String> f = Flowable.range(100, 10).map(Object::toString)
.doOnCancel(() -> calls.incrementAndGet())
.subscribeOn(Schedulers.computation())
.delay(10, TimeUnit.MILLISECONDS);
try (InputStream is = FlowableStringInputStream.createInputStream(f, utf8)) {
assertEquals('1', is.read());
assertEquals('0', is.read());
assertEquals('0', is.read());
byte[] buf = new byte[3];
assertEquals(3, is.read(buf));
assertArrayEquals("101".getBytes(utf8), buf);
}
assertEquals(1, calls.get());
}

Related

downloadUrlToStorageInBackground in ImageList model for imageViewer downloads & overrides the image every time

class ImageList implements ListModel<Image> {
private int selection;
private Image[] images;
private EventDispatcher listeners = new EventDispatcher();
public ImageList() {
this.images = new EncodedImage[imageURLs.length];
}
public Image getItemAt(final int index) {
if (images[index] == null) {
images[index] = placeholderForTable;
Util.downloadUrlToStorageInBackground(imageURLs[index], "list" + index, (e) -> {
try {
images[index] = EncodedImage.create(Storage.getInstance().createInputStream("list" + index));
listeners.fireDataChangeEvent(index, DataChangedListener.CHANGED);
} catch (IOException err) {
err.printStackTrace();
}
});
}
return images[index];
}
public int getSize() {
return imageURLs.length;
}
public int getSelectedIndex() {
return selection;
}
public void setSelectedIndex(int index) {
selection = index;
}
public void addDataChangedListener(DataChangedListener l) {
listeners.addListener(l);
}
public void removeDataChangedListener(DataChangedListener l) {
listeners.removeListener(l);
}
public void addSelectionListener(SelectionListener l) {
}
public void removeSelectionListener(SelectionListener l) {
}
public void addItem(Image item) {
}
public void removeItem(int index) {
}
}
protected void postMenuForm(Form f) {
BusinessForumImagesConnection bfic = new BusinessForumImagesConnection();
bfic.businessForumImagesConnectionMethod(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
if (bfic.response != null) {
for (int i = 0; i < imgLoop; i++) {
HashMap hm = (HashMap) bfic.response.get(i);
String imgUrl = (String) hm.get("imgUrl");
imageURLs[i] = imgUrl;
}
}
}
});
if (imageURLs != null) {
ImageList imodel = new ImageList();
ImageViewer iv = new ImageViewer(imodel.getItemAt(0));
iv.setImageList(imodel);
Container adsContainer = BoxLayout.encloseY(adsLabel, iv);
slideIndex = 0;
Runnable r = new Runnable() {
public void run() {
if (slideIndex < imodel.getSize()) {
nextImage = (Image) imodel.getItemAt(slideIndex);
if (nextImage != null) {
iv.setImage(nextImage);
}
slideIndex++;
} else {
slideIndex = 0;
}
}
};
if (uITimer == null) {
uITimer = new UITimer(r);
}
if (uITimer != null) {
uITimer.schedule(5000, true, f); //5 seconds
}
f.add(BorderLayout.SOUTH, adsContainer);
adsContainer.setLeadComponent(adsLabel);
adsLabel.addActionListener((e) -> {
showForm("BusinessForum", null);
});
}
}
I had used URLImage.createToStorage before but imageViewer didnt work properly so I have used ImageList model. But everytime the form is opened, it jst redownloads the imgs and overrides them in storage, that makes the app slower. How can I make sure if the image is already downloaded, it doesnt download it again and jst shows them in imgViewer? thankyou
The download method will always download regardless...
You need to check if the Storage file exists and if so load that.
See the WebServices/Dogs demo in the new kitchen sink: http://www.codenameone.com/blog/kitchensink-ii.html

LZH in Byte Array Decompress in .NET?

An LZH archive is embedded within a file. The file was read into a byte[], and the LZH part is identified as a smaller byte[].
How can the embedded LZH bytes be decompressed into another byte[] using .NET Framework 4.6 (C#)? I have only see http://www.infoq.com/news/2008/06/7-Zip-from-.NET which doesn't exactly do what I need.
Thanks.
the code snippet that follows is taken from the sample program from this article
http://www.codeproject.com/Articles/27148/C-NET-Interface-for-Zip-Archive-DLLs
There are no significant changes: instead of reading and writing files, it reads and write byte arrays. Changes are marked by comments
Run with sevenzip.exe e "C:\temp\gwo0.11-sample-win32.lzh" 3 for example
https://dl.dropboxusercontent.com/u/71459360/7z.zip
using System;
using System.Collections.Generic;
using System.Text;
using Nomad.Archive.SevenZip;
using System.IO;
using System.Runtime.InteropServices;
using System.Reflection;
namespace SevenZip
{
class Program
{
private static void ShowHelp()
{
Console.WriteLine("SevenZip");
Console.WriteLine("SevenZip l {ArchiveName}");
Console.WriteLine("SevenZip e {ArchiveName} {FileNumber}");
}
static void Main(string[] args)
{
if (args.Length < 2)
{
ShowHelp();
return;
}
try
{
string ArchiveName;
uint FileNumber = 0xFFFFFFFF;
bool Extract;
switch (args[0])
{
case "l":
ArchiveName = args[1];
Extract = false;
break;
case "e":
ArchiveName = args[1];
Extract = true;
if ((args.Length < 3) || !uint.TryParse(args[2], out FileNumber))
{
ShowHelp();
return;
}
break;
default:
ShowHelp();
return;
}
using (SevenZipFormat Format = new SevenZipFormat(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "7z.dll")))
{
IInArchive Archive = Format.CreateInArchive(SevenZipFormat.GetClassIdFromKnownFormat(KnownSevenZipFormat.Lzh));
if (Archive == null)
{
ShowHelp();
return;
}
try
{
//the byte array is provided by you. here it's coming from a file
byte[] data;
using (var stream = File.OpenRead(ArchiveName))
{
data = new byte[stream.Length];
stream.Read(data, 0, data.Length);
}
using (InStreamWrapper ArchiveStream = new InStreamWrapper(new MemoryStream(data))) //modified here
{
ulong CheckPos = 32 * 1024;
if (Archive.Open(ArchiveStream, ref CheckPos, null) != 0)
ShowHelp();
Console.Write("Archive: ");
Console.WriteLine(ArchiveName);
if (Extract)
{
PropVariant Name = new PropVariant();
Archive.GetProperty(FileNumber, ItemPropId.kpidPath, ref Name);
string FileName = (string) Name.GetObject();
Console.Write("Extracting: ");
Console.Write(FileName);
Console.Write(' ');
MemoryStream ms = new MemoryStream();
Archive.Extract(new uint[] { FileNumber }, 1, 0, new ArchiveMemoryCallback(FileNumber, ms)); //modified here
byte[] output = ms.ToArray(); //here you have the output byte array
output.ToString();
}
else
{
Console.WriteLine("List:");
uint Count = Archive.GetNumberOfItems();
for (uint I = 0; I < Count; I++)
{
PropVariant Name = new PropVariant();
Archive.GetProperty(I, ItemPropId.kpidPath, ref Name);
Console.Write(I);
Console.Write(' ');
Console.WriteLine(Name.GetObject());
}
}
}
}
finally
{
Marshal.ReleaseComObject(Archive);
}
}
}
catch (Exception e)
{
Console.Write("Error: ");
Console.WriteLine(e.Message);
}
}
}
class ArchiveCallback : IArchiveExtractCallback
{
private uint FileNumber;
private string FileName;
private OutStreamWrapper FileStream;
public ArchiveCallback(uint fileNumber, string fileName)
{
this.FileNumber = fileNumber;
this.FileName = fileName;
}
#region IArchiveExtractCallback Members
public void SetTotal(ulong total)
{
}
public void SetCompleted(ref ulong completeValue)
{
}
public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode)
{
if ((index == FileNumber) && (askExtractMode == AskMode.kExtract))
{
string FileDir = Path.GetDirectoryName(FileName);
if (!string.IsNullOrEmpty(FileDir))
Directory.CreateDirectory(FileDir);
FileStream = new OutStreamWrapper(File.Create(FileName));
outStream = FileStream;
}
else
outStream = null;
return 0;
}
public void PrepareOperation(AskMode askExtractMode)
{
}
public void SetOperationResult(OperationResult resultEOperationResult)
{
FileStream.Dispose();
Console.WriteLine(resultEOperationResult);
}
#endregion
}
//new
class ArchiveMemoryCallback : IArchiveExtractCallback
{
private uint FileNumber;
private Stream stream;
private OutStreamWrapper FileStream;
public ArchiveMemoryCallback(uint fileNumber, Stream stream)
{
this.FileNumber = fileNumber;
this.stream = stream;
}
#region IArchiveExtractCallback Members
public void SetTotal(ulong total)
{
}
public void SetCompleted(ref ulong completeValue)
{
}
public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode)
{
if ((index == FileNumber) && (askExtractMode == AskMode.kExtract))
{
FileStream = new OutStreamWrapper(stream);
outStream = FileStream;
}
else
outStream = null;
return 0;
}
public void PrepareOperation(AskMode askExtractMode)
{
}
public void SetOperationResult(OperationResult resultEOperationResult)
{
FileStream.Dispose();
Console.WriteLine(resultEOperationResult);
}
#endregion
}
}

Putting array with unknown variables into another array

The purpose of this code is is to define the root of the sum of the squares.
I cant figure out how to put i into j. Please help.
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int input, som, i=0;
int j = 0;
double answer;
Boolean gaDoor= true;
int [] array = new int [24];
while (gaDoor)
{
Console.Write("Specify a positive integer");
input = Convert.ToInt32(Console.ReadLine());
if (input == -1)
{
gaDoor = false;
}
else
{
if (input >= 0)
{
array[i] = input;
i++;
}
else
{
Console.WriteLine("Specify a positive integer ");
}
}
}
while (j<i)
{
sum = array [j] ^ 2;
answer = Math.Sqrt(sum);
Console.Write(answer);
}
Console.ReadKey();
}
}
}
using System;
namespace Test
{
class MainClass
{
public static void Main (string[] args)
{
int[] invoer = new int[24];
double[] resultaat = new double[24];
double totaal = 0;
double wortel = 0;
int commando = 0;
int teller = -1;
try {
// Keep going until a negative integer is entered (or a 0)
while ((commando = Convert.ToInt32 (Console.ReadLine ())) > 0) {
teller++;
invoer [teller] = commando;
}
} catch (FormatException) {
// Not a number at all.
}
teller = -1;
foreach (int i in invoer) {
teller++;
resultaat [teller] = Math.Pow (invoer [teller], 2);
totaal += resultaat [teller];
if (invoer [teller] > 0) {
Console.WriteLine ("Invoer: {0}, Resultaat: {1}", invoer [teller], resultaat [teller]);
}
}
wortel = Math.Sqrt (totaal);
Console.WriteLine ("Totaal: {0}, Wortel: {1}", totaal, wortel);
}
}
}

How can I detect the last character of GSM modem response

I am using a GSM modem "SIM900"
I have tested it with hyper terminal and main command is ok.
Then I burnt the code to send the AT command to dial a number on the Microcontroller to the GSM modem using UART and it works fine.
But I'm having a problem with the response.
The GSM replies with stream of characters but it doesn't end with Null '\0' !
How can I get the whole response in array to parse it later? And, how can I detect the end of response?
AT\r\n response is ==> OK
AT+CMGR=1 response is ==> +CMGR: "REC UNREAD" ,"+2347060580383","10/10/27,18:54:32+04"
Thanks in advance.
You can use \r\nOK for the ending, because phones use \n only for NewLine. But there's a more reliable way (I did that once) to make sure you don't get the wrong ending, for example when the incoming text message had the exact \r\nOK in it. In order to do that, I suggest that you change the Character Set to UCS2, so you will get the message text and sender number in UnicodeArray (It's like it is been escaped.)
Here's the class I used for my purpose (The extra check modules (AT\r command) are used to prevent getting stuck in error, in case there's an unexpected error or something like that! And the module I had sometimes went unresponsive, so with this I could make it again responsive! Doesn't seem logical, but saved me! Works perfectly for me now!):
public class SMSController
{
public event EventHandler StatusChanged;
protected virtual void OnStatusChanged()
{
if (StatusChanged != null)
{
StatusChanged(this, EventArgs.Empty);
}
}
SerialPort serial;
public SMSController(SerialPort serialPort)
{
this.serial = serialPort;
}
string readLine(int timeout = -1)
{
int oldTo = serial.ReadTimeout;
serial.ReadTimeout = timeout;
string str = serial.ReadTo("\n").Replace("\n", "").Replace("\r", "");
serial.ReadTimeout = oldTo;
return str;
}
void writeLine(string str)
{
serial.Write(str + "\r\n");
}
bool waitForString(string str, int timeout = -1)
{
if (readLine(timeout).Contains(str))
{
return true;
}
return false;
}
bool waitForOK(int timeout = -1, bool repeat = true)
{
if (repeat)
{
readUntilFind("OK", timeout);
return true;
}
else
return waitForString("OK", timeout);
}
void readUntilFind(string str, int timeout = -1)
{
while (!waitForString(str, timeout)) ;
}
void writeCommand(string command)
{
serial.DiscardInBuffer();
writeLine(command);
}
bool applyCommand(string command, int timeout = -1)
{
writeCommand(command);
return waitForOK(timeout);
}
private string lastStatus = "Ready";
public string LastStatus
{
get { return lastStatus; }
private set
{
lastStatus = value;
OnStatusChanged();
}
}
public void InitModule()
{
try
{
LastStatus = "Checking SIM900...";
applyCommand("ATE0", 2000); //Disable echo
applyCommand("AT", 5000); //Check module
LastStatus = "Initializing SIM900...";
applyCommand("AT+CMGF=1", 1000); //Set SMS format to text mode
LastStatus = "Operation successful!";
}
catch (TimeoutException)
{
LastStatus = "Operation timed-out";
}
catch (Exception ex)
{
LastStatus = ex.Message;
}
}
public static string ConvertToUnicodeArray(string str)
{
byte[] byt = Encoding.Unicode.GetBytes(str);
string res = "";
for (int i = 0; i < byt.Length; i+=2)
{
res += byt[i + 1].ToString("X2");
res += byt[i].ToString("X2");
}
return res;
}
public void SendMessage(string destinationNumber, string text, bool isUnicode = false)
{
try
{
LastStatus = "Initiating to send...";
applyCommand("AT+CSMP=17,167,2,25", 1000);
if (isUnicode)
{
if (!applyCommand("AT+CSCS=\"UCS2\"", 5000))
throw new Exception("Operation failed!");
writeCommand("AT+CMGS=\"" + ConvertToUnicodeArray(destinationNumber) + "\"");
}
else
{
if (!applyCommand("AT+CSCS=\"GSM\"", 5000))
throw new Exception("Operation failed!");
writeCommand("AT+CMGS=\"" + destinationNumber + "\"");
}
waitForString("> ", 5000);
LastStatus = "Sending...";
serial.DiscardInBuffer();
serial.Write(isUnicode ? ConvertToUnicodeArray(text) : text);
serial.Write(new byte[] { 0x1A }, 0, 1);
if (waitForOK(30000))
{
LastStatus = "Message sent!";
}
else
LastStatus = "Sending failed!";
}
catch (TimeoutException)
{
LastStatus = "Operation timed-out";
}
catch (Exception ex)
{
LastStatus = ex.Message;
}
}
private string readTo(string str, int timeout)
{
int to = serial.ReadTimeout;
serial.ReadTimeout = timeout;
string strread = serial.ReadTo(str);
serial.ReadTimeout = to;
return strread;
}
public static byte[] StringToByteArray(string hex)
{
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
public static string ConvertUnicodeToText(string bytes)
{
byte[] bt = StringToByteArray(bytes);
for (int i = 0; i < bt.Length; i+=2)
{
byte swap = bt[i];
bt[i] = bt[i + 1];
bt[i + 1] = swap;
}
return Encoding.Unicode.GetString(bt);
}
public SMS[] GetUnreadMessages()
{
List<SMS> lst = new List<SMS>();
try
{
LastStatus = "Initializing...";
applyCommand("AT+CSMP=17,167,2,25", 1000);
applyCommand("AT+CSCS=\"UCS2\"", 2000);
LastStatus = "Fetching text messages...";
writeCommand("AT+CMGL=\"REC UNREAD\"");
string texts = readTo("OK\r\n", 10000);
string[] packets = texts.Split(new string[] { "\r\n\r\n" }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < packets.Length; i++)
{
if (!packets[i].Contains("+CMGL"))
continue;
string num = packets[i].Split(new string[] { "," },
StringSplitOptions.RemoveEmptyEntries)[2].Replace("\"", "");
string txt = packets[i].Split(new string[] { "\r\n" },
StringSplitOptions.RemoveEmptyEntries)[1].Replace("\"", "");
lst.Add(new SMS(ConvertUnicodeToText(num), ConvertUnicodeToText(txt)));
}
applyCommand("AT+CMGDA=\"DEL READ\"", 10000);
LastStatus = "Operation successful!";
}
catch (TimeoutException)
{
LastStatus = "Operation timed-out";
}
catch (Exception ex)
{
LastStatus = ex.Message;
}
return lst.ToArray();
}
}
Test for a new-line, which typical is \n or \r\n.
A NUL (0 or '\0') is only used in C to terminate a character array, a "string".

Ref.get() does not work if comes from a just loaded List<Ref<?>>

I'm going crazy with Objectify because i've a problem with a List<Ref<?>> like this:
#Index
#Load
private LinkedList<Ref<Post>> diary = new LinkedList<Ref<Post>>();
when i save this Profile entity the diary Ref list is ok, and this:
getDiary().get(0).get() give me the correct Post entity.
When i load both Profile and then the first Post like this:
ofy().load().key(myProfileKey).get().getDiary().get(0).get() which should load the first Post in list, i got null, even if the Profile and the diary are correctly loaded (diary contains the correct Ref<Post>).
Any ideas?
Thanks in advance!
Update:
In my previous question i forgot to tell that Post has a #Parent field: the Profile.
Removing #Parent all works... even if i don't understand why.
I reduced all to a TestCase:
public class StandaloneTestCase {
protected static LocalServiceTestHelper helper = null;
protected static Objectify ds = null;
#BeforeClass
public static void setUp() {
LocalDatastoreServiceTestConfig config = new LocalDatastoreServiceTestConfig();
helper = new LocalServiceTestHelper(config);
helper.setUp();
ds = ObjectifyService.ofy();
ObjectifyService.register(Post.class);
ObjectifyService.register(Profile.class);
}
#Test
public void test() {
Profile p = new Profile();
p.setEmail("user1#email.com");
p.setPassword("user1pwd");
p.setRegistrationDate(new Date(0L));
p.setSex("Male");
p.setName("Name1");
p.setSurname("Surname1");
p.setFullName("Name1 Nick1 Surname1");
Key<Profile> pKey = ds.save().entity(p).now();
Profile pro = ds.load().type(Profile.class).filter("name", "Name1").first().get();
Assert.assertEquals(0, ds.load().key(pro.getRef().getKey()).get().getFriends().size());
Post newPost = new Post();
newPost.setDate(new Date());
newPost.setTitle("New Post p1");
newPost.setDescription("New Descr p1");
newPost.setAuthor(pro.getRef());
ds.save().entity(newPost).now();
Ref<Post> postRef = newPost.getRef();
pro.getDiary().addFirst(postRef);
pro.getMessages().addFirst(postRef);
ds.save().entity(pro).now();
newPost.getReceivers().addAll(pro.getFriends());
Collection<Profile> friends = ds.load().refs(pro.getFriends()).values();
for (Profile friend : friends) {
friend.getMessages().addFirst(newPost.getRef());
}
ds.save().entities(friends).now();
ds.save().entity(newPost).now();
Assert.assertEquals(1, ds.load().key(pro.getKey()).get().getDiary().size());
Assert.assertEquals(1, ds.load().key(pro.getKey()).get().getMessages().size());
Assert.assertEquals(newPost.getRef(), ds.load().key(pro.getKey()).get().getDiary().get(0));
// BIG FAT WARNING
Assert.assertEquals(newPost, ds.load().key(pro.getKey()).get().getDiary().get(0).get());
}
#AfterClass
public static void tearDown() {
ds.clear();
helper.tearDown();
}
}
//
#Entity
class Identifable<T> {
#Id
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
return equals((Identifable<?>) obj);
}
public boolean equals(Identifable<?> other) {
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
}
#Entity #Cache
class Post extends Identifable<Post> {
#Index(IfNotNull.class)
#Load
#Parent
private Ref<Profile> author = null;
#Index(IfNotNull.class)
private Date date = null;
#Index(IfNotNull.class)
private String title = null;
private String description = null;
#Index(IfNotEmpty.class)
#Load
private Set<Ref<Profile>> receivers = new HashSet<Ref<Profile>>();
public Set<Ref<Profile>> getReceivers() {
return receivers;
}
public Ref<Profile> getAuthor() {
return author;
}
public void setAuthor(Ref<Profile> author) {
this.author = author;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Override
public String toString() {
return "Post [author=" + author + ", date=" + date + ", title=" + title
+ ", description=" + description + "]";
}
#Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((author == null) ? 0 : author.hashCode());
result = prime * result + ((date == null) ? 0 : date.hashCode());
result = prime * result
+ ((description == null) ? 0 : description.hashCode());
result = prime * result + ((title == null) ? 0 : title.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
Post other = (Post) obj;
if (author == null) {
if (other.author != null)
return false;
} else if (!author.equals(other.author))
return false;
if (date == null) {
if (other.date != null)
return false;
} else if (!date.equals(other.date))
return false;
if (description == null) {
if (other.description != null)
return false;
} else if (!description.equals(other.description))
return false;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
return true;
}
public Key<Post> getKey() {
return Key.create(Post.class, getId());
}
public Ref<Post> getRef() {
return Ref.create(getKey(), this);
}
}
//
#Entity #Cache
class Profile extends Identifable<Profile> {
#Index
private String email = null;
#Index
private String password = null;
private Date registrationDate = null;
#Index(IfNotNull.class)
private String name = null;
#Index(IfNotNull.class)
private String surname = null;
#Index(IfNotNull.class)
private String fullName = null;
#Index
private String sex = null;
#Index
private Date dateOfBirth = null;
#Index(IfNotEmpty.class)
#Load
private LinkedList<Ref<Post>> diary = new LinkedList<Ref<Post>>();
#Index(IfNotEmpty.class)
#Load
private Set<Ref<Profile>> friends = new HashSet<Ref<Profile>>();
#Index(IfNotEmpty.class)
#Load
private LinkedList<Ref<Post>> messages = new LinkedList<Ref<Post>>();
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getRegistrationDate() {
return registrationDate;
}
public void setRegistrationDate(Date registrationDate) {
this.registrationDate = registrationDate;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public Set<Ref<Profile>> getFriends() {
return friends;
}
public LinkedList<Ref<Post>> getDiary() {
return diary;
}
public LinkedList<Ref<Post>> getMessages() {
return messages;
}
#Override
public String toString() {
return "Profile [email=" + email + ", password=" + password
+ ", registrationDate=" + registrationDate + ", name=" + name
+ ", surname=" + surname + ", fullName=" + fullName + ", sex="
+ sex + ", dateOfBirth=" + dateOfBirth + ", diary=" + diary
+ ", friends=" + friends + ", messages=" + messages + "]";
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((dateOfBirth == null) ? 0 : dateOfBirth.hashCode());
result = prime * result + ((diary == null) ? 0 : diary.hashCode());
result = prime * result + ((email == null) ? 0 : email.hashCode());
result = prime * result + ((friends == null) ? 0 : friends.hashCode());
result = prime * result
+ ((fullName == null) ? 0 : fullName.hashCode());
result = prime * result
+ ((messages == null) ? 0 : messages.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result
+ ((password == null) ? 0 : password.hashCode());
result = prime
* result
+ ((registrationDate == null) ? 0 : registrationDate.hashCode());
result = prime * result + ((sex == null) ? 0 : sex.hashCode());
result = prime * result + ((surname == null) ? 0 : surname.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Profile other = (Profile) obj;
if (dateOfBirth == null) {
if (other.dateOfBirth != null)
return false;
} else if (!dateOfBirth.equals(other.dateOfBirth))
return false;
if (diary == null) {
if (other.diary != null)
return false;
} else if (!diary.equals(other.diary))
return false;
if (email == null) {
if (other.email != null)
return false;
} else if (!email.equals(other.email))
return false;
if (friends == null) {
if (other.friends != null)
return false;
} else if (!friends.equals(other.friends))
return false;
if (fullName == null) {
if (other.fullName != null)
return false;
} else if (!fullName.equals(other.fullName))
return false;
if (messages == null) {
if (other.messages != null)
return false;
} else if (!messages.equals(other.messages))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (password == null) {
if (other.password != null)
return false;
} else if (!password.equals(other.password))
return false;
if (registrationDate == null) {
if (other.registrationDate != null)
return false;
} else if (!registrationDate.equals(other.registrationDate))
return false;
if (sex == null) {
if (other.sex != null)
return false;
} else if (!sex.equals(other.sex))
return false;
if (surname == null) {
if (other.surname != null)
return false;
} else if (!surname.equals(other.surname))
return false;
return true;
}
public Key<Profile> getKey() {
return Key.create(Profile.class, getId());
}
public Ref<Profile> getRef() {
return Ref.create(getKey(), this);
}
}
I use Objectify 4.0a4 and App Engine SDK 1.7.2
If you try to remove #Parent from author Post field the test is ok.
This may be NOT an Objectify bug (quite sure) and may be a my conceptual error.

Resources