From c678dccc87ca8bda1dbe944dedd0824d87016440 Mon Sep 17 00:00:00 2001
From: razzanYoni <13521087@mahasiswa.itb.ac.id>
Date: Mon, 13 Nov 2023 02:27:19 +0700
Subject: [PATCH] refactor : add use case for searching

---
 pom.xml                                       |   2 +-
 src/main/java/App.java                        |   2 +-
 .../java/org/tonality/model/Subscription.java |   2 +-
 .../tonality/repository/BaseRepository.java   |  39 ++++-
 .../org/tonality/repository/Subscription.java | 137 +++++++++++++++++-
 .../{ws => service}/ISubscription.java        |  40 ++++-
 .../org/tonality/service/Subscription.java    | 103 +++++++++++++
 .../java/org/tonality/ws/Subscription.java    | 123 ----------------
 8 files changed, 309 insertions(+), 139 deletions(-)
 rename src/main/java/org/tonality/{ws => service}/ISubscription.java (61%)
 create mode 100644 src/main/java/org/tonality/service/Subscription.java
 delete mode 100644 src/main/java/org/tonality/ws/Subscription.java

diff --git a/pom.xml b/pom.xml
index 91cb86d..639daed 100644
--- a/pom.xml
+++ b/pom.xml
@@ -41,7 +41,7 @@
         <dependency>
             <groupId>org.hibernate</groupId>
             <artifactId>hibernate-java8</artifactId>
-            <version>6.0.0.Alpha7</version>
+            <version>5.6.15.Final</version>
         </dependency>
     </dependencies>
 </project>
\ No newline at end of file
diff --git a/src/main/java/App.java b/src/main/java/App.java
index c736f34..bb905f9 100644
--- a/src/main/java/App.java
+++ b/src/main/java/App.java
@@ -1,4 +1,4 @@
-import org.tonality.ws.Subscription;
+import org.tonality.service.Subscription;
 
 import javax.xml.ws.Endpoint;
 
diff --git a/src/main/java/org/tonality/model/Subscription.java b/src/main/java/org/tonality/model/Subscription.java
index d752211..f5ef8b5 100644
--- a/src/main/java/org/tonality/model/Subscription.java
+++ b/src/main/java/org/tonality/model/Subscription.java
@@ -68,6 +68,6 @@ public class Subscription implements Serializable {
     }
 
     public String toString() {
-        return "Subscription: \n" + "userId :" + userId + " \nalbumId : " + albumId + " \nstatus: " + status;
+        return "Subscription: \n" + "userId :" + userId + "\n" + "username :" + username + "\n" + "albumId :" + albumId + "\n" + "albumName :" + albumName + "\n" + "artist :" + artist + "\n" + "status :" + status + "\n" + "createdAt :" + createdAt + "\n" + "updatedAt :" + updatedAt + "\n";
     }
 }
diff --git a/src/main/java/org/tonality/repository/BaseRepository.java b/src/main/java/org/tonality/repository/BaseRepository.java
index 55054d8..c68706b 100644
--- a/src/main/java/org/tonality/repository/BaseRepository.java
+++ b/src/main/java/org/tonality/repository/BaseRepository.java
@@ -1,6 +1,7 @@
 package org.tonality.repository;
 
 import org.hibernate.SessionFactory;
+import org.tonality.model.Subscription;
 import org.tonality.util.HibernateUtil;
 
 import javax.persistence.EntityManager;
@@ -60,7 +61,7 @@ public abstract class BaseRepository<T> {
     }
 
     // get by conditions
