From d27fa84ab437a446690b4f20067acf41e36f0764 Mon Sep 17 00:00:00 2001
From: MatMasIt <34745996+MatMasIt@users.noreply.github.com>
Date: Thu, 17 Jun 2021 01:47:29 +0200
Subject: [PATCH] Add files via upload
---
README.md | 25 ++
WallPost/WallPost.iml | 11 +
WallPost/src/HeaderNotFoundException.java | 5 +
WallPost/src/Post.java | 35 +++
WallPost/src/PostList.java | 5 +
WallPost/src/ServerConnection.java | 230 +++++++++++++++++
WallPost/src/ServerErrorException.java | 13 +
WallPost/src/Window.java | 231 ++++++++++++++++++
WallPostServer/WallPostServer.iml | 11 +
.../WallPostServer_jar/WallPostServer.jar | Bin 0 -> 10052 bytes
.../WallPostServer/META-INF/MANIFEST.MF | 3 +
.../src/HeaderNotFoundException.java | 5 +
WallPostServer/src/META-INF/MANIFEST.MF | 3 +
WallPostServer/src/PermanentSorage.java | 73 ++++++
WallPostServer/src/Post.java | 37 +++
WallPostServer/src/PostList.java | 18 ++
WallPostServer/src/SaveContainer.java | 27 ++
WallPostServer/src/ServerThread.java | 201 +++++++++++++++
WallPostServer/src/User.java | 25 ++
WallPostServer/src/UserList.java | 24 ++
WallPostServer/src/WallPostServer.java | 34 +++
21 files changed, 1016 insertions(+)
create mode 100644 README.md
create mode 100644 WallPost/WallPost.iml
create mode 100644 WallPost/src/HeaderNotFoundException.java
create mode 100644 WallPost/src/Post.java
create mode 100644 WallPost/src/PostList.java
create mode 100644 WallPost/src/ServerConnection.java
create mode 100644 WallPost/src/ServerErrorException.java
create mode 100644 WallPost/src/Window.java
create mode 100644 WallPostServer/WallPostServer.iml
create mode 100644 WallPostServer/out/artifacts/WallPostServer_jar/WallPostServer.jar
create mode 100644 WallPostServer/out/production/WallPostServer/META-INF/MANIFEST.MF
create mode 100644 WallPostServer/src/HeaderNotFoundException.java
create mode 100644 WallPostServer/src/META-INF/MANIFEST.MF
create mode 100644 WallPostServer/src/PermanentSorage.java
create mode 100644 WallPostServer/src/Post.java
create mode 100644 WallPostServer/src/PostList.java
create mode 100644 WallPostServer/src/SaveContainer.java
create mode 100644 WallPostServer/src/ServerThread.java
create mode 100644 WallPostServer/src/User.java
create mode 100644 WallPostServer/src/UserList.java
create mode 100644 WallPostServer/src/WallPostServer.java
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..60d2c8b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,25 @@
+# WallPost
+
+A Java Swing application which allows to post articles on a remote "wall"
+
+Includes:
+
+* SignUp/SignIn
+* Posting stories
+* Reading stories
+* Multi-threaded server
+* State persistence
+
+Employs a custom protocol in communication ("FOLLOWS protocol" to exchange variables)
+
+
+
+> **Notice**
+> This is just a demonstrative application
+> It lacks basic functionalities as editing and upvoting, and relies on terrible storage and authentication, in fact it does not even use SSL or TLS
+> Be aware of this
+
+
+
+* WallPost: The client
+* WallPostServer: The server
\ No newline at end of file
diff --git a/WallPost/WallPost.iml b/WallPost/WallPost.iml
new file mode 100644
index 0000000..c90834f
--- /dev/null
+++ b/WallPost/WallPost.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/WallPost/src/HeaderNotFoundException.java b/WallPost/src/HeaderNotFoundException.java
new file mode 100644
index 0000000..07c7fa6
--- /dev/null
+++ b/WallPost/src/HeaderNotFoundException.java
@@ -0,0 +1,5 @@
+public class HeaderNotFoundException extends Exception{
+ public HeaderNotFoundException(){
+ super("Header not found");
+ }
+}
diff --git a/WallPost/src/Post.java b/WallPost/src/Post.java
new file mode 100644
index 0000000..e499584
--- /dev/null
+++ b/WallPost/src/Post.java
@@ -0,0 +1,35 @@
+public class Post {
+ public String getTitle() {
+ return title;
+ }
+
+ public String getBody() {
+ return body;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public String getDate() {
+ return date;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ private String title, body,author, date;
+ private int id;
+ public void setBody(String body) {
+ this.body = body;
+ }
+
+ public Post(String title, String body, String author, String date, int id){
+ this.title=title;
+ this.body=body;
+ this.author=author;
+ this.date=date;
+ this.id=id;
+ }
+}
diff --git a/WallPost/src/PostList.java b/WallPost/src/PostList.java
new file mode 100644
index 0000000..24bed3b
--- /dev/null
+++ b/WallPost/src/PostList.java
@@ -0,0 +1,5 @@
+import java.util.ArrayList;
+
+public class PostList extends ArrayList{
+
+}
diff --git a/WallPost/src/ServerConnection.java b/WallPost/src/ServerConnection.java
new file mode 100644
index 0000000..6a63b45
--- /dev/null
+++ b/WallPost/src/ServerConnection.java
@@ -0,0 +1,230 @@
+import javax.swing.*;
+import java.io.*;
+import java.lang.reflect.Array;
+import java.net.Socket;
+import java.rmi.ServerError;
+import java.util.ArrayList;
+
+public class ServerConnection {
+ private Socket socket;
+ private InputStreamReader i;
+ private BufferedReader in;
+ private OutputStreamWriter osw;
+ private BufferedWriter bw;
+ private PrintWriter out;
+ private ArrayList headers=new ArrayList();
+ private ArrayList values=new ArrayList();
+ private JFrame window;
+ public ServerConnection(JFrame window) throws IOException {
+ this.window=window;
+ socket= new Socket("mascmt.ddns.net",70);
+ i= new InputStreamReader(socket.getInputStream());
+ in = new BufferedReader(i);
+ osw= new OutputStreamWriter(socket.getOutputStream());
+ bw =new BufferedWriter(osw);
+ out= new PrintWriter(bw, true);
+ out.println("HELLO");
+ }
+ public ArrayList> sendData(String action) throws IOException, ServerErrorException {//lenght of Arralist[] is 2 as in headers, values
+ ArrayList> hv=new ArrayList>();
+ hv.add(new ArrayList());
+ hv.add(new ArrayList());
+ out.println("HELLO AGAIN");
+ out.println("ACTION " + action);
+ for (int c = 0; c < headers.size(); c++) {
+ out.println("FOLLOWS " + headers.get(c).replaceAll("FOLLOWS","follows").replaceAll("END","end"));
+ out.println(values.get(c).replaceAll("FOLLOWS","follows").replaceAll("END","end"));
+ }
+ out.println("END");
+ String line="",temp="";
+ if(in.readLine().equals("ERROR")){
+ while(true){
+ line=in.readLine();
+ if(line.equals("END")){
+ String title=in.readLine();
+ String type=in.readLine();
+
+ if(in.readLine().equals("QUIT")){
+ throw new ServerErrorException(title,temp,in.readLine(),true);
+ }
+ else{
+ throw new ServerErrorException(title,temp,in.readLine(),false);
+ }
+ }
+ else{
+
+ temp+=line;
+ }
+ }
+ }
+ int flNum=0;
+ do{
+ line=in.readLine();
+ if(line.startsWith("FOLLOWS")){
+ hv.get(0).add(line.split(" ",2)[1]);
+ if(flNum!=0){
+ hv.get(1).add(temp);
+ }
+ temp="";
+ flNum++;
+ }
+ else if(line.equals("END")){
+ hv.get(1).add(temp);
+ }
+ else{
+ temp+=line;
+ }
+
+ }while (!line.equals("END"));
+ return hv;
+ }
+ public void init(){
+ headers.clear();
+ values.clear();
+ }
+ public void bindParam(String h,String v){
+ headers.add(h);
+ values.add(v);
+ }
+
+ public ArrayList> handledGetData(String action){
+ ArrayList> s=new ArrayList>(2);
+ try {
+ s=this.sendData(action);
+ } catch (IOException e) {
+ JOptionPane.showMessageDialog(window,
+ "Connection error",
+ "Could not connect to the server",
+ JOptionPane.ERROR_MESSAGE);
+ } catch (ServerErrorException e) {
+ handleServerErrorInGUI(e.title,e.message,e.errorType,e.mustQuit);
+ }
+ System.out.println(s.toString());
+ return s;
+ }
+
+ public void handleServerErrorInGUI(String title, String text, String type, boolean mustQuit){
+ if(type.equals("INFO")){
+ JOptionPane.showMessageDialog(this.window, title, text,JOptionPane.INFORMATION_MESSAGE);
+
+ }
+ else if(type.equals("WARNING")){
+ JOptionPane.showMessageDialog(this.window,
+ title,
+ text,
+ JOptionPane.WARNING_MESSAGE);
+
+
+ }
+ else if(type.equals("PLAIN")){
+ JOptionPane.showMessageDialog(this.window,
+ title,
+ text,
+ JOptionPane.PLAIN_MESSAGE);
+
+
+ }
+ else{//ERROR
+ JOptionPane.showMessageDialog(this.window,
+ title,
+ text,
+ JOptionPane.ERROR_MESSAGE);
+
+ }
+ if(mustQuit) {
+ System.exit(1);
+ }
+ }
+ public String valueByHeader(ArrayList> resp,String header) throws HeaderNotFoundException {
+ for(int i=0;i> li= this.handledGetData("signIn");
+ try {
+ return this.valueByHeader(li,"status").trim().equals("OK");
+ } catch (HeaderNotFoundException e) {
+ return false;
+ }
+ }
+ public boolean signUp(String username, String password){
+ this.init();
+ this.bindParam("username",username);
+ this.bindParam("password",password);
+ ArrayList> li= this.handledGetData("signUp");
+
+ try {
+ return this.valueByHeader(li,"status").trim().equals("OK");
+ } catch (HeaderNotFoundException e) {
+ return false;
+ }
+ }
+ public PostList fetchPostsFromServer(){
+ this.init();
+ ArrayList> li =this.handledGetData("listPosts");
+ PostList p= new PostList();
+ int count=0;
+ for(int i=0; i> li=this.handledGetData("getPostBody");
+ String body="";
+ try {
+ body=this.valueByHeader(li,"body");
+ } catch (HeaderNotFoundException e) {
+ body="An error occurred while loading the post";
+ }
+ a.setBody(body);
+ list.set(index,a);
+ }
+ return a;
+ }
+ public void publishPost(String title,String body){
+ this.init();
+ this.bindParam("POST-Title",title);
+ this.bindParam("POST-Body",body);
+ this.handledGetData("sendPost");
+ }
+ /*
+ NOT SUPPORTED BY SERVER
+ @Deprecated
+ public Post getPost(int Id) throws HeaderNotFoundException {
+ this.init();
+ this.bindParam("POST-Id",String.valueOf(Id));
+ ArrayList> li=this.handledGetData("getPost");
+ Post p= new Post(this.valueByHeader(li,"POST-Title"),this.valueByHeader(li,"POST-Body"),this.valueByHeader(li,"POST-Author"),this.valueByHeader(li,"POST-Date"),Integer.parseInt(this.valueByHeader(li,"POST-Id")));
+ return p;
+ }
+
+ */
+
+}
diff --git a/WallPost/src/ServerErrorException.java b/WallPost/src/ServerErrorException.java
new file mode 100644
index 0000000..596078a
--- /dev/null
+++ b/WallPost/src/ServerErrorException.java
@@ -0,0 +1,13 @@
+import javax.swing.*;
+
+public class ServerErrorException extends Exception{
+ public String message,errorType, title;
+ public boolean mustQuit;
+ public ServerErrorException(String title, String message, String errorType, boolean mustQuit){
+ super("The server issued an error");
+ this.message=message;
+ this.title=title;
+ this.errorType = errorType;
+ this.mustQuit=mustQuit;
+ }
+}
diff --git a/WallPost/src/Window.java b/WallPost/src/Window.java
new file mode 100644
index 0000000..2a877d9
--- /dev/null
+++ b/WallPost/src/Window.java
@@ -0,0 +1,231 @@
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.DefaultTableModel;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.io.IOException;
+
+public class Window extends JFrame implements ActionListener {
+ private JPanel auth, list, viewOne, mine;
+ private JLabel labelUsername, labelPassword, postHeader;
+ private JTextField username, titleField;
+ private JPasswordField password;
+ private JButton signIn, signUp, make, send, backList,backList2;
+ private JScrollPane TablePane, textViewPane, textEditPane,postHeaderPane;
+ private JTable table;
+ private JTextArea view, write;
+ private DefaultTableModel tb;
+ private ServerConnection server;
+ private PostList PL;
+ private Post CP;
+ public Window() throws IOException {
+ initComponents();
+ server= new ServerConnection(this);
+ PL=null;
+ }
+ public void initComponents(){
+
+ auth=new JPanel();
+ labelUsername= new JLabel("Username");
+ labelPassword=new JLabel("Password");
+ username = new JTextField(15);
+ password = new JPasswordField(15);
+ signIn=new JButton("Sign In");
+ signUp=new JButton("Sign Up");
+ auth.setLayout(new GridLayout(3,2));
+
+
+ auth.add(labelUsername);
+ auth.add(username);
+
+ auth.add(labelPassword);
+ auth.add(password);
+
+ auth.add(signIn);
+
+ auth.add(signUp);
+
+
+ list=new JPanel();
+ Object[][] data = {};
+ String[] columnNames = {"User","Title","Date"};
+ tb=new DefaultTableModel(data,columnNames);
+ table = new JTable(tb);
+ TablePane= new JScrollPane(table);
+ make=new JButton("Write");
+
+ list.setLayout(new GridLayout(2,1));
+
+ list.add(TablePane);
+ list.add(make);
+
+ send= new JButton("Send");
+
+ this.setLayout(new FlowLayout());
+ //this.add(list,new GridBagConstraints());
+ viewOne= new JPanel();
+ view= new JTextArea(15,50);
+ backList2= new JButton("Back To list");
+ textViewPane= new JScrollPane(view);
+ postHeader=new JLabel("Title, details");
+ postHeaderPane=new JScrollPane(postHeader, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ viewOne.setLayout(new GridLayout(3,1));
+
+ viewOne.add(postHeaderPane);
+ viewOne.add(textViewPane);
+ viewOne.add(backList2);
+
+ mine=new JPanel();
+ titleField=new JTextField(15);
+ titleField.setForeground(Color.GRAY);
+ titleField.setText("Title");
+ titleField.setForeground(Color.GRAY);
+ titleField.addFocusListener(new FocusListener() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ if (titleField.getText().equals("Title")) {
+ titleField.setText("");
+ titleField.setForeground(Color.BLACK);
+ }
+ }
+ @Override
+ public void focusLost(FocusEvent e) {
+ if (titleField.getText().isEmpty()) {
+ titleField.setForeground(Color.GRAY);
+ titleField.setText("Title");
+ }
+ }
+ });
+ write=new JTextArea(15,50);
+ write.setForeground(Color.GRAY);
+ write.setText("Body");
+ write.setForeground(Color.GRAY);
+ write.addFocusListener(new FocusListener() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ if (write.getText().equals("Body")) {
+ write.setText("");
+ write.setForeground(Color.BLACK);
+ }
+ }
+ @Override
+ public void focusLost(FocusEvent e) {
+ if (write.getText().isEmpty()) {
+ write.setForeground(Color.GRAY);
+ write.setText("Body");
+ }
+ }
+ });
+
+ textEditPane= new JScrollPane(write);
+
+ backList= new JButton("Back To list");
+ mine.setLayout(new GridLayout(4,1));
+ mine.add(titleField);
+ mine.add(textEditPane);
+ mine.add(send);
+ mine.add(backList);
+
+
+ signIn.addActionListener(this);
+ signUp.addActionListener(this);
+ make.addActionListener(this);
+ backList.addActionListener(this);
+ backList2.addActionListener(this);
+ send.addActionListener(this);
+
+ this.add(auth);
+ this.add(list);
+ this.add(viewOne);
+ this.add(mine);
+ list.setVisible(false);
+ viewOne.setVisible(false);
+ mine.setVisible(false);
+ //this.add(auth,new GridBagConstraints());
+ table.getSelectionModel().addListSelectionListener(new ListSelectionListener(){
+ public void valueChanged(ListSelectionEvent event) {
+ // do some actions here, for example
+ // print first column value from selected row
+ CP=server.fetchPostBodyIfEmpty(PL,table.getSelectedRow());
+ if (CP!= null) {
+
+
+ postHeader.setText(CP.getTitle() + ", written by " + CP.getAuthor() + " at " + CP.getDate());
+ view.setText(CP.getBody());
+ list.setVisible(false);
+ viewOne.setVisible(true);
+ }
+ }
+ });
+ }
+ public static void main(String args[]) throws IOException {
+ Window window= new Window();
+ window.setSize(600,1000);
+ window.setTitle("WallPost");
+ window.setVisible(true);
+ }
+
+ public void updateTable(PostList a) {
+ tb.setRowCount(0);//Imposta il numero di righe a 0 eliminando tutte le righe presenti
+ for (int i = 0; i < a.size(); i++) {
+ Object[] row = {a.get(i).getAuthor(),a.get(i).getTitle(), a.get(i).getDate()};//Crea riga temporanea
+ tb.addRow(row);//aggiungi riga
+ }
+ }
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if(e.getSource().equals(signIn)){
+ if(server.signIn(username.getText(),new String(password.getPassword()))) {
+ PL=server.fetchPostsFromServer();
+ this.updateTable(PL);
+ auth.setVisible(false);
+ list.setVisible(true);
+ }
+ else{
+ JOptionPane.showMessageDialog(this,
+ "Wrong credentials",
+ "Cannot sign in",
+ JOptionPane.WARNING_MESSAGE);
+ }
+ }
+ else if(e.getSource().equals(signUp)){
+ if(server.signUp(username.getText(),new String(password.getPassword()))) {
+ updt();
+ auth.setVisible(false);
+ list.setVisible(true);
+ }
+ else{
+ JOptionPane.showMessageDialog(this,
+ "User Taken",
+ "Cannot sign up",
+ JOptionPane.WARNING_MESSAGE);
+ }
+ }
+ else if(e.getSource().equals(make)){
+ list.setVisible(false);
+ mine.setVisible(true);
+ }
+ else if(e.getSource().equals(backList)||e.getSource().equals(backList2)){
+ updt();
+ viewOne.setVisible(false);
+ mine.setVisible(false);
+ list.setVisible(true);
+ }
+ else if(e.getSource().equals(send)){
+ server.publishPost(titleField.getText(),write.getText());
+ updt();
+ mine.setVisible(false);
+ list.setVisible(true);
+ }
+ }
+
+ public void updt(){
+ PL=server.fetchPostsFromServer();
+ this.updateTable(PL);
+ }
+}
+
diff --git a/WallPostServer/WallPostServer.iml b/WallPostServer/WallPostServer.iml
new file mode 100644
index 0000000..c90834f
--- /dev/null
+++ b/WallPostServer/WallPostServer.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/WallPostServer/out/artifacts/WallPostServer_jar/WallPostServer.jar b/WallPostServer/out/artifacts/WallPostServer_jar/WallPostServer.jar
new file mode 100644
index 0000000000000000000000000000000000000000..c251101f50703bf426d2537930d357a2677ed159
GIT binary patch
literal 10052
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
literal 0
HcmV?d00001
diff --git a/WallPostServer/out/production/WallPostServer/META-INF/MANIFEST.MF b/WallPostServer/out/production/WallPostServer/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..836f72b
--- /dev/null
+++ b/WallPostServer/out/production/WallPostServer/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: WallPostServer
+
diff --git a/WallPostServer/src/HeaderNotFoundException.java b/WallPostServer/src/HeaderNotFoundException.java
new file mode 100644
index 0000000..07c7fa6
--- /dev/null
+++ b/WallPostServer/src/HeaderNotFoundException.java
@@ -0,0 +1,5 @@
+public class HeaderNotFoundException extends Exception{
+ public HeaderNotFoundException(){
+ super("Header not found");
+ }
+}
diff --git a/WallPostServer/src/META-INF/MANIFEST.MF b/WallPostServer/src/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..836f72b
--- /dev/null
+++ b/WallPostServer/src/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: WallPostServer
+
diff --git a/WallPostServer/src/PermanentSorage.java b/WallPostServer/src/PermanentSorage.java
new file mode 100644
index 0000000..0a20b1e
--- /dev/null
+++ b/WallPostServer/src/PermanentSorage.java
@@ -0,0 +1,73 @@
+import java.io.*;
+import java.net.Socket;
+import java.util.ArrayList;
+
+public class PermanentSorage extends Thread{
+ public UserList getUList() {
+ return UList;
+ }
+
+ public PostList getPList() {
+ return PList;
+ }
+
+ private UserList UList;
+ private PostList PList;
+ private FileInputStream FIn=null;
+ private ObjectInputStream ObjIn=null;
+ private boolean firstTime;
+ public PermanentSorage(UserList UList, PostList PList) {
+ this.UList=UList;
+ this.PList=PList;
+ try {
+ File f = new File("SAVE.DAT");
+ if(!f.exists()) {
+ this.firstTime= f.createNewFile();
+ }
+ else {
+ FIn = new FileInputStream(f);
+ ObjIn = new ObjectInputStream(FIn);
+ }
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ public void loadFromDisk(){
+ try {
+ if(!firstTime) {
+ SaveContainer c = (SaveContainer) ObjIn.readObject();
+ this.UList = c.getUl();
+ this.PList = c.getPl();
+ ObjIn.close();
+ FIn.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void run(){
+ while(true) {
+ try {
+ System.out.println("STARTING SAVE");
+ FileOutputStream FOut= new FileOutputStream(new File("SAVE.DAT"));
+ ObjectOutputStream ObjOut= new ObjectOutputStream(FOut);
+ ObjOut.writeObject(new SaveContainer(UList,PList));
+ FOut.close();
+ Thread.sleep(60000);//10 sec
+ System.out.println("END SAVE");
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+ }
+}
diff --git a/WallPostServer/src/Post.java b/WallPostServer/src/Post.java
new file mode 100644
index 0000000..8b6e65f
--- /dev/null
+++ b/WallPostServer/src/Post.java
@@ -0,0 +1,37 @@
+import java.io.Serializable;
+
+public class Post implements Serializable {
+ public String getTitle() {
+ return title;
+ }
+
+ public String getBody() {
+ return body;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public String getDate() {
+ return date;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ private String title, body,author, date;
+ private int id;
+ public void setBody(String body) {
+ this.body = body;
+ }
+
+ public Post(String title, String body, String author, String date, int id){
+ this.title=title;
+ this.body=body;
+ this.author=author;
+ this.date=date;
+ this.id=id;
+ }
+}
diff --git a/WallPostServer/src/PostList.java b/WallPostServer/src/PostList.java
new file mode 100644
index 0000000..34b1453
--- /dev/null
+++ b/WallPostServer/src/PostList.java
@@ -0,0 +1,18 @@
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Random;
+
+public class PostList extends ArrayList implements Serializable {
+ public int getNewId(){
+ int u;
+ Random r = new Random();
+ u=r.nextInt();
+ for(int i=0;i headers, values;
+ public ServerThread(Socket clientSocket,UserList UList,PostList PList) {
+ this.socket = clientSocket;
+ this.UList=UList;
+ this.PList=PList;
+ }
+ /*
+
+ ERROR
+ TITLE
+ END
+ TEXT
+ END
+ END
+ END
+
+
+ ERROR
+ TITLE
+ END
+ TEXT
+ END
+ QUIT
+ QUIT
+
+ */
+ private String sanitize(String a){
+ return a.replaceAll("FOLLOWS","follows").replaceAll("END","END");
+ }
+ private synchronized UserList accessUserList(){
+ return this.UList;
+ }
+ private synchronized PostList accessPostList(){
+ return this.PList;
+ }
+ public String valueByHeader(String header) throws HeaderNotFoundException {
+ for(int i=0;i();
+ values= new ArrayList();
+ while (true) {
+ try {
+ line = in.readLine();
+ if ((line == null) || line.equalsIgnoreCase("QUIT")) {
+ socket.close();
+ return;
+ } else {
+ if(line.startsWith("ACTION")) {
+ headers.clear();
+ values.clear();
+ action=line.split(" ", 2)[1];
+ while(!line.equals("END")){
+ if(line.startsWith("FOLLOWS")){
+ headers.add(line.split(" ", 2)[1]);
+ }
+ else{
+ if(!line.startsWith("ACTION")) {
+ values.add(line);
+ }
+ }
+ line=in.readLine();
+ }
+ }
+ if(line.equals("END")){
+ if(action.equals("signIn")){
+ UserList u=accessUserList();
+ boolean access= u.signIn(new User(valueByHeader("username"),valueByHeader("password")));
+ out.writeBytes("OK\n");
+ out.writeBytes("FOLLOWS status\n");
+ if(access){
+ out.writeBytes("OK\n");
+ out.writeBytes("END\n");
+ name=valueByHeader("username");
+ }
+ else{
+ out.writeBytes("NO\n");
+ out.writeBytes("END\n");
+
+ }
+ }
+ else if(action.equals("signUp")){
+ UserList u=accessUserList();
+ boolean access= u.signUp(new User(valueByHeader("username"),valueByHeader("password")));
+ out.writeBytes("OK\n");
+ out.writeBytes("FOLLOWS status\n");
+ if(access){
+ out.writeBytes("OK\n");
+ out.writeBytes("END\n");
+ name=valueByHeader("username");
+ }
+ else{
+ out.writeBytes("NO\n");
+ out.writeBytes("END\n");
+
+ }
+ }
+ else if(name.equals("DEFAULT")){
+ out.writeBytes("ERROR\n" +
+ "Authentication Error\n" +
+ "END\n" +
+ "You must log in" +
+ "END\n" +
+ "QUIT\n" +
+ "QUIT\n");
+ }
+ else if(action.equals("listPosts")){
+
+ PostList p= accessPostList();
+ out.writeBytes("OK\n");
+ for(int i=0;i implements Serializable{
+ public boolean signUp(User a){
+ for(int i=0;i