Files
VisualSapfor/src/Repository/RepositoryServer.java
2024-10-07 22:04:09 +03:00

380 lines
19 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package Repository;
import Common.Utils.CommonUtils;
import Common_old.Constants;
import Common.Database.Objects.DBObject;
import Common.Database.Database;
import _VisualDVM.Global;
import Common.Utils.InterruptThread;
import Common_old.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,
() -> {
System.exit(0);
return null;
});
protected static void Print(String message) {
if (printOn) {
try {
Log = new FileWriter("Log.txt", true);
String dmessage = CommonUtils.Brackets("SESSION -> ") + new Date() +
" " + message;
Log.write(dmessage + "\n");
Log.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
protected void checkTargets(EmailMessage message_in) {
}
public void Email(EmailMessage message_in, File... directAttachements) throws Exception {
checkTargets(message_in);
Thread thread = new Thread(() -> {
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);
CommonUtils.bytesToFile(message_in.files.get(aName), f);
innerFiles.put(aName, f);
}
Vector<String> targets_ = new Vector<>(message_in.targets);
Utils.addDefaultMails(targets_);
//------------------------------
Session session = Session.getDefaultInstance(props,
new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
Constants.MailAddress,
Constants.MailPassword);
}
});
for (String target : targets_) {
boolean done = false;
int attempts = 5;
while (!done && (attempts > 0)) {
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) {
if (f.exists()) {
MimeBodyPart attachmentBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(f);
attachmentBodyPart.setDataHandler(new DataHandler(source));
attachmentBodyPart.setFileName(f.getName());
multipart.addBodyPart(attachmentBodyPart);
}
}
message.setContent(multipart);
Transport.send(message);
done = true;
} catch (Exception ex) {
System.out.println("Исключение во время отправки сообщения абоненту " + CommonUtils.Brackets(target));
ex.printStackTrace();
Utils.sleep(1000);
} finally {
attempts--;
}
}
}
} catch (Exception ex) {
System.out.println("Исключение во время выполнения рассылки.");
ex.printStackTrace();
}
});
thread.start();
}
public boolean canDelete(DBObject object) throws Exception {
return true;
}
public void StartAction() throws Exception {
}
public void Start() throws Exception {
/*
File started = new File(Constants.STARTED);
if (started.exists())
FileUtils.forceDelete(started);
Utils.createEmptyFile(Constants.STARTED);
*/
DiagnosticSignalHandler.install("TERM", signalHandler);
DiagnosticSignalHandler.install("INT", signalHandler);
DiagnosticSignalHandler.install("ABRT", signalHandler);
interruptThread.start();
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("Отправить клиенту текст файла по пути " + CommonUtils.Brackets(request.arg));
response = new ServerExchangeUnit_2021(ServerCode.OK, "", Utils.ReadAllText(new File(request.arg)));
break;
case SendFile:
//нам пришел файл.
Print("Получить от клиента файл, и распаковать его по пути " + CommonUtils.Brackets(request.arg));
request.Unpack(); //распаковка идет по его аргу-пути назначения
response = new ServerExchangeUnit_2021(ServerCode.OK);
break;
case ReceiveFile:
Print("Отправить клиенту файл по пути " + CommonUtils.Brackets(request.arg));
response = new ServerExchangeUnit_2021(ServerCode.OK);
File file = new File(request.arg);
response.object = file.exists() ? CommonUtils.fileToBytes(file) : null;
break;
case Email:
Print("Отправка сообщения электронной почты");
Email((EmailMessage) request.object);
response = new ServerExchangeUnit_2021(ServerCode.OK);
break;
//</editor-fold>
//<editor-fold desc="Главная база данных">
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 EditObject:
DBObject new_object = (DBObject) request.object;
Print("Редактировать объект " + new_object.getPK());
db.UpdateWithCheck(new_object);
afterEditAction(new_object);
response = new ServerExchangeUnit_2021(ServerCode.OK);
break;
case DeleteObject: //устарело. потом убрать. сейчас на это баг репорты повязаны.
dbObject = (DBObject) request.object;
Print("Удалить объект " + dbObject.getPK());
db.DeleteWithCheck(dbObject);
afterDeleteAction(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;
case GetObjectsCopiesByPK:
Print("Получить список копий объектов по ключам");
p = (Pair<Class, Object>) request.object;
response = new ServerExchangeUnit_2021(ServerCode.OK);
response.object = db.getObjectsCopies(p.getKey(), (Vector<Object>) p.getValue());
break;
case PublishObject:
PublishObject();
break;
case PublishObjects:
PublishObjects();
break;
case DeleteObjectByPK:
DeleteObjectByPK();
break;
case DeleteObjectsByPK:
DeleteObjectsByPK();
break;
//</editor-fold>
case EXIT:
Print("ЗАВЕРШИТЬ РАБОТУ СЕРВЕРА");
System.exit(0);
break;
case Ping:
Print("Проверка активности сервера");
Ping();
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("Сервер ждет следующего клиента.");
}
}
}
//--
protected Database getDefaultDatabase() {
return db;
}
//--
private void PublishObject() throws Exception {
response = new ServerExchangeUnit_2021(ServerCode.OK);
DBObject dbObject = (DBObject) request.object;
beforePublishAction(dbObject);
response.object = (Serializable) getDefaultDatabase().InsertS(dbObject).getPK();
afterPublishAction(dbObject);
}
private void PublishObjects() throws Exception {
response = new ServerExchangeUnit_2021(ServerCode.OK);
Vector<DBObject> objects = (Vector<DBObject>) request.object;
Database database = getDefaultDatabase();
for (DBObject dbObject : objects) {
beforePublishAction(dbObject);
response.object = (Serializable) database.InsertS(dbObject).getPK();
afterPublishAction(dbObject);
}
}
protected void beforePublishAction(DBObject object) throws Exception {
}
protected void afterPublishAction(DBObject object) throws Exception {
}
protected void afterEditAction(DBObject object) throws Exception {
}
//------------------------------
private void DeleteObjectByPK() throws Exception {
Print("Удалить объект по ключу");
Pair<Class, Object> to_delete = (Pair<Class, Object>) request.object;
afterDeleteAction(getDefaultDatabase().DeleteByPK(to_delete.getKey(), to_delete.getValue()));
response = new ServerExchangeUnit_2021(ServerCode.OK);
}
private void DeleteObjectsByPK() throws Exception {
Print("Удалить объекты по ключам");
Pair<Class, Vector<Object>> to_delete = (Pair<Class, Vector<Object>>) request.object;
Database database = getDefaultDatabase();
for (Object object : to_delete.getValue()) {
afterDeleteAction(database.DeleteByPK(to_delete.getKey(), object));
}
response = new ServerExchangeUnit_2021(ServerCode.OK);
}
public void afterDeleteAction(DBObject object) throws Exception {
}
public void Ping() {
response = new ServerExchangeUnit_2021(ServerCode.OK);
}
}