2023-09-17 22:13:42 +03:00
|
|
|
|
package Repository;
|
2023-10-14 00:43:39 +03:00
|
|
|
|
import Common.Constants;
|
2023-09-17 22:13:42 +03:00
|
|
|
|
import Common.Database.DBObject;
|
|
|
|
|
|
import Common.Database.Database;
|
|
|
|
|
|
import Common.Database.rDBObject;
|
|
|
|
|
|
import Common.Global;
|
|
|
|
|
|
import Common.Utils.InterruptThread;
|
|
|
|
|
|
import Common.Utils.Utils;
|
|
|
|
|
|
import Repository.Server.DiagnosticSignalHandler;
|
|
|
|
|
|
import Repository.Server.ServerCode;
|
|
|
|
|
|
import Repository.Server.ServerExchangeUnit_2021;
|
|
|
|
|
|
import javafx.util.Pair;
|
|
|
|
|
|
import sun.misc.SignalHandler;
|
|
|
|
|
|
|
|
|
|
|
|
import javax.activation.DataHandler;
|
|
|
|
|
|
import javax.activation.DataSource;
|
|
|
|
|
|
import javax.activation.FileDataSource;
|
|
|
|
|
|
import javax.mail.*;
|
|
|
|
|
|
import javax.mail.internet.InternetAddress;
|
|
|
|
|
|
import javax.mail.internet.MimeBodyPart;
|
|
|
|
|
|
import javax.mail.internet.MimeMessage;
|
|
|
|
|
|
import javax.mail.internet.MimeMultipart;
|
|
|
|
|
|
import java.io.*;
|
|
|
|
|
|
import java.net.ServerSocket;
|
|
|
|
|
|
import java.net.Socket;
|
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
|
import java.util.LinkedHashMap;
|
|
|
|
|
|
import java.util.Properties;
|
|
|
|
|
|
import java.util.Vector;
|
|
|
|
|
|
public abstract class RepositoryServer<D extends Database> {
|
|
|
|
|
|
Class<D> d_class;
|
|
|
|
|
|
protected Socket clientSocket; //сокет для общения
|
|
|
|
|
|
protected ServerSocket server; // серверсокет
|
|
|
|
|
|
protected ObjectInputStream in; // поток чтения из сокета
|
|
|
|
|
|
protected ObjectOutputStream out; // поток записи в сокет
|
|
|
|
|
|
//-
|
|
|
|
|
|
public D db;
|
|
|
|
|
|
protected static FileWriter Log;
|
|
|
|
|
|
protected ServerExchangeUnit_2021 request;
|
|
|
|
|
|
protected ServerExchangeUnit_2021 response;
|
|
|
|
|
|
//-
|
|
|
|
|
|
protected ServerCode code;
|
|
|
|
|
|
protected long count = 0; //для отладки.
|
|
|
|
|
|
protected static boolean printOn = false;
|
|
|
|
|
|
//-----------
|
|
|
|
|
|
SignalHandler signalHandler = signal -> {
|
|
|
|
|
|
};
|
|
|
|
|
|
//------------
|
|
|
|
|
|
public abstract int getPort();
|
|
|
|
|
|
protected abstract void Session() throws Exception;
|
|
|
|
|
|
protected void startAdditionalThreads() {
|
|
|
|
|
|
}
|
|
|
|
|
|
public final static String separator = "----------------------------------";
|
|
|
|
|
|
public RepositoryServer(Class<D> d_class_in) {
|
|
|
|
|
|
d_class = d_class_in;
|
|
|
|
|
|
}
|
|
|
|
|
|
public void ActivateDB() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
db = d_class.newInstance();
|
|
|
|
|
|
db.Connect();
|
|
|
|
|
|
db.CreateAllTables();
|
|
|
|
|
|
db.prepareTablesStatements();
|
|
|
|
|
|
db.Synchronize();
|
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
protected Thread interruptThread = new InterruptThread(10000,
|
|
|
|
|
|
() -> {
|
2023-10-09 22:51:54 +03:00
|
|
|
|
System.out.println("INTERRUPT FILE FOUND");
|
2023-09-17 22:13:42 +03:00
|
|
|
|
System.exit(0);
|
|
|
|
|
|
return null;
|
|
|
|
|
|
});
|
|
|
|
|
|
protected static void Print(String message) throws IOException {
|
|
|
|
|
|
if (printOn) {
|
|
|
|
|
|
Log = new FileWriter("Log.txt", true);
|
|
|
|
|
|
String dmessage = Utils.Brackets("SESSION -> ") + new Date() +
|
|
|
|
|
|
" " + message;
|
|
|
|
|
|
System.out.println(dmessage);
|
|
|
|
|
|
Log.write(dmessage + "\n");
|
|
|
|
|
|
Log.close();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public void Email(EmailMessage message_in, File... directAttachements) throws Exception {
|
2023-11-07 19:28:38 +03:00
|
|
|
|
Thread thread = new Thread(() -> {
|
|
|
|
|
|
System.out.println("EMAIL THREAD STARTED");
|
|
|
|
|
|
try {
|
|
|
|
|
|
Properties props = new Properties();
|
|
|
|
|
|
props.put("mail.smtp.host", Global.properties.SMTPHost);
|
|
|
|
|
|
props.put("mail.smtp.auth", "true");
|
|
|
|
|
|
props.put("mail.smtp.port", String.valueOf(Global.properties.SMTPPort));
|
|
|
|
|
|
props.put("mail.smtp.socketFactory.port", String.valueOf(Global.properties.MailSocketPort));
|
|
|
|
|
|
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
|
|
|
|
|
|
props.put("mail.smtp.connectiontimeout", String.valueOf(Global.properties.SocketTimeout));
|
|
|
|
|
|
props.put("mail.smtp.timeout", String.valueOf(Global.properties.SocketTimeout));
|
|
|
|
|
|
props.put("mail.smtp.writetimeout", String.valueOf(Global.properties.SocketTimeout));
|
|
|
|
|
|
//------------------------------
|
|
|
|
|
|
LinkedHashMap<String, File> innerFiles = new LinkedHashMap<>();
|
|
|
|
|
|
for (String aName : message_in.files.keySet()) {
|
|
|
|
|
|
File f = Utils.getTempFileName(aName);
|
|
|
|
|
|
Utils.unpackFile(message_in.files.get(aName), f);
|
|
|
|
|
|
innerFiles.put(aName, f);
|
2023-09-17 22:13:42 +03:00
|
|
|
|
}
|
2023-11-07 19:28:38 +03:00
|
|
|
|
Vector<String> targets_ = new Vector<>();
|
|
|
|
|
|
targets_.add(Constants.MailAddress); //себе.
|
|
|
|
|
|
targets_.addAll(message_in.targets);
|
|
|
|
|
|
//------------------------------
|
|
|
|
|
|
Session session = Session.getDefaultInstance(props,
|
|
|
|
|
|
new Authenticator() {
|
|
|
|
|
|
@Override
|
|
|
|
|
|
protected PasswordAuthentication getPasswordAuthentication() {
|
|
|
|
|
|
return new PasswordAuthentication(
|
|
|
|
|
|
Constants.MailAddress,
|
|
|
|
|
|
Constants.MailPassword);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
for (String target : targets_) {
|
|
|
|
|
|
System.out.println("target=" + target);
|
|
|
|
|
|
if (needsEmail(target)) {
|
|
|
|
|
|
System.out.println("needs email");
|
|
|
|
|
|
try {
|
|
|
|
|
|
MimeMessage message = new MimeMessage(session);
|
|
|
|
|
|
message.setFrom(new InternetAddress(Constants.MailAddress));
|
|
|
|
|
|
message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(target));
|
|
|
|
|
|
message.setSubject(message_in.subject);
|
|
|
|
|
|
Multipart multipart = new MimeMultipart();
|
|
|
|
|
|
MimeBodyPart textBodyPart = new MimeBodyPart();
|
|
|
|
|
|
textBodyPart.setText(message_in.text);
|
|
|
|
|
|
multipart.addBodyPart(textBodyPart);
|
|
|
|
|
|
for (String aName : innerFiles.keySet()) {
|
|
|
|
|
|
MimeBodyPart attachmentBodyPart = new MimeBodyPart();
|
|
|
|
|
|
DataSource source = new FileDataSource(innerFiles.get(aName));
|
|
|
|
|
|
attachmentBodyPart.setDataHandler(new DataHandler(source));
|
|
|
|
|
|
attachmentBodyPart.setFileName(aName);
|
|
|
|
|
|
multipart.addBodyPart(attachmentBodyPart);
|
|
|
|
|
|
}
|
|
|
|
|
|
for (File f : directAttachements) {
|
2023-11-14 00:56:05 +03:00
|
|
|
|
if (f.exists()) {
|
|
|
|
|
|
MimeBodyPart attachmentBodyPart = new MimeBodyPart();
|
|
|
|
|
|
DataSource source = new FileDataSource(f);
|
|
|
|
|
|
attachmentBodyPart.setDataHandler(new DataHandler(source));
|
|
|
|
|
|
attachmentBodyPart.setFileName(f.getName());
|
|
|
|
|
|
multipart.addBodyPart(attachmentBodyPart);
|
|
|
|
|
|
}
|
2023-11-07 19:28:38 +03:00
|
|
|
|
}
|
|
|
|
|
|
message.setContent(multipart);
|
|
|
|
|
|
Transport.send(message);
|
|
|
|
|
|
System.out.println("message sent");
|
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
|
System.out.println("Исключение во время отправки сообщения абоненту " + Utils.Brackets(target));
|
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
|
}
|
|
|
|
|
|
} else System.out.println("does not need email");
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
|
System.out.println("Исключение во время выполнения рассылки.");
|
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
|
}
|
|
|
|
|
|
System.out.println("EMAIL THREAD ENDED");
|
|
|
|
|
|
});
|
|
|
|
|
|
thread.start();
|
2023-09-17 22:13:42 +03:00
|
|
|
|
}
|
2023-10-09 22:51:54 +03:00
|
|
|
|
public boolean needsEmail(String email) {
|
2023-09-17 22:13:42 +03:00
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
public void PublishAction(DBObject object) throws Exception {
|
|
|
|
|
|
}
|
|
|
|
|
|
public boolean canDelete(DBObject object) throws Exception {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
public void DeleteAction(DBObject object) throws Exception {
|
|
|
|
|
|
}
|
|
|
|
|
|
public void StartAction() throws Exception {
|
|
|
|
|
|
}
|
|
|
|
|
|
public void Start() throws Exception {
|
|
|
|
|
|
DiagnosticSignalHandler.install("TERM", signalHandler);
|
|
|
|
|
|
DiagnosticSignalHandler.install("INT", signalHandler);
|
|
|
|
|
|
DiagnosticSignalHandler.install("ABRT", signalHandler);
|
|
|
|
|
|
interruptThread.start();
|
|
|
|
|
|
if (!Global.properties.OldServer)
|
|
|
|
|
|
startAdditionalThreads();
|
|
|
|
|
|
server = new ServerSocket(getPort());
|
|
|
|
|
|
Print("Сервер запущен!");
|
|
|
|
|
|
StartAction();
|
|
|
|
|
|
while (true) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
clientSocket = server.accept();
|
|
|
|
|
|
Print((count++) + " клиент присоединился, IP=" + clientSocket.getInetAddress());
|
|
|
|
|
|
code = ServerCode.Undefined;
|
|
|
|
|
|
out = new ObjectOutputStream(clientSocket.getOutputStream());
|
|
|
|
|
|
in = new ObjectInputStream(clientSocket.getInputStream());
|
|
|
|
|
|
//->
|
|
|
|
|
|
while (true) {
|
|
|
|
|
|
DBObject dbObject = null;
|
|
|
|
|
|
Pair<Class, Object> p = null;
|
|
|
|
|
|
Print("Ожидание команды от клиента...");
|
|
|
|
|
|
Object transport = in.readObject();
|
|
|
|
|
|
Print("Команда прочитана.");
|
|
|
|
|
|
if (transport instanceof ServerExchangeUnit_2021) {
|
|
|
|
|
|
request = (ServerExchangeUnit_2021) transport;
|
|
|
|
|
|
response = null;
|
|
|
|
|
|
Print("клиент_2021: <- " + (request.codeName));
|
|
|
|
|
|
try {
|
|
|
|
|
|
code = request.getCode();
|
|
|
|
|
|
//базовый функционал.
|
|
|
|
|
|
switch (code) {
|
|
|
|
|
|
//<editor-fold desc="БАЗОВЫЕ">
|
|
|
|
|
|
case ReadFile:
|
|
|
|
|
|
Print("Отправить клиенту текст файла по пути " + Utils.Brackets(request.arg));
|
|
|
|
|
|
response = new ServerExchangeUnit_2021(ServerCode.OK, "", Utils.ReadAllText(new File(request.arg)));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case SendFile:
|
|
|
|
|
|
//нам пришел файл.
|
|
|
|
|
|
Print("Получить от клиента файл, и распаковать его по пути " + Utils.Brackets(request.arg));
|
|
|
|
|
|
request.Unpack(); //распаковка идет по его аргу-пути назначения
|
|
|
|
|
|
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ReceiveFile:
|
|
|
|
|
|
Print("Отправить клиенту файл по пути " + Utils.Brackets(request.arg));
|
|
|
|
|
|
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
|
|
|
|
|
File file = new File(request.arg);
|
|
|
|
|
|
response.object = file.exists() ? Utils.packFile(file) : null;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case Email:
|
|
|
|
|
|
Print("Отправка сообщения электронной почты");
|
|
|
|
|
|
Email((EmailMessage) request.object);
|
|
|
|
|
|
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
|
|
|
|
|
break;
|
|
|
|
|
|
//</editor-fold>
|
|
|
|
|
|
case PublishObject:
|
|
|
|
|
|
dbObject = (DBObject) request.object;
|
|
|
|
|
|
Print("Опубликовать объект " + dbObject.getPK());
|
|
|
|
|
|
db.InsertWithCheck(dbObject);
|
|
|
|
|
|
PublishAction(dbObject);
|
|
|
|
|
|
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case CheckObjectExistense:
|
|
|
|
|
|
p = (Pair<Class, Object>) request.object;
|
|
|
|
|
|
Print("Проверить существование объекта класса " + p.getKey().toString() + " с ключом " + p.getValue());
|
|
|
|
|
|
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
|
|
|
|
|
response.object = db.checkObjectExistense(p.getKey(), p.getValue());
|
|
|
|
|
|
break;
|
|
|
|
|
|
case CopyObjects:
|
|
|
|
|
|
String[] data = request.arg.split("\n");
|
|
|
|
|
|
String sender_name = data[0];
|
|
|
|
|
|
String sender_address = data[1];
|
|
|
|
|
|
Print("Дублировать объекты для пользователя " + sender_name + ":" + sender_address);
|
|
|
|
|
|
Vector<Object> src = (Vector<Object>) request.object;
|
|
|
|
|
|
Vector<Object> dst = new Vector<>();
|
|
|
|
|
|
for (Object object : src) {
|
|
|
|
|
|
if (object instanceof rDBObject) {
|
|
|
|
|
|
rDBObject copy = (rDBObject) object.getClass().newInstance();
|
|
|
|
|
|
copy.SynchronizeFields((rDBObject) object);
|
|
|
|
|
|
copy.genName();
|
|
|
|
|
|
copy.sender_name = sender_name;
|
|
|
|
|
|
copy.sender_address = sender_address;
|
|
|
|
|
|
CopyAction((rDBObject) object, copy);
|
|
|
|
|
|
dst.add(copy);
|
|
|
|
|
|
db.Insert(copy);
|
|
|
|
|
|
} else
|
|
|
|
|
|
throw new RepositoryRefuseException("Поддерживается дублирование только объектов типа rDBObject");
|
|
|
|
|
|
}
|
|
|
|
|
|
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
|
|
|
|
|
response.object = dst;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case EditObject:
|
|
|
|
|
|
DBObject new_object = (DBObject) request.object;
|
|
|
|
|
|
Print("Редактировать объект " + new_object.getPK());
|
|
|
|
|
|
db.UpdateWithCheck(new_object);
|
|
|
|
|
|
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DeleteObject:
|
|
|
|
|
|
dbObject = (DBObject) request.object;
|
|
|
|
|
|
Print("Удалить объект " + dbObject.getPK());
|
|
|
|
|
|
db.DeleteWithCheck(dbObject);
|
|
|
|
|
|
DeleteAction(dbObject);
|
|
|
|
|
|
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GetObjectCopyByPK:
|
|
|
|
|
|
p = (Pair<Class, Object>) request.object;
|
|
|
|
|
|
Print("Получить копию объекта класса " + p.getKey().toString() + " по ключу " + p.getValue());
|
|
|
|
|
|
dbObject = db.getObjectCopyByPK(p.getKey(), p.getValue());
|
|
|
|
|
|
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
|
|
|
|
|
response.object = dbObject;
|
|
|
|
|
|
break;
|
2023-10-15 20:20:07 +03:00
|
|
|
|
case GetObjectsCopiesByPK:
|
2023-10-31 20:59:32 +03:00
|
|
|
|
Print("Получить список копий объектов по ключам");
|
2023-10-15 20:20:07 +03:00
|
|
|
|
p = (Pair<Class, Object>) request.object;
|
|
|
|
|
|
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
|
|
|
|
|
response.object = db.getObjectsCopies(p.getKey(), (Vector<Object>) p.getValue());
|
|
|
|
|
|
break;
|
2023-09-17 22:13:42 +03:00
|
|
|
|
case DeleteObjects:
|
|
|
|
|
|
Print("Удалить список объектов ");
|
|
|
|
|
|
Vector<Object> objects = (Vector<Object>) request.object;
|
|
|
|
|
|
db.BeginTransaction();
|
|
|
|
|
|
for (Object object : objects) {
|
|
|
|
|
|
dbObject = (DBObject) object;
|
|
|
|
|
|
if (canDelete(dbObject)) {
|
|
|
|
|
|
db.DeleteWithCheck(dbObject);
|
|
|
|
|
|
DeleteAction(dbObject);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
db.Commit();
|
|
|
|
|
|
response = new ServerExchangeUnit_2021(ServerCode.OK);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case EXIT:
|
|
|
|
|
|
Print("ЗАВЕРШИТЬ РАБОТУ СЕРВЕРА");
|
|
|
|
|
|
System.exit(0);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
Session();
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
|
response = new ServerExchangeUnit_2021(ServerCode.FAIL, "Исключение сервера", ex);
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
Print("сервер: -> " + response.codeName);
|
|
|
|
|
|
out.writeObject(response);
|
|
|
|
|
|
Print("Ответ отправлен.");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//->
|
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
|
Print("Соединение с клиентом завершено.");
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
//->
|
|
|
|
|
|
try {
|
|
|
|
|
|
if (clientSocket != null)
|
|
|
|
|
|
clientSocket.close();
|
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
|
}
|
|
|
|
|
|
// потоки тоже хорошо бы закрыть
|
|
|
|
|
|
try {
|
|
|
|
|
|
if (in != null)
|
|
|
|
|
|
in.close();
|
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
|
|
|
if (out != null)
|
|
|
|
|
|
out.close();
|
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
|
}
|
|
|
|
|
|
Print("Сервер ждет следующего клиента.");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public void CopyAction(rDBObject src, rDBObject dst) throws Exception {
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|