Creating a Netflix Clone
II
codenameone.com github.com/codenameone/CodenameOne
Server and
Lombok
Introduction
codenameone.com github.com/codenameone/CodenameOne
Server and Lombok Introduction
We use H2 for simplicity as usual we use JPA for persistence
Lombok is used for entities and DTOs
There’s only one webservice
We don’t need more without authentication and other complexities
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/
maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.codename1.demos</groupId>
<artifactId>netflixclone</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>NetflixCloneServer</name>
<description>Netflix Clone Sample</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
Source Listing - pom.xml
codenameone.com github.com/codenameone/CodenameOne
<artifactId>netflixclone</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>NetflixCloneServer</name>
<description>Netflix Clone Sample</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
Source Listing - pom.xml
codenameone.com github.com/codenameone/CodenameOne
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
Source Listing - pom.xml
codenameone.com github.com/codenameone/CodenameOne
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
Source Listing - pom.xml
codenameone.com github.com/codenameone/CodenameOne
codenameone.com github.com/codenameone/CodenameOne
Lombok
Java language enhancement tool
Requires IDE plugin
Removes boilerplate getters/setters
Works with Codename One as well but not as valuable thanks to properties
See https://www.codenameone.com/blog/tip-using-lombok-other-tools.html
public class ConstructorExample<T> {
private int x, y;
@NonNull private T description;
private ConstructorExample(T description) {
if (description == null) throw new NullPointerException("description");
this.description = description;
}
public static <T> ConstructorExample<T> of(T description) {
return new ConstructorExample<T>(description);
}
@java.beans.ConstructorProperties({"x", "y", "description"})
protected ConstructorExample(int x, int y, T description) {
if (description == null) throw new NullPointerException("description");
this.x = x;
this.y = y;
this.description = description;
}
public static class NoArgsExample {
@NonNull private String field;
public NoArgsExample() {
Source Listing - Lombok: Constructors
codenameone.com github.com/codenameone/CodenameOne
this.y = y;
this.description = description;
}
public static class NoArgsExample {
@NonNull private String field;
public NoArgsExample() {
}
}
}
@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class ConstructorExample<T> {
private int x, y;
@NonNull
private T description;
@NoArgsConstructor
public static class NoArgsExample {
@NonNull
private String field;
}
}
Source Listing - Lombok: Constructors
codenameone.com github.com/codenameone/CodenameOne
public class ConstructorExample<T> {
private int x, y;
@NonNull private T description;
private ConstructorExample(T description) {
if (description == null) throw new NullPointerException("description");
this.description = description;
}
public static <T> ConstructorExample<T> of(T description) {
return new ConstructorExample<T>(description);
}
@java.beans.ConstructorProperties({"x", "y", "description"})
protected ConstructorExample(int x, int y, T description) {
if (description == null) throw new NullPointerException("description");
this.x = x;
this.y = y;
this.description = description;
}
public static class NoArgsExample {
@NonNull private String field;
public NoArgsExample() {
Source Listing - Lombok: Constructors
codenameone.com github.com/codenameone/CodenameOne
protected ConstructorExample(int x, int y, T description) {
if (description == null) throw new NullPointerException("description");
this.x = x;
this.y = y;
this.description = description;
}
public static class NoArgsExample {
@NonNull private String field;
public NoArgsExample() {
}
}
}
@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class ConstructorExample<T> {
private int x, y;
@NonNull
private T description;
@NoArgsConstructor
public static class NoArgsExample {
@NonNull
private String field;
}
}
Source Listing - Lombok: Constructors
codenameone.com github.com/codenameone/CodenameOne
@java.beans.ConstructorProperties({"x", "y", "description"})
protected ConstructorExample(int x, int y, T description) {
if (description == null) throw new NullPointerException("description");
this.x = x;
this.y = y;
this.description = description;
}
public static class NoArgsExample {
@NonNull private String field;
public NoArgsExample() {
}
}
}
@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class ConstructorExample<T> {
private int x, y;
@NonNull
private T description;
@NoArgsConstructor
public static class NoArgsExample {
@NonNull
private String field;
}
}
Source Listing - Lombok: Constructors
codenameone.com github.com/codenameone/CodenameOne
@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class ConstructorExample<T> {
private int x, y;
@NonNull
private T description;
@NoArgsConstructor
public static class NoArgsExample {
@NonNull
private String field;
}
}
Source Listing - Lombok: Constructors
codenameone.com github.com/codenameone/CodenameOne
public class NonNullExample extends Something {
private String name;
public NonNullExample(@NonNull Person person) {
super("Hello");
if (person == null) {
throw new NullPointerException("person is marked @NonNull but is null");
}
this.name = person.getName();
}
}
public class NonNullExample extends Something {
private String name;
public NonNullExample(@NonNull Person person) {
super("Hello");
this.name = person.getName();
}
}
Source Listing - Lombok: NonNull
codenameone.com github.com/codenameone/CodenameOne
public class NonNullExample extends Something {
private String name;
public NonNullExample(@NonNull Person person) {
super("Hello");
if (person == null) {
throw new NullPointerException("person is marked @NonNull but is null");
}
this.name = person.getName();
}
}
public class NonNullExample extends Something {
private String name;
public NonNullExample(@NonNull Person person) {
super("Hello");
this.name = person.getName();
}
}
Source Listing - Lombok: NonNull
codenameone.com github.com/codenameone/CodenameOne
public class CleanupExample {
public static void main(String[] args) throws IOException {
InputStream in = new FileInputStream(args[0]);
try {
OutputStream out = new FileOutputStream(args[1]);
try {
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
} finally {
if (out != null) {
out.close();
}
}
} finally {
if (in != null) {
in.close();
}
}
}
}
public class CleanupExample {
Source Listing - Lombok: Cleanup
codenameone.com github.com/codenameone/CodenameOne
if (r == -1) break;
out.write(b, 0, r);
}
} finally {
if (out != null) {
out.close();
}
}
} finally {
if (in != null) {
in.close();
}
}
}
}
public class CleanupExample {
public static void main(String[] args) throws IOException {
@Cleanup InputStream in = new FileInputStream(args[0]);
@Cleanup OutputStream out = new FileOutputStream(args[1]);
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
}
}
Source Listing - Lombok: Cleanup
codenameone.com github.com/codenameone/CodenameOne
public class GetterSetterExample {
private int age = 10;
private String name;
@Override public String toString() {
return String.format("%s (age: %d)", name, age);
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
protected void setName(String name) {
this.name = name;
}
}
public class GetterSetterExample {
@Getter @Setter private int age = 10;
Source Listing - Lombok: Getters & Setters
codenameone.com github.com/codenameone/CodenameOne
@Override public String toString() {
return String.format("%s (age: %d)", name, age);
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
protected void setName(String name) {
this.name = name;
}
}
public class GetterSetterExample {
@Getter @Setter private int age = 10;
@Setter(AccessLevel.PROTECTED) private String name;
@Override public String toString() {
return String.format("%s (age: %d)", name, age);
}
}
Source Listing - Lombok: Getters & Setters
codenameone.com github.com/codenameone/CodenameOne
public class DataExample {
private final String name;
private int age;
private double score;
private String[] tags;
public DataExample(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
public void setScore(double score) {
this.score = score;
}
Source Listing - Lombok: Data (and more…)
codenameone.com github.com/codenameone/CodenameOne
}
public void setTags(String[] tags) {
this.tags = tags;
}
@Override public String toString() {
return "DataExample(" + this.getName() + ", " + this.getAge() + ", " + this.getScore() +
", " + Arrays.deepToString(this.getTags()) + ")";
}
protected boolean canEqual(Object other) {
return other instanceof DataExample;
}
@Override public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof DataExample)) return false;
DataExample other = (DataExample) o;
if (!other.canEqual((Object)this)) return false;
if (this.getName() == null ? other.getName() != null : !
this.getName().equals(other.getName())) return false;
if (this.getAge() != other.getAge()) return false;
if (Double.compare(this.getScore(), other.getScore()) != 0) return false;
if (!Arrays.deepEquals(this.getTags(), other.getTags())) return false;
return true;
}
@Override public int hashCode() {
final int PRIME = 59;
int result = 1;
Source Listing - Lombok: Data (and more…)
codenameone.com github.com/codenameone/CodenameOne
if (this.getAge() != other.getAge()) return false;
if (Double.compare(this.getScore(), other.getScore()) != 0) return false;
if (!Arrays.deepEquals(this.getTags(), other.getTags())) return false;
return true;
}
@Override public int hashCode() {
final int PRIME = 59;
int result = 1;
final long temp1 = Double.doubleToLongBits(this.getScore());
result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode());
result = (result*PRIME) + this.getAge();
result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));
result = (result*PRIME) + Arrays.deepHashCode(this.getTags());
return result;
}
public static class Exercise<T> {
private final String name;
private final T value;
private Exercise(String name, T value) {
this.name = name;
this.value = value;
}
public static <T> Exercise<T> of(String name, T value) {
return new Exercise<T>(name, value);
}
public String getName() {
Source Listing - Lombok: Data (and more…)
codenameone.com github.com/codenameone/CodenameOne
result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));
result = (result*PRIME) + Arrays.deepHashCode(this.getTags());
return result;
}
public static class Exercise<T> {
private final String name;
private final T value;
private Exercise(String name, T value) {
this.name = name;
this.value = value;
}
public static <T> Exercise<T> of(String name, T value) {
return new Exercise<T>(name, value);
}
public String getName() {
return this.name;
}
public T getValue() {
return this.value;
}
@Override public String toString() {
return "Exercise(name=" + this.getName() + ", value=" + this.getValue() + ")";
}
protected boolean canEqual(Object other) {
Source Listing - Lombok: Data (and more…)
codenameone.com github.com/codenameone/CodenameOne
@Override public int hashCode() {
final int PRIME = 59;
int result = 1;
result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode());
result = (result*PRIME) + (this.getValue() == null ? 43 :
this.getValue().hashCode());
return result;
}
}
}
@Data public class DataExample {
private final String name;
@Setter(AccessLevel.PACKAGE) private int age;
private double score;
private String[] tags;
@ToString(includeFieldNames=true)
@Data(staticConstructor="of")
public static class Exercise<T> {
private final String name;
private final T value;
}
}
Source Listing - Lombok: Data (and more…)
codenameone.com github.com/codenameone/CodenameOne
public class ValVarExample {
public String example() {
final ArrayList<String> example = new ArrayList<String>();
example.add("Hello, World!");
int varExample = 3;
ArrayList<String> varExample = new ArrayList<String>();
varExample = new ArrayList<String>();
final String foo = example.get(0);
return foo.toLowerCase();
}
}
public class ValVarExample {
public String example() {
val example = new ArrayList<String>();
example.add("Hello, World!");
var varExample = new ArrayList<String>();
varExample = new ArrayList<String>();
val foo = example.get(0);
return foo.toLowerCase();
}
}
Source Listing - Lombok: val/var
codenameone.com github.com/codenameone/CodenameOne
public class ValVarExample {
public String example() {
final ArrayList<String> example = new ArrayList<String>();
example.add("Hello, World!");
int varExample = 3;
ArrayList<String> varExample = new ArrayList<String>();
varExample = new ArrayList<String>();
final String foo = example.get(0);
return foo.toLowerCase();
}
}
public class ValVarExample {
public String example() {
val example = new ArrayList<String>();
example.add("Hello, World!");
var varExample = new ArrayList<String>();
varExample = new ArrayList<String>();
val foo = example.get(0);
return foo.toLowerCase();
}
}
Source Listing - Lombok: val/var
codenameone.com github.com/codenameone/CodenameOne
codenameone.com github.com/codenameone/CodenameOne
Lombok: There are a lot of features we didn’t cover…
@Value
@Builder
@SneakyThrows
@Synchronized
@With
codenameone.com github.com/codenameone/CodenameOne
Lombok: There are a lot of features we didn’t cover…
@Log
@Getter(lazy=true)
You can learn more at https://projectlombok.org/features/all
codenameone.com github.com/codenameone/CodenameOne
Thank You
Thank You
create-netflix-clone-02-server.pdf

create-netflix-clone-02-server.pdf