package su.mauser.router;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.velocity.app.VelocityEngine;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import spark.Request;
import spark.Response;
import spark.Route;
import spark.template.velocity.VelocityRoute;
import su.mauser.interfaces.IDBStatus.DBStatus;
import su.mauser.service.ActorsPageServiceImpl;
import su.mauser.service.InsertActorPageServiceImpl;
import su.mauser.service.ListPageServiceImpl;
import su.mauser.service.MissingPageServiceImpl;
import su.mauser.service.SelectPageServiceImpl;
import com.mongodb.DB;
/**
* Маршрутизатор страниц.
*
* При отсутствии соединения с БД отображает страницу с ошибкой.
*
*/
public class Router
{
private static Logger logger = LoggerFactory.getLogger(Router.class);
private VelocityEngine engine = new VelocityEngine();
private DBStatus connectionStatus;
public Router(DBStatus connectionStatus)
{
this.connectionStatus = connectionStatus;
}
/**
* Начальная страница выбора вариантов работы.
*
* @return Начальная страница.
*/
public VelocityRoute getStartPage()
{
return new EncodingRoute("/", engine)
{
@Override
public Object handle(final Request request, final Response response)
{
if (connectionStatus != DBStatus.CONNECTED)
{
response.redirect("/dberror");
}
logger.debug("Started route to /");
return modelAndView(new HashMap<String, Object>(), "src/main/java/resources/templates/startPage.vm");
}
};
}
/**
* Страница выбранного фильма. Отображает полную информацию с фильмом.
*
* @param db
* БД.
* @return Маршрут к странице с выбранным фильмом.
*/
public VelocityRoute getSelectPage(final DB db)
{
return new EncodingRoute("/select", engine)
{
@Override
public Object handle(Request request, Response response)
{
if (connectionStatus != DBStatus.CONNECTED)
{
response.redirect("/dberror");
}
SelectPageServiceImpl selectPageService = new SelectPageServiceImpl(db);
Map<String, Object> model = new HashMap<String, Object>();
// Если заданы параметры поиска, ищем и возвращаем результат поиска.
if (request.queryParams().size() > 0)
{
model.put("view", selectPageService.getSelectPageViewWithResult(request.queryMap()));
}
else
{
model.put("view", selectPageService.getSelectPageView());
}
logger.debug("Started route to /select");
return modelAndView(model, "src/main/java/resources/templates/selectPage.vm");
}
};
}
/**
* AJAX-запрос для получения информации по фильму.
*
* @param db
* База данных.
* @return Возвращает данные по фильму в формате JSON.
*/
public VelocityRoute getFilmInfo(final DB db)
{
return new JSONRouter("/filminfo")
{
@Override
public Object handle(Request request, Response response)
{
if (connectionStatus != DBStatus.CONNECTED)
{
response.redirect("/dberror");
}
if (request.queryParams().size() > 0 && request.queryMap().get("id").value().length() > 0)
{
ListPageServiceImpl listPageService = new ListPageServiceImpl(db);
JSONObject info = listPageService.getFilmInfo(request.queryMap().get("id").value());
response.header("Access-Control-Allow-Origin", "*");
response.status(200);
return info;
}
return null;
}
};
}
/**
* Получение списка актеров по AJAX. Используется для редактирования данных
* фильма.
*
* @param db
* База данных.
* @return Список актеров: _id-ФИО.
*/
public VelocityRoute getActorsShortList(final DB db)
{
return new JSONRouter("/actorslist")
{
@Override
public Object handle(Request request, Response response)
{
ActorsPageServiceImpl serviceImpl = new ActorsPageServiceImpl(db);
List<JSONObject> actors = serviceImpl.getActors();
response.header("Access-Control-Allow-Origin", "*");
response.status(200);
return actors;
}
};
}
/**
* Список фильмов.
*
* @param db
* БД.
* @return Маршрут к странице со списком фильмов.
*/
public VelocityRoute getListPage(final DB db)
{
return new EncodingRoute("/list", engine)
{
@Override
public Object handle(Request request, Response response)
{
if (connectionStatus != DBStatus.CONNECTED)
{
response.redirect("/dberror");
}
ListPageServiceImpl listPageService = new ListPageServiceImpl(db);
Map<String, Object> model = new HashMap<String, Object>();
model.put("view", listPageService.getFilmsListPageView());
logger.debug("Started route to /list");
return modelAndView(model, "src/main/java/resources/templates/listFilmsPage.vm");
}
};
}
/**
* Справочник по актёрам.
*
* @param db
* Подключение к БД.
* @return Маршрут к странице актёров.
*/
public VelocityRoute getActorsPage(final DB db)
{
return new EncodingRoute("/actors", engine)
{
@Override
public Object handle(Request request, Response response)
{
if (connectionStatus != DBStatus.CONNECTED)
{
response.redirect("/dberror");
}
ActorsPageServiceImpl actorsPageService = new ActorsPageServiceImpl(db);
Map<String, Object> model = new HashMap<String, Object>();
model.put("view", actorsPageService.getActorsPageView());
logger.debug("Started route to /actors");
return modelAndView(model, "src/main/java/resources/templates/actorsPage.vm");
}
};
}
/**
* Маршрут страницы ошибки соединения с базой данных.
*
* @return Страница ошибки соединения с БД.
*/
public VelocityRoute getDBConnectionErrorPage()
{
return new EncodingRoute("/dberror", engine)
{
@Override
public Object handle(Request request, Response response)
{
logger.debug("Started route to /dberror");
return modelAndView(new HashMap<String, Object>(), "src/main/java/resources/templates/errorPage.vm");
}
};
}
/**
* Страница со списком фильмов, которых нет в БД.
*
* @return
*/
public VelocityRoute getMissingPage()
{
return new EncodingRoute("/missing", engine)
{
@Override
public Object handle(Request request, Response response)
{
if (connectionStatus != DBStatus.CONNECTED)
{
response.redirect("/dberror");
}
MissingPageServiceImpl missingPage = new MissingPageServiceImpl();
Map<String, Object> model = new HashMap<String, Object>();
model.put("view", missingPage.getMissingPageView());
logger.debug("Started route to /missing");
return modelAndView(model, "src/main/java/resources/templates/missingPage.vm");
}
};
}
/**
* Редактирование данных фильма и открытие списка фильмов.
*
* @param db
* БД.
* @return Маршрут к редактированию фильма.
*/
public VelocityRoute getEditFilmPage(final DB db)
{
return new JSONRouter("/edit")
{
@Override
public Object handle(Request request, Response response)
{
ListPageServiceImpl listPageService = new ListPageServiceImpl(db);
JSONObject jsonObject = new JSONObject(request.queryParams("newData"));
listPageService.setFilmDatabaseValues(jsonObject);
JSONObject info = listPageService.getFilmInfo(jsonObject.getString("id"));
response.header("Access-Control-Allow-Origin", "*");
response.status(200);
return info;
}
};
}
/**
* Редактирование данных актёра и открытие списка актёров.
*
* @param db
* БД
* @return
*/
public VelocityRoute getEditActorPage(final DB db)
{
return new EncodingRoute("/editactor", engine)
{
@Override
public Object handle(Request request, Response response)
{
if (connectionStatus != DBStatus.CONNECTED)
{
response.redirect("/dberror");
}
ActorsPageServiceImpl actorsPageService = new ActorsPageServiceImpl(db);
actorsPageService.setDatabaseValues(request.queryMap());
response.redirect("/actors");
return null;
}
};
}
/**
* Удаляем выбранный фильм и отображаем снова список фильмов.
*
* @param db
* БД.
* @return Маршрут к странице удаления фильма.
*/
public VelocityRoute getRemovePage(final DB db)
{
return new EncodingRoute("/remove", engine)
{
@Override
public Object handle(Request request, Response response)
{
if (connectionStatus != DBStatus.CONNECTED)
{
response.redirect("/dberror");
}
logger.debug("Started route to /remove");
ListPageServiceImpl listPageService = new ListPageServiceImpl(db);
listPageService.removeMovie(request.queryMap());
response.redirect("/list");
return null;
}
};
}
/**
* Страница вставки актеров.
*
* @param db
* @return
*/
public Route getInsertActorsPage(final DB db)
{
return new EncodingRoute("/insertactors", engine)
{
@Override
public Object handle(Request request, Response response)
{
if (connectionStatus != DBStatus.CONNECTED)
{
response.redirect("/dberror");
}
InsertActorPageServiceImpl insertActorPageService = new InsertActorPageServiceImpl(db);
Map<String, Object> model = new HashMap<String, Object>();
// После заполнения формы - запрос на добавление
// Фамилия актёра - обязательна для ввода
if (request.queryParams().size() > 0 && request.queryMap().get("lname").value().length() > 0)
{
model.put("view", insertActorPageService.insert(request.queryMap()));
}
// Первоначальная форма, до заполнения параметров
else
{
model.put("view", insertActorPageService.getInsertPageView());
}
logger.debug("Started route to /insertactors");
return modelAndView(model, "src/main/java/resources/templates/insertActorPage.vm");
}
};
}
/**
* Удаляем выбранного актёра и отображаем снова список актёров.
*
* @param db
* DataBase instance
* @return
*/
public VelocityRoute getRemoveActor(final DB db)
{
return new EncodingRoute("/removeactor", engine)
{
@Override
public Object handle(Request request, Response response)
{
if (connectionStatus != DBStatus.CONNECTED)
{
response.redirect("/dberror");
}
logger.debug("Started route to /removeactor");
ActorsPageServiceImpl actorsPageServiceImpl = new ActorsPageServiceImpl(db);
actorsPageServiceImpl.removeActor(request.queryMap());
response.redirect("/actors");
return null;
}
};
}
/**
* Добавляем новый фильм в БД. Добавляем только наименование. Остальные
* данные добавляются при редактировании данных.
*
* @param db
* DataBase instance
* @return
*/
public Route getInsertFilmPage(final DB db)
{
return new JSONRouter("/insertfilm")
{
@Override
public Object handle(Request request, Response response)
{
// ListPageServiceImpl listPageService = new ListPageServiceImpl(db);
// JSONObject jsonObject = new JSONObject(request.queryParams("newData"));
//
// listPageService.setFilmDatabaseValues(jsonObject);
//
// JSONObject info = listPageService.getFilmInfo(jsonObject.getString("id"));
response.header("Access-Control-Allow-Origin", "*");
response.status(200);
// return info;
return null;
}
};
}
}