Hunt Hunt - 5 months ago 11
Android Question

convert protobuff class as model and store its value using realm

I am generating protobuf class using Squareup Wire protobuf libary

here is my proto file

syntax = "proto2";

package squareup.dinosaurs;

option java_package = "com.squareup.dinosaurs";


message Dinosaur {
// Common name of this dinosaur, like "Stegosaurus".
optional string name = 1;

// URLs with images of this dinosaur.
repeated string picture_urls = 2;

}


and here is my auto generated code

// Code generated by Wire protocol buffer compiler, do not edit.
// Source file: dinosaur/dinosaur.proto at 8:1
package com.squareup.dinosaurs;

import com.squareup.wire.FieldEncoding;
import com.squareup.wire.Message;
import com.squareup.wire.ProtoAdapter;
import com.squareup.wire.ProtoReader;
import com.squareup.wire.ProtoWriter;
import java.io.IOException;
import java.lang.Object;
import java.lang.Override;
import java.lang.String;
import java.lang.StringBuilder;
import java.util.List;
import okio.ByteString;

public final class Dinosaur extends Message<Dinosaur, Dinosaur.Builder> {
public static final ProtoAdapter<Dinosaur> ADAPTER = new ProtoAdapter<Dinosaur>(FieldEncoding.LENGTH_DELIMITED, Dinosaur.class) {
@Override
public int encodedSize(Dinosaur value) {
return (value.name != null ? ProtoAdapter.STRING.encodedSizeWithTag(1, value.name) : 0)
+ ProtoAdapter.STRING.asRepeated().encodedSizeWithTag(2, value.picture_urls)
+ value.unknownFields().size();
}

@Override
public void encode(ProtoWriter writer, Dinosaur value) throws IOException {
if (value.name != null) ProtoAdapter.STRING.encodeWithTag(writer, 1, value.name);
if (value.picture_urls != null) ProtoAdapter.STRING.asRepeated().encodeWithTag(writer, 2, value.picture_urls);
writer.writeBytes(value.unknownFields());
}

@Override
public Dinosaur decode(ProtoReader reader) throws IOException {
Builder builder = new Builder();
long token = reader.beginMessage();
for (int tag; (tag = reader.nextTag()) != -1;) {
switch (tag) {
case 1: builder.name(ProtoAdapter.STRING.decode(reader)); break;
case 2: builder.picture_urls.add(ProtoAdapter.STRING.decode(reader)); break;
default: {
FieldEncoding fieldEncoding = reader.peekFieldEncoding();
Object value = fieldEncoding.rawProtoAdapter().decode(reader);
builder.addUnknownField(tag, fieldEncoding, value);
}
}
}
reader.endMessage(token);
return builder.build();
}

@Override
public Dinosaur redact(Dinosaur value) {
Builder builder = value.newBuilder();
builder.clearUnknownFields();
return builder.build();
}
};

private static final long serialVersionUID = 0L;

public static final String DEFAULT_NAME = "";

/**
* Common name of this dinosaur, like "Stegosaurus".
*/
public final String name;

/**
* URLs with images of this dinosaur.
*/
public final List<String> picture_urls;

public Dinosaur(String name, List<String> picture_urls) {
this(name, picture_urls, ByteString.EMPTY);
}

public Dinosaur(String name, List<String> picture_urls, ByteString unknownFields) {
super(unknownFields);
this.name = name;
this.picture_urls = immutableCopyOf("picture_urls", picture_urls);
}

@Override
public Builder newBuilder() {
Builder builder = new Builder();
builder.name = name;
builder.picture_urls = copyOf("picture_urls", picture_urls);
builder.addUnknownFields(unknownFields());
return builder;
}

@Override
public boolean equals(Object other) {
if (other == this) return true;
if (!(other instanceof Dinosaur)) return false;
Dinosaur o = (Dinosaur) other;
return equals(unknownFields(), o.unknownFields())
&& equals(name, o.name)
&& equals(picture_urls, o.picture_urls);
}

@Override
public int hashCode() {
int result = super.hashCode;
if (result == 0) {
result = unknownFields().hashCode();
result = result * 37 + (name != null ? name.hashCode() : 0);
result = result * 37 + (picture_urls != null ? picture_urls.hashCode() : 1);
super.hashCode = result;
}
return result;
}

@Override
public String toString() {
StringBuilder builder = new StringBuilder();
if (name != null) builder.append(", name=").append(name);
if (picture_urls != null) builder.append(", picture_urls=").append(picture_urls);
return builder.replace(0, 2, "Dinosaur{").append('}').toString();
}

public static final class Builder extends com.squareup.wire.Message.Builder<Dinosaur, Builder> {
public String name;

public List<String> picture_urls;

public Builder() {
picture_urls = newMutableList();
}

/**
* Common name of this dinosaur, like "Stegosaurus".
*/
public Builder name(String name) {
this.name = name;
return this;
}

/**
* URLs with images of this dinosaur.
*/
public Builder picture_urls(List<String> picture_urls) {
checkElementsNotNull(picture_urls);
this.picture_urls = picture_urls;
return this;
}

@Override
public Dinosaur build() {
return new Dinosaur(name, picture_urls, buildUnknownFields());
}
}
}


now the issue is i want to directly store the value of
Dinosaur
into the database using Realm in android. i want
Dinosaur
class to act as a model.
but the problem is
Dinosaur
class is declared as final so i cant even derive it.

So is there any design pattern or way that exists to reuse or convert
Dinosaur
class into model?

Answer

You cannot use the Wire Dinosaur with Realm as Wire also require you to extend the Message class, while Realm require you to extend RealmObject.

If you want to combine the two you can create a RealmDinosaur class that accept the wire Dinosaur. Something like this:

public class RealmDinosaur extends RealmObject {

  private String name;
  private RealmList<RealmString> pictureUrls;

  public RealmDinosaur(Dinosaur dino) {
    // Fill Realm fields. Note that Realm doesn't support Lists 
    // with primitive strings yet.
    // See https://realm.io/docs/java/latest/#primitive-lists
  }

  // getter and setters

}

realm.beginTransaction();
realm.copyToRealm(new RealmDinosaur(wireDinosaur));
realm.commitTransaction();
Comments