-    public List<T> search(Map<String, Object>andConditions, Map<String, Object> orConditions) {
+    public List<T> search(Map<String, Object> andConditions, Map<String, Object> orConditions, String searchInput, List<String> searchField, String orderBy, int page, int size) {
         try {
             SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
             EntityManager entityManager = sessionFactory.createEntityManager();
@@ -68,28 +69,50 @@ public abstract class BaseRepository<T> {
             CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
             CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(this.getEntityClass());
             Root<T> root = criteriaQuery.from(this.getEntityClass());
+            List<Predicate> predicates = new java.util.ArrayList<>();
 
             // and conditions
             Predicate andPredicate = criteriaBuilder.conjunction();
             for (Map.Entry<String, Object> entry : andConditions.entrySet()) {
                 andPredicate = criteriaBuilder.and(andPredicate, criteriaBuilder.equal(root.get(entry.getKey()), entry.getValue()));
             }
+            if (andPredicate.getExpressions().size() > 0) {
+                predicates.add(andPredicate);
+            }
 
             // or conditions
             Predicate orPredicate = criteriaBuilder.disjunction();
             for (Map.Entry<String, Object> entry : orConditions.entrySet()) {
                 orPredicate = criteriaBuilder.or(orPredicate, criteriaBuilder.equal(root.get(entry.getKey()), entry.getValue()));
             }
+            if (orPredicate.getExpressions().size() > 0) {
+                predicates.add(orPredicate);
+            }
+
+            // order by
+            criteriaQuery.orderBy(criteriaBuilder.asc(root.get(orderBy)));
+
+            // pagination
+            int offset = (page - 1) * size;
+
+            // like query
+            Predicate likePredicate = criteriaBuilder.disjunction();
+            if (!searchInput.isEmpty()) {
+                for (String field : searchField) {
+                    likePredicate = criteriaBuilder.or(likePredicate, criteriaBuilder.like(root.get(field), "%" + searchInput + "%"));
+                }
+            }
+            if (likePredicate.getExpressions().size() > 0) {
+                predicates.add(likePredicate);
+            }
 
-            if (andPredicate.getExpressions().size() > 0 && orPredicate.getExpressions().size() > 0) {
-                criteriaQuery.where(criteriaBuilder.and(andPredicate, orPredicate));
-            } else if (andPredicate.getExpressions().size() > 0) {
-                criteriaQuery.where(andPredicate);
-            } else if (orPredicate.getExpressions().size() > 0) {
-                criteriaQuery.where(orPredicate);
+            if (predicates.size() > 0) {
+                criteriaQuery.where(predicates.toArray(new Predicate[0]));
+            } else {
+                criteriaQuery.where();
             }
 
-            List<T> entities = entityManager.createQuery(criteriaQuery).getResultList();
+            List<T> entities = entityManager.createQuery(criteriaQuery).setFirstResult(offset).setMaxResults(size).getResultList();
             entityManager.getTransaction().commit();
             entityManager.close();
             return entities;
diff --git a/src/main/java/org/tonality/repository/Subscription.java b/src/main/java/org/tonality/repository/Subscription.java
index 8f1961e..a04e239 100644
--- a/src/main/java/org/tonality/repository/Subscription.java
+++ b/src/main/java/org/tonality/repository/Subscription.java
@@ -1,7 +1,9 @@
 package org.tonality.repository;
 
 import org.tonality.model.SubscriptionId;
+import org.tonality.type.SubscriptionStatus;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
@@ -20,6 +22,136 @@ public class Subscription extends BaseRepository<org.tonality.model.Subscription
         return instance;
     }
 
+    public org.tonality.model.Subscription createSubscription(long userId, String username, long albumId, String albumName, String artist) {
+        try {
+            org.tonality.model.Subscription subscription = new org.tonality.model.Subscription();
+            subscription.setUserId(userId);
+            subscription.setUsername(username);
+            subscription.setAlbumId(albumId);
+            subscription.setAlbumName(albumName);
+            subscription.setArtist(artist);
+            if (org.tonality.repository.Subscription.getInstance().add(subscription) == null) {
+                throw new Exception("Failed to create subscription");
+            }
+            return subscription;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public org.tonality.model.Subscription updateSubscription(long userId, long albumId, SubscriptionStatus status) {
+        try {
+            org.tonality.model.Subscription subscription = org.tonality.repository.Subscription.getInstance().getById(new org.tonality.model.SubscriptionId(userId, albumId));
+            subscription.setStatus(status);
+            if (update(subscription) == null) {
+                throw new Exception("Failed to update subscription");
+            }
+            return subscription;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public List<org.tonality.model.Subscription> searchSubscriptions(SubscriptionStatus status, String searchInput, String orderBy, int page, int size) {
+        try {
+            if (searchInput == null || searchInput.isEmpty() || searchInput.equals("[string?]")) {
+                searchInput = "";
+            }
+
+            if (orderBy == null || orderBy.isEmpty() || orderBy.equals("[string?]")) {
+                orderBy = "albumName";
+            } else {
+                orderBy = orderBy.replaceAll(" ", "_");
+            }
+
+            if (page < 1) {
+                page = 1;
+            }
+            if (size < 1) {
+                size = 15;
+            }
+
+            java.util.Map<String, Object> andConditions = new java.util.HashMap<>();
+            andConditions.put("status", status);
+            java.util.Map<String, Object> orConditions = new java.util.HashMap<>();
+            ArrayList<String> searchField = new ArrayList<>();
+            searchField.add("username");
+            searchField.add("artist");
+            searchField.add("albumName");
+            return search(andConditions, orConditions, searchInput, searchField, orderBy, page, size);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public List<org.tonality.model.Subscription> getSubscriptionByStatus(SubscriptionStatus status, String orderBy, int page, int size) {
+        try {
+            if (orderBy == null || orderBy.isEmpty() || orderBy.equals("[string?]")) {
+                orderBy = "albumName";
+            } else {
+                orderBy = orderBy.replaceAll(" ", "_");
+            }
+
+            if (page < 1) {
+                page = 1;
+            }
+            if (size < 1) {
+                size = 15;
+            }
+
+            java.util.Map<String, Object> andConditions = new java.util.HashMap<>();
+            andConditions.put("status", status);
+            java.util.Map<String, Object> orConditions = new java.util.HashMap<>();
+            return search(andConditions, orConditions, "", new ArrayList<>(), orderBy, page, size);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public List<org.tonality.model.Subscription> getSubscriptionsByUserId(long userId, int page, int size) {
+        try {
+            java.util.Map<String, Object> andConditions = new java.util.HashMap<>();
+            andConditions.put("userId", userId);
+            java.util.Map<String, Object> orConditions = new java.util.HashMap<>();
+            return search(andConditions, orConditions, "", new ArrayList<>(), "albumName", page, size);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public boolean deleteSubscriptionsByUserId(long userId) {
+        try {
+            java.util.Map<String, Object> conditions = new java.util.HashMap<>();
+            conditions.put("userId", userId);
+            if (!delete(conditions)) {
+                throw new Exception("Failed to delete subscriptions");
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    public boolean deleteSubscriptionsByAlbumId(long albumId) {
+        try {
+            java.util.Map<String, Object> conditions = new java.util.HashMap<>();
+            conditions.put("albumId", albumId);
+            if (!delete(conditions)) {
+                throw new Exception("Failed to delete subscriptions");
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
     // Test
     public static void main(String[] args) {
         Subscription subscription = Subscription.getInstance();
@@ -30,6 +162,9 @@ public class Subscription extends BaseRepository<org.tonality.model.Subscription
             for (int j = 1; j < 4; j++) {
                 entity.setUserId(i);
                 entity.setAlbumId(j);
+                entity.setUsername("User " + i);
+                entity.setAlbumName("Album " + j);
+                entity.setArtist("Artist " + 10);
                 System.out.println(subscription.add(entity));
             }
         }
@@ -47,7 +182,7 @@ public class Subscription extends BaseRepository<org.tonality.model.Subscription
         Map<String, Object> andConditions = new java.util.HashMap<>();
         andConditions.put("status", org.tonality.type.SubscriptionStatus.ACTIVE.toString());
         java.util.Map<String, Object> orConditions = new java.util.HashMap<>();
-        java.util.List<org.tonality.model.Subscription> entities = subscription.search(andConditions, orConditions);
+        java.util.List<org.tonality.model.Subscription> entities = subscription.search(andConditions, orConditions, "", new ArrayList<>(), "albumName", 1, 15);
         for (org.tonality.model.Subscription e : entities) {
             System.out.println(e + "\n");
         }
diff --git a/src/main/java/org/tonality/ws/ISubscription.java b/src/main/java/org/tonality/service/ISubscription.java
similarity index 61%
rename from src/main/java/org/tonality/ws/ISubscription.java
rename to src/main/java/org/tonality/service/ISubscription.java
index e3fc4da..c335289 100644
--- a/src/main/java/org/tonality/ws/ISubscription.java
+++ b/src/main/java/org/tonality/service/ISubscription.java
@@ -1,4 +1,4 @@
-package org.tonality.ws;
+package org.tonality.service;
 
 import org.tonality.type.SubscriptionStatus;
 
@@ -6,6 +6,7 @@ import javax.jws.WebMethod;
 import javax.jws.WebParam;
 import javax.jws.WebResult;
 import javax.jws.WebService;
+import javax.xml.bind.annotation.XmlElement;
 import java.util.List;
 
 @WebService
@@ -15,8 +16,14 @@ public interface ISubscription {
     org.tonality.model.Subscription createSubscription(
             @WebParam(name = "userId")
             long userId,
+            @WebParam(name = "username")
+            String username,
             @WebParam(name = "albumId")
-            long albumId
+            long albumId,
+            @WebParam(name = "albumName")
+            String albumName,
+            @WebParam(name = "artist")
+            String artist
     );
 
     @WebMethod
@@ -39,18 +46,43 @@ public interface ISubscription {
             long albumId
     );
 
+    @WebMethod
+    @WebResult(name = "subscriptions")
+    List<org.tonality.model.Subscription> searchSubscription(
+            @WebParam(name = "status")
+            SubscriptionStatus status,
+            @WebParam(name = "searchInput")
+            String searchInput,
+            @WebParam(name = "orderBy")
+            String orderBy,
+            @WebParam(name = "page")
+            int page,
+            @WebParam(name = "size")
+            int size
+    );
+
     @WebMethod
     @WebResult(name = "subscriptions")
     List<org.tonality.model.Subscription> getSubscriptionsByStatus(
             @WebParam(name = "status")
-            SubscriptionStatus status
+            SubscriptionStatus status,
+            @WebParam(name = "orderBy")
+            String orderBy,
+            @WebParam(name = "page")
+            int page,
+            @WebParam(name = "size")
+            int size
     );
 
     @WebMethod
     @WebResult(name = "subscriptions")
     List<org.tonality.model.Subscription> getSubscriptionsByUserId(
             @WebParam(name = "userId")
-            long userId
+            long userId,
+            @WebParam(name = "page")
+            int page,
+            @WebParam(name = "size")
+            int size
     );
 
     @WebMethod
diff --git a/src/main/java/org/tonality/service/Subscription.java b/src/main/java/org/tonality/service/Subscription.java
new file mode 100644
index 0000000..7063209
--- /dev/null
+++ b/src/main/java/org/tonality/service/Subscription.java
@@ -0,0 +1,103 @@
+package org.tonality.service;
+
+import org.tonality.model.SubscriptionId;
+import org.tonality.type.SubscriptionStatus;
+
+import javax.jws.WebService;
+import java.util.List;
+
+@WebService(endpointInterface = "org.tonality.service.ISubscription")
+public class Subscription implements ISubscription {
+    @Override
+    public org.tonality.model.Subscription createSubscription(long userId, String username, long albumId, String albumName, String artist) {
+        try {
+            return org.tonality.repository.Subscription.getInstance().createSubscription(userId, username, albumId, albumName, artist);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    @Override
+    public org.tonality.model.Subscription updateSubscription(long userId, long albumId, SubscriptionStatus status) {
+        try {
+            return org.tonality.repository.Subscription.getInstance().updateSubscription(userId, albumId, status);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    @Override
+    public org.tonality.model.Subscription getSubscription(long userId, long albumId) {
+        try {
+            return org.tonality.repository.Subscription.getInstance().getById(new SubscriptionId(userId, albumId));
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    @Override
+    public List<org.tonality.model.Subscription> searchSubscription(SubscriptionStatus status, String searchInput, String orderBy, int page, int size) {
+        try {
+            return org.tonality.repository.Subscription.getInstance().searchSubscriptions(status, searchInput, orderBy, page, size);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    @Override
+    public List<org.tonality.model.Subscription> getSubscriptionsByStatus(SubscriptionStatus status, String orderBy, int page, int size) {
+        try {
+            return org.tonality.repository.Subscription.getInstance().getSubscriptionByStatus(status, orderBy, page, size);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    @Override
+    public List<org.tonality.model.Subscription> getSubscriptionsByUserId(long userId, int page, int size) {
+        try {
+            return org.tonality.repository.Subscription.getInstance().getSubscriptionsByUserId(userId, page, size);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    @Override
+    public boolean deleteSubscription(long userId, long albumId) {
+        try {
+            if (!org.tonality.repository.Subscription.getInstance().deleteById(new org.tonality.model.SubscriptionId(userId, albumId))) {
+                throw new Exception("Failed to delete subscription");
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    @Override
+    public boolean deleteSubscriptionsByUserId(long userId) {
+        try {
+            return org.tonality.repository.Subscription.getInstance().deleteSubscriptionsByUserId(userId);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    @Override
+    public boolean deleteSubscriptionsByAlbumId(long albumId) {
+        try {
+            return org.tonality.repository.Subscription.getInstance().deleteSubscriptionsByAlbumId(albumId);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+}
diff --git a/src/main/java/org/tonality/ws/Subscription.java b/src/main/java/org/tonality/ws/Subscription.java
deleted file mode 100644
index bd31846..0000000
--- a/src/main/java/org/tonality/ws/Subscription.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package org.tonality.ws;
-
-import org.tonality.type.SubscriptionStatus;
-
-import javax.jws.WebService;
-import java.util.List;
-
-@WebService(endpointInterface = "org.tonality.ws.ISubscription")
-public class Subscription implements ISubscription {
-    @Override
-    public org.tonality.model.Subscription createSubscription(long userId, long albumId) {
-        try {
-            org.tonality.model.Subscription subscription = new org.tonality.model.Subscription();
-            subscription.setUserId(userId);
-            subscription.setAlbumId(albumId);
-            if (org.tonality.repository.Subscription.getInstance().add(subscription) == null) {
-                throw new Exception("Failed to create subscription");
-            }
-            return subscription;
-        } catch (Exception e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    @Override
-    public org.tonality.model.Subscription updateSubscription(long userId, long albumId, SubscriptionStatus status) {
-        try {
-            org.tonality.model.Subscription subscription = new org.tonality.model.Subscription();
-            subscription.setUserId(userId);
-            subscription.setAlbumId(albumId);
-            subscription.setStatus(status);
-            if (org.tonality.repository.Subscription.getInstance().update(subscription) == null) {
-                throw new Exception("Failed to update subscription");
-            }
-            return subscription;
-        } catch (Exception e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    @Override
-    public org.tonality.model.Subscription getSubscription(long userId, long albumId) {
-        try {
-            org.tonality.model.SubscriptionId id = new org.tonality.model.SubscriptionId(userId, albumId);
-            return org.tonality.repository.Subscription.getInstance().getById(id);
-        } catch (Exception e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    @Override
-    public List<org.tonality.model.Subscription> getSubscriptionsByStatus(SubscriptionStatus status) {
-        try {
-            java.util.Map<String, Object> andConditions = new java.util.HashMap<>();
-            andConditions.put("status", status.toString());
-            java.util.Map<String, Object> orConditions = new java.util.HashMap<>();
-            return org.tonality.repository.Subscription.getInstance().search(andConditions, orConditions);
-        } catch (Exception e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    @Override
-    public List<org.tonality.model.Subscription> getSubscriptionsByUserId(long userId) {
-        try {
-            java.util.Map<String, Object> andConditions = new java.util.HashMap<>();
-            andConditions.put("userId", userId);
-            java.util.Map<String, Object> orConditions = new java.util.HashMap<>();
-            return org.tonality.repository.Subscription.getInstance().search(andConditions, orConditions);
-        } catch (Exception e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    @Override
-    public boolean deleteSubscription(long userId, long albumId) {
-        try {
-            org.tonality.model.SubscriptionId id = new org.tonality.model.SubscriptionId(userId, albumId);
-            if (!org.tonality.repository.Subscription.getInstance().deleteById(id)) {
-                throw new Exception("Failed to delete subscription");
-            }
-            return true;
-        } catch (Exception e) {
-            e.printStackTrace();
-            return false;
-        }
-    }
-
-    @Override
-    public boolean deleteSubscriptionsByUserId(long userId) {
-        try {
-            java.util.Map<String, Object> conditions = new java.util.HashMap<>();
-            conditions.put("userId", userId);
-            if (!org.tonality.repository.Subscription.getInstance().delete(conditions)) {
-                throw new Exception("Failed to delete subscriptions");
-            }
-            return true;
-        } catch (Exception e) {
-            e.printStackTrace();
-            return false;
-        }
-    }
-
-    @Override
-    public boolean deleteSubscriptionsByAlbumId(long albumId) {
-        try {
-            java.util.Map<String, Object> conditions = new java.util.HashMap<>();
-            conditions.put("albumId", albumId);
-            if (!org.tonality.repository.Subscription.getInstance().delete(conditions)) {
-                throw new Exception("Failed to delete subscriptions");
-            }
-            return true;
-        } catch (Exception e) {
-            e.printStackTrace();
-            return false;
-        }
-    }
-}
-- 
GitLab