From db29a4869ccc06b0248c78af0f6711a708da57de Mon Sep 17 00:00:00 2001 From: Zaki <zakiamanullah215@gmail.com> Date: Sun, 12 Nov 2023 23:51:15 +0700 Subject: [PATCH] chore: general architecture --- .env | 6 + .gitignore | 5 +- .idea/dataSources.xml | 12 ++ .idea/sqldialects.xml | 7 + .idea/uiDesigner.xml | 124 ++++++++++++++++++ Dockerfile | 2 +- db/migrations.sql | 14 ++ docker-compose.yml | 11 +- pom.xml | 28 ++++ src/main/java/org/spotiplay/Main.java | 2 + src/main/java/org/spotiplay/db/Database.java | 41 ++++++ .../org/spotiplay/db/DatabaseInterface.java | 6 + .../java/org/spotiplay/model/Logging.java | 61 +++++++++ src/main/java/org/spotiplay/model/Model.java | 5 + .../org/spotiplay/model/Subscription.java | 71 ++++++++++ .../spotiplay/model/SubscriptionStatus.java | 19 +++ .../org/spotiplay/repo/LoggingRepository.java | 40 ++++++ .../java/org/spotiplay/repo/Repository.java | 36 +++++ .../repo/SubscriptionRepository.java | 111 ++++++++++++++++ src/main/java/org/spotiplay/utils/Dotenv.java | 29 ++++ .../spotiplay/ws/SubscriptionInterface.java | 8 ++ .../java/org/spotiplay/ws/WebService.java | 9 ++ 22 files changed, 644 insertions(+), 3 deletions(-) create mode 100644 .env create mode 100644 .idea/dataSources.xml create mode 100644 .idea/sqldialects.xml create mode 100644 .idea/uiDesigner.xml create mode 100644 db/migrations.sql create mode 100644 src/main/java/org/spotiplay/db/Database.java create mode 100644 src/main/java/org/spotiplay/db/DatabaseInterface.java create mode 100644 src/main/java/org/spotiplay/model/Logging.java create mode 100644 src/main/java/org/spotiplay/model/Model.java create mode 100644 src/main/java/org/spotiplay/model/Subscription.java create mode 100644 src/main/java/org/spotiplay/model/SubscriptionStatus.java create mode 100644 src/main/java/org/spotiplay/repo/LoggingRepository.java create mode 100644 src/main/java/org/spotiplay/repo/Repository.java create mode 100644 src/main/java/org/spotiplay/repo/SubscriptionRepository.java create mode 100644 src/main/java/org/spotiplay/utils/Dotenv.java create mode 100644 src/main/java/org/spotiplay/ws/SubscriptionInterface.java create mode 100644 src/main/java/org/spotiplay/ws/WebService.java diff --git a/.env b/.env new file mode 100644 index 0000000..4a76d71 --- /dev/null +++ b/.env @@ -0,0 +1,6 @@ +MYSQL_DATABASE=spotiplay-soap +MYSQL_USER=kelompok-30 +MYSQL_PASSWORD=kelompok-30 +MYSQL_ROOT_PASSWORD=kelompok-30 +REST_API_KEY=fb791bd8fbf13047b92a2e9819d1a85e09279a878937aebce4654beccff5f66cecc6b93969c6e8b55c24bf4604a93f4c8b1b0f827bfd3d12fb4034c314d8f24e +PHP_API_KEY=6c15b79f3d06aca57138c9df532de8c64681729c15ad29be4eb2250984bed2292b7f0750dc9195d99fa535ecc16bcd116735ff727981066448e880a228d76942 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 5ff6309..ffdf945 100644 --- a/.gitignore +++ b/.gitignore @@ -35,4 +35,7 @@ build/ .vscode/ ### Mac OS ### -.DS_Store \ No newline at end of file +.DS_Store + +### Environment Files ### +.env \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..e765bc8 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="DataSourceManagerImpl" format="xml" multifile-model="true"> + <data-source source="LOCAL" name="Spotiplay SOAP Database" uuid="531f93a0-db1d-4637-a0b5-15246be545fa"> + <driver-ref>mysql.8</driver-ref> + <synchronize>true</synchronize> + <jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver> + <jdbc-url>jdbc:mysql://host.docker.internal:3306/spotiplay-soap</jdbc-url> + <working-dir>$ProjectFileDir$</working-dir> + </data-source> + </component> +</project> \ No newline at end of file diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml new file mode 100644 index 0000000..49d36c4 --- /dev/null +++ b/.idea/sqldialects.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="SqlDialectMappings"> + <file url="file://$PROJECT_DIR$/db/migrations.sql" dialect="GenericSQL" /> + <file url="PROJECT" dialect="MySQL" /> + </component> +</project> \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="Palette2"> + <group name="Swing"> + <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" /> + </item> + <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" /> + </item> + <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" /> + </item> + <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true"> + <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" /> + </item> + <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" /> + <initial-values> + <property name="text" value="Button" /> + </initial-values> + </item> + <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> + <initial-values> + <property name="text" value="RadioButton" /> + </initial-values> + </item> + <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> + <initial-values> + <property name="text" value="CheckBox" /> + </initial-values> + </item> + <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" /> + <initial-values> + <property name="text" value="Label" /> + </initial-values> + </item> + <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> + <preferred-size width="150" height="-1" /> + </default-constraints> + </item> + <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> + <preferred-size width="150" height="-1" /> + </default-constraints> + </item> + <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> + <preferred-size width="150" height="-1" /> + </default-constraints> + </item> + <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" /> + </item> + <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> + <preferred-size width="200" height="200" /> + </default-constraints> + </item> + <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> + <preferred-size width="200" height="200" /> + </default-constraints> + </item> + <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> + </item> + <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> + </item> + <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" /> + </item> + <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" /> + </item> + <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1"> + <preferred-size width="-1" height="20" /> + </default-constraints> + </item> + <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" /> + </item> + <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" /> + </item> + </group> + </component> +</project> \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 48fa6fb..b2142e4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,4 +6,4 @@ COPY target/spotiplay-soap-1.0-SNAPSHOT.jar /app/spotiplay-soap-1.0-SNAPSHOT.jar EXPOSE 8080 -ENTRYPOINT ["java", "-jar", "spotiplay-soap-1.0-SNAPSHOT.jar"] \ No newline at end of file +ENTRYPOINT ["java", "-jar", "spotiplay-soap-1.0-SNAPSHOT-jar-with-dependencies.jar"] \ No newline at end of file diff --git a/db/migrations.sql b/db/migrations.sql new file mode 100644 index 0000000..7d9acc8 --- /dev/null +++ b/db/migrations.sql @@ -0,0 +1,14 @@ +CREATE TABLE logging ( + id SERIAL PRIMARY KEY, + description TEXT NOT NULL, + ip CHAR(255) NOT NULL, + endpoint VARCHAR(255) NOT NULL, + requested_at TIMESTAMP NOT NULL DEFAULT NOW() NOT NULL +); + +CREATE TABLE subscriptions ( + creator_id SERIAL PRIMARY KEY, + user_id INTEGER NOT NULL, + STATUS ENUM('pending', 'accepted', 'rejected') NOT NULL DEFAULT 'pending' +); + diff --git a/docker-compose.yml b/docker-compose.yml index 8903ddf..0fb671e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,4 +7,13 @@ services: ports: - "8080:8080" volumes: - - ./target/spotiplay-soap-1.0-SNAPSHOT.jar:/app/spotiplay-soap-1.0-SNAPSHOT.jar \ No newline at end of file + - ./target/spotiplay-soap-1.0-SNAPSHOT.jar:/app/spotiplay-soap-1.0-SNAPSHOT.jar + - ./target/spotiplay-soap-1.0-SNAPSHOT-jar-with-dependencies.jar:/app/spotiplay-soap-1.0-SNAPSHOT-jar-with-dependencies.jar + soap-db: + image: mysql:5.7 + ports: + - "3306:3306" + env_file: + - .env + volumes: + - ./db:/docker-entrypoint-initdb.d \ No newline at end of file diff --git a/pom.xml b/pom.xml index 4c6cdf1..50adbd6 100644 --- a/pom.xml +++ b/pom.xml @@ -14,6 +14,11 @@ <artifactId>jaxws-rt</artifactId> <version>2.3.5</version> </dependency> + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + <version>8.0.23</version> + </dependency> </dependencies> <build> @@ -31,6 +36,29 @@ </archive> </configuration> </plugin> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>3.3.0</version> <!-- Use the latest version available --> + <configuration> + <archive> + <manifest> + <mainClass>org.spotiplay.Main</mainClass> <!-- Replace with your main class --> + </manifest> + </archive> + <descriptorRefs> + <descriptorRef>jar-with-dependencies</descriptorRef> + </descriptorRefs> + </configuration> + <executions> + <execution> + <id>make-assembly</id> <!-- this is used for an identifier --> + <phase>package</phase> <!-- bind to the packaging phase --> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> </plugins> </build> diff --git a/src/main/java/org/spotiplay/Main.java b/src/main/java/org/spotiplay/Main.java index b1e0d3c..15dc478 100644 --- a/src/main/java/org/spotiplay/Main.java +++ b/src/main/java/org/spotiplay/Main.java @@ -1,5 +1,7 @@ package org.spotiplay; +import org.spotiplay.db.Database; + import javax.xml.ws.Endpoint; public class Main { diff --git a/src/main/java/org/spotiplay/db/Database.java b/src/main/java/org/spotiplay/db/Database.java new file mode 100644 index 0000000..aebd9e3 --- /dev/null +++ b/src/main/java/org/spotiplay/db/Database.java @@ -0,0 +1,41 @@ +package org.spotiplay.db; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +public class Database implements DatabaseInterface { + private static Database instance = null; + private Connection connection; + + private Database() { + String url = "jdbc:mysql://host.docker.internal:3306/spotiplay-soap?useSSL=false"; + String username = "kelompok-30"; + String password = "kelompok-30"; + try { + connection = DriverManager.getConnection(url, username, password); + } catch (SQLException e) { + System.out.println("SQLException: " + e.getMessage()); + System.out.println("SQLState: " + e.getSQLState()); + System.out.println("VendorError: " + e.getErrorCode()); + e.printStackTrace(); + System.exit(1); + } catch (Exception e) { + System.out.println("Error: " + e.getMessage()); + e.printStackTrace(); + System.exit(1); + } + } + + @Override + public Connection getConnection() { + return connection; + } + + public static Database getInstance() { + if (instance == null) { + instance = new Database(); + } + return instance; + } +} diff --git a/src/main/java/org/spotiplay/db/DatabaseInterface.java b/src/main/java/org/spotiplay/db/DatabaseInterface.java new file mode 100644 index 0000000..e9e1e24 --- /dev/null +++ b/src/main/java/org/spotiplay/db/DatabaseInterface.java @@ -0,0 +1,6 @@ +package org.spotiplay.db; + +import java.sql.Connection; +public interface DatabaseInterface { + public Connection getConnection(); +} diff --git a/src/main/java/org/spotiplay/model/Logging.java b/src/main/java/org/spotiplay/model/Logging.java new file mode 100644 index 0000000..0a27944 --- /dev/null +++ b/src/main/java/org/spotiplay/model/Logging.java @@ -0,0 +1,61 @@ +package org.spotiplay.model; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class Logging extends Model { + private String description; + private String ipAddress; + private String endpoint; + private String requestedAt; + + public Logging(String description, String ipAddress, String endpoint, String requestedAt) { + this.description = description; + this.ipAddress = ipAddress; + this.endpoint = endpoint; + this.requestedAt = requestedAt; + } + + public Logging() { + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getIpAddress() { + return ipAddress; + } + + public void setIpAddress(String ipAddress) { + this.ipAddress = ipAddress; + } + + public String getEndpoint() { + return endpoint; + } + + public void setEndpoint(String endpoint) { + this.endpoint = endpoint; + } + + public String getRequestedAt() { + return requestedAt; + } + + public void setRequestedAt(String requestedAt) { + this.requestedAt = requestedAt; + } + + @Override + public void constructFromSQLResult(ResultSet result) throws SQLException { + this.description = result.getString("description"); + this.ipAddress = result.getString("ip_address"); + this.endpoint = result.getString("endpoint"); + this.requestedAt = result.getString("requested_at"); + } +} diff --git a/src/main/java/org/spotiplay/model/Model.java b/src/main/java/org/spotiplay/model/Model.java new file mode 100644 index 0000000..107e889 --- /dev/null +++ b/src/main/java/org/spotiplay/model/Model.java @@ -0,0 +1,5 @@ +package org.spotiplay.model; + +public abstract class Model { + public abstract void constructFromSQLResult(java.sql.ResultSet result) throws java.sql.SQLException; +} diff --git a/src/main/java/org/spotiplay/model/Subscription.java b/src/main/java/org/spotiplay/model/Subscription.java new file mode 100644 index 0000000..64582ee --- /dev/null +++ b/src/main/java/org/spotiplay/model/Subscription.java @@ -0,0 +1,71 @@ +package org.spotiplay.model; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class Subscription extends Model { + + private Integer creatorId; + private Integer userId; + private SubscriptionStatus status; + + public Subscription(Integer creatorId, Integer userId, SubscriptionStatus status) { + this.creatorId = creatorId; + this.userId = userId; + this.status = status; + } + + public Subscription() { + } + + public Integer getCreatorId() { + return creatorId; + } + + public void setCreatorId(Integer creatorId) { + this.creatorId = creatorId; + } + + public Integer getUserId() { + return userId; + } + + public void setUserId(Integer userId) { + this.userId = userId; + } + + public SubscriptionStatus getStatus() { + return status; + } + + public void setStatus(SubscriptionStatus status) { + this.status = status; + } + + @Override + public void constructFromSQLResult(ResultSet result) throws SQLException { + this.creatorId = result.getInt("creator_id"); + this.userId = result.getInt("user_id"); + this.status = SubscriptionStatus.fromString(result.getString("status")); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Subscription that = (Subscription) o; + + if (!creatorId.equals(that.creatorId)) return false; + if (!userId.equals(that.userId)) return false; + return status == that.status; + } + + @Override + public int hashCode() { + int result = creatorId.hashCode(); + result = 31 * result + userId.hashCode(); + result = 31 * result + status.hashCode(); + return result; + } +} diff --git a/src/main/java/org/spotiplay/model/SubscriptionStatus.java b/src/main/java/org/spotiplay/model/SubscriptionStatus.java new file mode 100644 index 0000000..92e58c0 --- /dev/null +++ b/src/main/java/org/spotiplay/model/SubscriptionStatus.java @@ -0,0 +1,19 @@ +package org.spotiplay.model; + +import javax.xml.bind.annotation.XmlEnum; + +@XmlEnum +public enum SubscriptionStatus { + PENDING, + ACCEPTED, + REJECTED; + + public static SubscriptionStatus fromString(String value) { + for (SubscriptionStatus status : SubscriptionStatus.values()) { + if (status.toString().equalsIgnoreCase(value)) { + return status; + } + } + return null; + } +} diff --git a/src/main/java/org/spotiplay/repo/LoggingRepository.java b/src/main/java/org/spotiplay/repo/LoggingRepository.java new file mode 100644 index 0000000..0f692c4 --- /dev/null +++ b/src/main/java/org/spotiplay/repo/LoggingRepository.java @@ -0,0 +1,40 @@ +package org.spotiplay.repo; + +import org.spotiplay.db.Database; +import org.spotiplay.model.Logging; + +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + +public class LoggingRepository extends Repository<Logging> { + private static LoggingRepository instance; + + public LoggingRepository(Database database, String tableName) { + super(database, tableName); + } + + @Override + public Repository<Logging> getInstance() { + if (instance == null) { + instance = new LoggingRepository(Database.getInstance(), "logging"); + } + return instance; + } + + @Override + public Logging create(Logging logging) throws Exception{ + Connection connection = database.getConnection(); + Statement stmt = connection.createStatement(); + + String sql = "INSERT INTO " + tableName + " (description, ip, endpoint, requested_at) VALUES ('" + + logging.getDescription() + "', '" + logging.getIpAddress() + "', '" + logging.getEndpoint() + "', '" + + logging.getRequestedAt() + "');"; + + int res = stmt.executeUpdate(sql); + if (res == 0) { + throw new Exception("Error: Failed to create log"); + } + return null; + } +} diff --git a/src/main/java/org/spotiplay/repo/Repository.java b/src/main/java/org/spotiplay/repo/Repository.java new file mode 100644 index 0000000..4313a89 --- /dev/null +++ b/src/main/java/org/spotiplay/repo/Repository.java @@ -0,0 +1,36 @@ +package org.spotiplay.repo; + +import org.spotiplay.db.Database; + +import java.util.List; +import java.util.Map; + +public abstract class Repository<Model> { + protected Database database; + protected String tableName; + + public Repository(Database database, String tableName) { + this.database = database; + this.tableName = tableName; + } + + public abstract Repository<Model> getInstance(); + public List<Model> findAll() throws Exception { + throw new Exception("Not implemented"); + } + public Model create(Model model) throws Exception { + throw new Exception("Not implemented"); + } + public Model update(Model model) throws Exception { + throw new Exception("Not implemented"); + } + public Model delete(Model model) throws Exception { + throw new Exception("Not implemented"); + } + public Model findById(Map<String, Integer> id) throws Exception { + throw new Exception("Not implemented"); + } + public List<Model> findBy(String field, String value) throws Exception { + throw new Exception("Not implemented"); + } +} diff --git a/src/main/java/org/spotiplay/repo/SubscriptionRepository.java b/src/main/java/org/spotiplay/repo/SubscriptionRepository.java new file mode 100644 index 0000000..33a1b92 --- /dev/null +++ b/src/main/java/org/spotiplay/repo/SubscriptionRepository.java @@ -0,0 +1,111 @@ +package org.spotiplay.repo; + +import org.spotiplay.db.Database; +import org.spotiplay.model.Subscription; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class SubscriptionRepository extends Repository<Subscription> { + private static SubscriptionRepository instance; + + public SubscriptionRepository(Database database, String tableName) { + super(database, tableName); + } + + @Override + public Repository<Subscription> getInstance() { + if (instance == null) { + instance = new SubscriptionRepository(Database.getInstance(), "subscription"); + } + return instance; + } + + public List<Subscription> findAll() throws SQLException { + List<Subscription> result = new ArrayList<>(); + + Connection connection = database.getConnection(); + Statement statement = connection.createStatement(); + String sql = "SELECT * FROM " + tableName + ";"; + ResultSet rs = statement.executeQuery(sql); + while (rs.next()) { + Subscription subscription = new Subscription(); + subscription.constructFromSQLResult(rs); + result.add(subscription); + } + return result; + } + + public Subscription create(Subscription model) throws SQLException { + Connection connection = database.getConnection(); + Statement stmt = connection.createStatement(); + String sql = "INSERT INTO " + tableName + " (creator_id, user_id) VALUES (" + + model.getCreatorId() + ", " + model.getUserId() + ");"; + int res = stmt.executeUpdate(sql); + if (res == 0) { + throw new SQLException("Error: Failed to create subscription"); + } + return null; + } + + public Subscription update(Subscription model) throws SQLException { + Connection connection = database.getConnection(); + Statement stmt = connection.createStatement(); + String sql = "UPDATE " + tableName + " SET status = '" + model.getStatus().toString() + "' WHERE creator_id = " + + model.getCreatorId() + " AND user_id = " + model.getUserId() + ";"; + int res = stmt.executeUpdate(sql); + if (res == 0) { + throw new SQLException("Error: Failed to update subscription"); + } else if (res > 1) { + throw new SQLException("Error: Updated more than one subscription"); + } + return null; + } + + public Subscription delete(Subscription model) throws SQLException { + Connection connection = database.getConnection(); + Statement stmt = connection.createStatement(); + String sql = "DELETE FROM " + tableName + " WHERE creator_id = " + model.getCreatorId() + " AND user_id = " + + model.getUserId() + ";"; + int res = stmt.executeUpdate(sql); + if (res == 0) { + throw new SQLException("Error: Failed to delete subscription"); + } else if (res > 1) { + throw new SQLException("Error: Deleted more than one subscription"); + } + return null; + } + + public Subscription findById(Map<String, Integer> id) throws SQLException { + assert id.size() == 2 && id.containsKey("creator_id") && id.containsKey("user_id"); + Connection connection = database.getConnection(); + Statement statement = connection.createStatement(); + String sql = "SELECT * FROM " + tableName + " WHERE creator_id = " + id.get("creator_id") + " AND user_id = " + id.get("user_id") + ";"; + ResultSet rs = statement.executeQuery(sql); + Subscription subscription = new Subscription(); + subscription.constructFromSQLResult(rs); + return subscription; + } + public List<Subscription> findBy(String field, String value) throws SQLException { + List<Subscription> result = new ArrayList<>(); + + Connection connection = database.getConnection(); + Statement statement = connection.createStatement(); + String sql = "SELECT * FROM " + tableName + " WHERE " + field + " = '" + value + "';"; + ResultSet rs = statement.executeQuery(sql); + + while (rs.next()) { + Subscription subscription = new Subscription(); + subscription.constructFromSQLResult(rs); + result.add(subscription); + } + + return result; + } + +} diff --git a/src/main/java/org/spotiplay/utils/Dotenv.java b/src/main/java/org/spotiplay/utils/Dotenv.java new file mode 100644 index 0000000..2e59122 --- /dev/null +++ b/src/main/java/org/spotiplay/utils/Dotenv.java @@ -0,0 +1,29 @@ +package org.spotiplay.utils; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class Dotenv { + private static final Map<String, String> env = load(); + public static Map<String, String> load() { + Map<String, String> env = new HashMap<>(); + try { + BufferedReader reader = new BufferedReader(new FileReader(".env")); + String line; + while ((line = reader.readLine()) != null) { + String[] parts = line.split("="); + env.put(parts[0].trim(), parts[1].trim()); + } + reader.close(); + } catch (IOException e) { + System.out.println("Error: " + e.getMessage()); + } + return env; + } + public static String get(String key) { + return env.get(key); + } +} diff --git a/src/main/java/org/spotiplay/ws/SubscriptionInterface.java b/src/main/java/org/spotiplay/ws/SubscriptionInterface.java new file mode 100644 index 0000000..344747c --- /dev/null +++ b/src/main/java/org/spotiplay/ws/SubscriptionInterface.java @@ -0,0 +1,8 @@ +package org.spotiplay.ws; + +import javax.jws.WebMethod; +import javax.jws.WebService; + +@WebService +public interface SubscriptionInterface { +} diff --git a/src/main/java/org/spotiplay/ws/WebService.java b/src/main/java/org/spotiplay/ws/WebService.java new file mode 100644 index 0000000..4fa0ea3 --- /dev/null +++ b/src/main/java/org/spotiplay/ws/WebService.java @@ -0,0 +1,9 @@ +package org.spotiplay.ws; + +public abstract class WebService { + protected void recordClientRequest(String endpoint, String description, String ipAddress) { + + } + + +} -- GitLab