Commit 81be0b1d authored by Riegel's avatar Riegel
Browse files

Merge branch 'dev_GUI' into 'dev'

Open source release of CityDoctorGUI and other extensions.

See merge request !6
parents 12d96d95 5a4d0a74
Pipeline #10056 passed with stage
in 1 minute and 6 seconds
package de.hft.stuttgart.citydoctor2.webservice.endpoints;
import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import javax.persistence.EntityManager;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import de.hft.stuttgart.citydoctor2.datastructure.AbstractBuilding;
import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface;
import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurfaceType;
import de.hft.stuttgart.citydoctor2.datastructure.BoundingBox;
import de.hft.stuttgart.citydoctor2.datastructure.Building;
import de.hft.stuttgart.citydoctor2.datastructure.BuildingPart;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.Installation;
import de.hft.stuttgart.citydoctor2.datastructure.Lod;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.math.Triangle3d;
import de.hft.stuttgart.citydoctor2.math.Vector3d;
import de.hft.stuttgart.citydoctor2.parser.CityGmlConsumer;
import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException;
import de.hft.stuttgart.citydoctor2.parser.CityGmlParser;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.tesselation.TesselatedPolygon;
import de.hft.stuttgart.citydoctor2.webservice.AuthenticationException;
import de.hft.stuttgart.citydoctor2.webservice.database.BuildingQueries;
import de.hft.stuttgart.citydoctor2.webservice.database.ModelQueries;
import de.hft.stuttgart.citydoctor2.webservice.model.BuildingReference;
import de.hft.stuttgart.citydoctor2.webservice.model.BuildingsReturnType;
import de.hft.stuttgart.citydoctor2.webservice.model.ModelReference;
import de.hft.stuttgart.citydoctor2.webservice.model.ParseStatus;
import de.hft.stuttgart.citydoctor2.webservice.model.ValidationReference;
import de.hft.stuttgart.citydoctor2.webservice.model.entities.GmlFile;
import de.hft.stuttgart.citydoctor2.webservice.model.entities.User;
import de.hft.stuttgart.citydoctor2.webservice.model.entities.Validation;
import de.hft.stuttgart.citydoctor2.webservice.model.entities.WebBuilding;
import de.hft.stuttgart.citydoctor2.webservice.model.entities.WebCityDoctorModel;
import de.hft.stuttgart.citydoctor2.webservice.utils.AuthenticationUtils;
import de.hft.stuttgart.citydoctor2.webservice.utils.HibernateUtils;
@Path("models")
public class ModelsEndpoint {
private static final String ERROR_WHILE_RETRIEVING_MODELS = "Error while retrieving models";
private static final String ACCESS_VIOLATION = "User {} tried to access not owned model with id {}";
private static final Logger logger = LogManager.getLogger(ModelsEndpoint.class);
private static final AtomicLong FILE_COUNTER = new AtomicLong(0);
private static final String DIGITS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
private static final int NAME_LENGTH = 40;
private static final Random RANDOM = new Random();
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getModels(@DefaultValue("0") @QueryParam("from") int from, @Context HttpServletRequest request) {
EntityManager manager = null;
try {
manager = HibernateUtils.createManager();
User user = AuthenticationUtils.authenticateUser(request, manager);
if (user == null) {
return Response.status(Status.FORBIDDEN).build();
}
List<ModelReference> models = new ArrayList<>();
for (WebCityDoctorModel webModel : user.getOwnedModels()) {
ModelReference ref = new ModelReference(webModel.getId(), webModel.getFileName(), webModel.getStatus());
models.add(ref);
for (Validation valid : webModel.getValidations()) {
ref.getValidations().add(ValidationReference.of(valid));
}
}
return Response.ok(models).build();
} catch (AuthenticationException e) {
logger.trace(AuthenticationUtils.AUTHENTICATION_DENIED, request.getRemoteAddr(), e);
return Response.status(Status.FORBIDDEN).build();
} catch (Exception e) {
logger.fatal(ERROR_WHILE_RETRIEVING_MODELS, e);
return Response.serverError().build();
} finally {
HibernateUtils.closeManager(manager);
}
}
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response addModel(@FormDataParam("file") InputStream fileStream,
@FormDataParam("file") FormDataContentDisposition fileDetails, @Context HttpServletRequest request,
@Context ServletContext context) {
if (fileStream == null || fileDetails == null) {
return Response.status(Status.BAD_REQUEST).entity("No file provided").build();
} else if (fileDetails.getFileName().length() > 255) {
return Response.status(Status.BAD_REQUEST).entity("File name is too long (> 255 characters").build();
}
EntityManager manager = null;
try {
manager = HibernateUtils.createManager();
User user = AuthenticationUtils.authenticateUser(request, manager);
final File tempDir = (File) context.getAttribute("javax.servlet.context.tempdir");
final String tempFileName = String.valueOf(FILE_COUNTER.getAndIncrement());
File tempFile = new File(tempDir.getAbsolutePath() + File.separator + tempFileName);
Files.copy(fileStream, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
String fileName = fileDetails.getFileName();
WebCityDoctorModel model = new WebCityDoctorModel();
model.setFileName(fileName);
model.setOwner(user);
model.setStatus(ParseStatus.PARSING);
ModelQueries.storeModel(model, manager);
handleNewModel(model, tempFile, tempDir, context);
ModelReference ref = new ModelReference(model.getId(), model.getFileName(), model.getStatus());
return Response.ok(ref).build();
} catch (AuthenticationException e) {
logger.trace(AuthenticationUtils.AUTHENTICATION_DENIED, request.getRemoteAddr(), e);
return Response.status(Status.FORBIDDEN).build();
} catch (Exception e) {
logger.fatal("Error while handling uploaded file.", e);
return Response.serverError().build();
} finally {
HibernateUtils.closeManager(manager);
}
}
@GET
@Path("{modelId}/error_buildings")
@Produces(MediaType.APPLICATION_JSON)
public Response getErrorBuildings(@PathParam("modelId") int modelId,
@QueryParam("from") @DefaultValue("0") int from, @QueryParam("valid") Integer validationId,
@Context HttpServletRequest request) {
if (validationId == null) {
return Response.status(Status.BAD_REQUEST).build();
}
EntityManager manager = null;
try {
manager = HibernateUtils.createManager();
User user = AuthenticationUtils.authenticateUser(request, manager);
WebCityDoctorModel model = manager.find(WebCityDoctorModel.class, modelId);
if (model.getOwner().getId() != user.getId()) {
logger.warn(ACCESS_VIOLATION, user.getId(), model.getId());
return Response.status(Status.FORBIDDEN).build();
}
List<BuildingReference> buildings;
long maxCount = BuildingQueries.getErrorBuildingCountForModel(modelId, validationId, manager);
buildings = BuildingQueries.getErrorBuildingsWithErrorIndicator(from, modelId, validationId, manager);
BuildingsReturnType returnValue = new BuildingsReturnType();
returnValue.setFrom(from);
returnValue.setTo(Math.min(from + 25l, maxCount));
returnValue.setBuildings(buildings);
return Response.ok(returnValue).build();
} catch (AuthenticationException e) {
logger.trace(AuthenticationUtils.AUTHENTICATION_DENIED, request.getRemoteAddr(), e);
return Response.status(Status.FORBIDDEN).build();
} catch (Exception e) {
logger.fatal(ERROR_WHILE_RETRIEVING_MODELS, e);
return Response.serverError().build();
} finally {
HibernateUtils.closeManager(manager);
}
}
@GET
@Path("{modelId}/buildings")
@Produces(MediaType.APPLICATION_JSON)
public Response getBuildings(@PathParam("modelId") int modelId, @QueryParam("from") @DefaultValue("0") int from,
@QueryParam("valid") Integer validationId, @Context HttpServletRequest request) {
EntityManager manager = null;
try {
manager = HibernateUtils.createManager();
User user = AuthenticationUtils.authenticateUser(request, manager);
WebCityDoctorModel model = manager.find(WebCityDoctorModel.class, modelId);
if (model.getOwner().getId() != user.getId()) {
logger.warn(ACCESS_VIOLATION, user.getId(), model.getId());
return Response.status(Status.FORBIDDEN).build();
}
List<BuildingReference> buildings;
long maxCount = BuildingQueries.getBuildingCountForModel(modelId, manager);
if (validationId == null) {
buildings = BuildingQueries.getBuildingsForModel(from, modelId, manager);
} else {
buildings = BuildingQueries.getBuildingsWithErrorIndicator(from, modelId, validationId, manager);
}
BuildingsReturnType returnValue = new BuildingsReturnType();
returnValue.setFrom(from);
returnValue.setTo(Math.min(from + 25l, maxCount));
returnValue.setBuildings(buildings);
return Response.ok(returnValue).build();
} catch (AuthenticationException e) {
logger.trace(AuthenticationUtils.AUTHENTICATION_DENIED, request.getRemoteAddr(), e);
return Response.status(Status.FORBIDDEN).build();
} catch (Exception e) {
logger.fatal(ERROR_WHILE_RETRIEVING_MODELS, e);
return Response.serverError().build();
} finally {
HibernateUtils.closeManager(manager);
}
}
@DELETE
@Path("{modelId}")
public Response deleteModel(@PathParam("modelId") int modelId, @Context HttpServletRequest request) {
EntityManager manager = null;
try {
manager = HibernateUtils.createManager();
User user = AuthenticationUtils.authenticateUser(request, manager);
WebCityDoctorModel model = manager.find(WebCityDoctorModel.class, modelId);
if (model.getOwner().getId() != user.getId()) {
logger.warn(ACCESS_VIOLATION, user.getId(), model.getId());
return Response.status(Status.FORBIDDEN).build();
}
if (model.getZipFile() != null && model.getZipFile().getFilePath() != null) {
File zip = new File(model.getZipFile().getFilePath());
Files.delete(zip.toPath());
}
manager.getTransaction().begin();
manager.remove(model);
manager.getTransaction().commit();
return Response.ok().build();
} catch (AuthenticationException e) {
logger.trace(AuthenticationUtils.AUTHENTICATION_DENIED, request.getRemoteAddr(), e);
return Response.status(Status.FORBIDDEN).build();
} catch (Exception e) {
logger.fatal("Error while deleting model {}", modelId, e);
return Response.serverError().build();
} finally {
HibernateUtils.closeManager(manager);
}
}
private void handleNewModel(WebCityDoctorModel oldModel, File gmlFile, File tempDir, ServletContext context) {
Thread t = new Thread(() -> {
EntityManager manager = HibernateUtils.createManager();
WebCityDoctorModel model = manager.merge(oldModel);
File parseFile = storeModelAsZipFile(gmlFile, tempDir, context, manager, model);
try {
parseDataModel(parseFile, model, manager);
ModelQueries.updateStatus(model, ParseStatus.OK, manager);
} catch (UncheckedIOException | CityGmlParseException e) {
logger.catching(e);
ModelQueries.updateStatus(model, ParseStatus.ERROR, manager);
} finally {
manager.close();
if (parseFile != null) {
try {
Files.delete(parseFile.toPath());
} catch (IOException e1) {
logger.catching(e1);
}
}
}
});
t.setUncaughtExceptionHandler((thread, e) -> {
logger.catching(e);
EntityManager manager = HibernateUtils.createManager();
WebCityDoctorModel model = manager.merge(oldModel);
ModelQueries.updateStatus(model, ParseStatus.ERROR, manager);
manager.close();
});
t.start();
}
/**
* Stores the gml file as a zip into the configured folder. Returns the unpacked
* file in a temporary directory.
*
* @param gmlFile the incoming file
* @param tempDir the temporary folder for the unzipped files
* @param context servlet context for retrieving where to store the zip files
* @param manager the database access manager
* @param model the associated data model for the file
* @return the unzipped file in a temporary directory
*/
private File storeModelAsZipFile(File gmlFile, File tempDir, ServletContext context, EntityManager manager,
WebCityDoctorModel model) {
boolean isZipFile = isZipFile(model.getFileName());
File parseFile = gmlFile;
if (!parseFile.canWrite()) {
logger.warn("Cannot write the file, deletion will fail, before zip");
}
File zipFile = gmlFile;
String storagePath = context.getInitParameter("fileStorage");
File fileStorageDir = new File(storagePath);
try {
if (!isZipFile) {
zipFile = createZipFile(gmlFile, fileStorageDir);
if (!parseFile.canWrite()) {
logger.warn("Cannot write the file, deletion will fail, after zip");
}
} else {
File copy = getStorageFile(fileStorageDir);
Files.move(zipFile.toPath(), copy.toPath());
zipFile = copy;
parseFile = unzipFile(zipFile, tempDir);
}
} catch (IOException e) {
logger.catching(e);
ModelQueries.updateStatus(model, ParseStatus.ERROR, manager);
}
GmlFile fileModel = new GmlFile();
fileModel.setFilePath(zipFile.getAbsolutePath());
ModelQueries.updateModelWithBlob(model, fileModel, manager);
return parseFile;
}
private File unzipFile(File zipFile, File tempDir) throws IOException {
try (ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipFile)))) {
ZipEntry entry = zis.getNextEntry();
if (entry == null) {
throw new IllegalStateException("Zip contains no files");
}
final String tempFileName = String.valueOf(FILE_COUNTER.getAndIncrement());
File tempFile = new File(tempDir.getAbsolutePath() + File.separator + tempFileName);
Files.copy(zis, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
if (zis.getNextEntry() != null) {
throw new IllegalStateException("Zip contains more than one file");
}
return tempFile;
}
}
private void parseDataModel(File file, WebCityDoctorModel model, EntityManager manager)
throws CityGmlParseException {
ParserConfiguration config = new ParserConfiguration(8, false);
CityGmlConsumer coConsumer = new CityGmlConsumer() {
@Override
public void accept(CityObject co) {
if (co instanceof Building) {
try {
mapBuilding(model, co, manager);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
} else {
throw new UnsupportedOperationException();
}
logger.debug(co.getGmlId().getGmlString());
}
};
CityGmlParser.streamCityGml(file.getAbsolutePath(), config, coConsumer, null);
}
private void mapBuilding(WebCityDoctorModel model, CityObject co, EntityManager manager) throws IOException {
Building b = (Building) co;
Lod highestLod = findHighestLod(b);
WebBuilding buildingRef = new WebBuilding();
buildingRef.setModel(model);
buildingRef.setGmlId(b.getGmlId().getGmlString());
if (highestLod == null) {
buildingRef.setViewData(new byte[] {});
} else {
List<Polygon> polys = collectPolygonsForLod(b, highestLod);
if (polys.isEmpty()) {
throw new IllegalStateException("Found empty geometries for Lod: " + highestLod);
}
byte[] geometryData;
BoundingBox bbox = BoundingBox.of(polys);
geometryData = createGeometryData(polys, bbox.getCenter());
double width = Math.max(bbox.getWidth(), bbox.getDepth());
buildingRef.setModelWidth(width);
buildingRef.setViewData(geometryData);
}
BuildingQueries.persistBuilding(buildingRef, manager);
}
private byte[] createGeometryData(List<Polygon> polys, Vector3d center) throws IOException {
byte[] geometryData;
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos)) {
for (Polygon p : polys) {
Vector3d normal = p.calculateNormalNormalized();
float red = 1.0f;
float green = 1.0f;
float blue = 1.0f;
BoundarySurface surface = p.getPartOfSurface();
if (surface != null && surface.getType() == BoundarySurfaceType.ROOF) {
green = 0.0f;
blue = 0.0f;
}
TesselatedPolygon tesselatedPolygon = p.tesselate();
for (Triangle3d t : tesselatedPolygon.getTriangles()) {
writeTriangle(dos, normal, red, green, blue, t, center);
}
}
dos.flush();
geometryData = baos.toByteArray();
}
return geometryData;
}
private void writeTriangle(DataOutputStream dos, Vector3d normal, float red, float green, float blue, Triangle3d t,
Vector3d center) throws IOException {
float normalX = (float) normal.getX();
float normalY = (float) normal.getY();
float normalZ = (float) normal.getZ();
dos.writeFloat((float) (t.getP1().getX() - center.getX()));
dos.writeFloat((float) (t.getP1().getY() - center.getY()));
dos.writeFloat((float) (t.getP1().getZ() - center.getZ()));
dos.writeFloat(normalX);
dos.writeFloat(normalY);
dos.writeFloat(normalZ);
dos.writeFloat(red);
dos.writeFloat(green);
dos.writeFloat(blue);
dos.writeFloat((float) (t.getP2().getX() - center.getX()));
dos.writeFloat((float) (t.getP2().getY() - center.getY()));
dos.writeFloat((float) (t.getP2().getZ() - center.getZ()));
dos.writeFloat(normalX);
dos.writeFloat(normalY);
dos.writeFloat(normalZ);
dos.writeFloat(red);
dos.writeFloat(green);
dos.writeFloat(blue);
dos.writeFloat((float) (t.getP3().getX() - center.getX()));
dos.writeFloat((float) (t.getP3().getY() - center.getY()));
dos.writeFloat((float) (t.getP3().getZ() - center.getZ()));
dos.writeFloat(normalX);
dos.writeFloat(normalY);
dos.writeFloat(normalZ);
dos.writeFloat(red);
dos.writeFloat(green);
dos.writeFloat(blue);
}
private List<Polygon> collectPolygonsForLod(Building b, Lod highestLod) {
List<Polygon> polygons = new ArrayList<>();
collectAbstractBuildingPolygons(b, polygons, highestLod);
for (BuildingPart bp : b.getBuildingParts()) {
collectAbstractBuildingPolygons(bp, polygons, highestLod);
}
return polygons;
}
private void collectAbstractBuildingPolygons(AbstractBuilding ab, List<Polygon> polygons, Lod highestLod) {
collectCityObjectPolygons(ab, polygons, highestLod);
for (Installation bi : ab.getBuildingInstallations()) {
collectCityObjectPolygons(bi, polygons, highestLod);
for (BoundarySurface bs : bi.getBoundarySurfaces()) {
collectCityObjectPolygons(bs, polygons, highestLod);
}
}
for (BoundarySurface bs : ab.getBoundarySurfaces()) {
collectCityObjectPolygons(bs, polygons, highestLod);
}
}
private void collectCityObjectPolygons(CityObject co, List<Polygon> polygons, Lod highestLod) {
for (Geometry geom : co.getGeometries()) {
if (geom.getLod() == highestLod) {
for (Polygon p : geom.getPolygons()) {
if (!p.isLink()) {
polygons.add(p);
}
}
}
}
}
private Lod findHighestLod(Building b) {
Lod lod = findHighestAbstractBuildingLod(b);
for (BuildingPart bp : b.getBuildingParts()) {
Lod bpLod = findHighestAbstractBuildingLod(bp);
lod = getHigherLod(lod, bpLod);
}
return lod;
}
private Lod findHighestAbstractBuildingLod(AbstractBuilding ab) {
Lod lod = findHighestCityObjectLod(ab);
for (Installation bi : ab.getBuildingInstallations()) {
Lod biLod = findHighestCityObjectLod(bi);
lod = getHigherLod(lod, biLod);
for (BoundarySurface bs : bi.getBoundarySurfaces()) {
Lod bsLod = findHighestCityObjectLod(bs);
lod = getHigherLod(lod, bsLod);
}
}
for (BoundarySurface bs : ab.getBoundarySurfaces()) {
Lod bsLod = findHighestCityObjectLod(bs);
lod = getHigherLod(lod, bsLod);
}
return lod;
}
private Lod getHigherLod(Lod lod, Lod bsLod) {
if (lod == null) {
lod = bsLod;
} else {
if (!lod.isHigher(bsLod)) {
lod = bsLod;
}
}
return lod;
}
private Lod findHighestCityObjectLod(CityObject co) {
Lod highestLod = null;
for (Geometry geom : co.getGeometries()) {
if (highestLod == null) {
highestLod = geom.getLod();
} else {
if (geom.getLod().isHigher(highestLod)) {
highestLod = geom.getLod();
}
}
}
return highestLod;
}
private File createZipFile(File gmlFile, File storageDir) throws IOException {
if (!gmlFile.exists() || gmlFile.isDirectory()) {
throw new IllegalStateException("File does not exist or is a directory");
}
File zipFile = getStorageFile(storageDir);
try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile))) {
ZipEntry entry = new ZipEntry(gmlFile.getName());
zipOut.putNextEntry(entry);
java.nio.file.Path path = gmlFile.toPath();
Files.copy(path, zipOut);
}
return zipFile;
}
private boolean isZipFile(String fileName) {
int lastIndex = fileName.lastIndexOf('.');
if (lastIndex != -1) {
return fileName.substring(lastIndex).equalsIgnoreCase("zip");
}
return false;
}
private File getStorageFile(File dir) {
String name = generateRandomName();
File f = new File(dir.getAbsolutePath() + File.separator + name);
while (f.exists()) {
name = generateRandomName();
f = new File(dir.getAbsolutePath() + File.separator + name);
}
return f;
}
private String generateRandomName() {
StringBuilder sb = new StringBuilder(NAME_LENGTH);
for (int i = 0; i < NAME_LENGTH; i++) {
sb.append(DIGITS.charAt(RANDOM.nextInt(DIGITS.length())));
}
return sb.toString();
}
@GET
@Path("{modelId}/status")
@Produces(MediaType.APPLICATION_JSON)
public Response getStatus(@PathParam("modelId") int modelId, @Context HttpServletRequest request) {
EntityManager manager = null;
try {
manager = HibernateUtils.createManager();
User user = AuthenticationUtils.authenticateUser(request, manager);
if (user == null) {
return Response.status(Status.FORBIDDEN).build();
}
WebCityDoctorModel model = manager.find(WebCityDoctorModel.class, modelId);
if (model.getOwner().getId() != user.getId()) {
return Response.status(Status.FORBIDDEN).build();
}
ModelReference ref = new ModelReference(model.getId(), model.getFileName(), model.getStatus());
return Response.ok(ref).build();
} catch (AuthenticationException e) {
logger.trace(AuthenticationUtils.AUTHENTICATION_DENIED, request.getRemoteAddr(), e);
return Response.status(Status.FORBIDDEN).build();
} finally {
HibernateUtils.closeManager(manager);
}
}
@SuppressWarnings("unused")
private String determineModelName(WebCityDoctorModel webModel) {
String modelName = webModel.getFileName();
int fileEndingIndex = modelName.lastIndexOf('.');
if (fileEndingIndex != -1) {
modelName = modelName.substring(0, fileEndingIndex);
}
return modelName;
}
}
package de.hft.stuttgart.citydoctor2.webservice.endpoints;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.persistence.EntityManager;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import de.hft.stuttgart.citydoctor2.webservice.database.UserQueries;
import de.hft.stuttgart.citydoctor2.webservice.model.entities.User;
import de.hft.stuttgart.citydoctor2.webservice.utils.HashUtils;
import de.hft.stuttgart.citydoctor2.webservice.utils.HexUtils;
import de.hft.stuttgart.citydoctor2.webservice.utils.HibernateUtils;
@Path("register")
public class RegisterEndpoint {
private static Logger logger = LogManager.getLogger(RegisterEndpoint.class);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response register(@FormParam("username") String username, @FormParam("password") String password) {
EntityManager manager = null;
try {
manager = HibernateUtils.createManager();
User user = UserQueries.getUserForUsername(username, manager);
if (user != null) {
return Response.status(Status.CONFLICT).entity("Username already taken").build();
}
String salt = createSalt();
logger.debug("Salt for new User: {}", salt);
String passwordHash = HashUtils.createPasswordHash(password, salt);
user = new User();
user.setMail(username);
user.setPasswordHash(passwordHash);
user.setSalt(salt);
UserQueries.createUser(user, manager);
return Response.ok().build();
} catch (NoSuchAlgorithmException e) {
logger.fatal(e);
return Response.status(Status.INTERNAL_SERVER_ERROR).build();
} finally {
if (manager != null) {
manager.close();
}
}
}
private String createSalt() {
SecureRandom sr = new SecureRandom();
byte[] bytes = new byte[8];
sr.nextBytes(bytes);
return HexUtils.encode(bytes);
}
}
package de.hft.stuttgart.citydoctor2.webservice.endpoints;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.ZipInputStream;
import javax.persistence.EntityManager;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.StreamingOutput;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.Checker;
import de.hft.stuttgart.citydoctor2.check.ValidationConfiguration;
import de.hft.stuttgart.citydoctor2.checks.util.FeatureCheckedListener;
import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException;
import de.hft.stuttgart.citydoctor2.webservice.AuthenticationException;
import de.hft.stuttgart.citydoctor2.webservice.database.BuildingQueries;
import de.hft.stuttgart.citydoctor2.webservice.database.ErrorQueries;
import de.hft.stuttgart.citydoctor2.webservice.database.ValidationQueries;
import de.hft.stuttgart.citydoctor2.webservice.model.ValidationReference;
import de.hft.stuttgart.citydoctor2.webservice.model.ValidationStatus;
import de.hft.stuttgart.citydoctor2.webservice.model.entities.FeatureValidationStatus;
import de.hft.stuttgart.citydoctor2.webservice.model.entities.User;
import de.hft.stuttgart.citydoctor2.webservice.model.entities.Validation;
import de.hft.stuttgart.citydoctor2.webservice.model.entities.WebBuilding;
import de.hft.stuttgart.citydoctor2.webservice.model.entities.WebCityDoctorModel;
import de.hft.stuttgart.citydoctor2.webservice.model.entities.WebError;
import de.hft.stuttgart.citydoctor2.webservice.utils.AuthenticationUtils;
import de.hft.stuttgart.citydoctor2.webservice.utils.HibernateUtils;
@Path("models")
public class ValidationEndpoint {
private static final Logger logger = LogManager.getLogger(ValidationEndpoint.class);
private static final AtomicInteger FILE_COUNTER = new AtomicInteger(0);
@Path("{modelId}/validations")
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response addValidation(@FormDataParam("file") InputStream fileStream,
@FormDataParam("file") FormDataContentDisposition fileDetails, @Context HttpServletRequest request,
@PathParam("modelId") int modelId, @Context ServletContext context) {
EntityManager manager = null;
try {
manager = HibernateUtils.createManager();
User user = AuthenticationUtils.authenticateUser(request, manager);
if (user == null) {
return Response.status(Status.FORBIDDEN).build();
}
WebCityDoctorModel model = manager.find(WebCityDoctorModel.class, modelId);
if (model.getOwner().getId() != user.getId()) {
return Response.status(Status.FORBIDDEN).build();
}
ValidationConfiguration config = ValidationConfiguration.loadValidationConfig(fileStream);
Validation validation = new Validation(model, ValidationStatus.VALIDATING, fileDetails.getFileName());
ValidationQueries.persistValidation(manager, model, validation);
startValidationProcess(context, model, config, validation);
ValidationReference validRef = new ValidationReference(validation.getId(), fileDetails.getFileName(),
validation.getStatus());
return Response.ok(validRef).build();
} catch (AuthenticationException e) {
logger.trace(AuthenticationUtils.AUTHENTICATION_DENIED, request.getRemoteAddr(), e);
return Response.status(Status.FORBIDDEN).build();
} finally {
if (manager != null) {
manager.close();
}
}
}
@Path("validations/{validationId}/status")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getValidationStatus(@PathParam("validationId") int validationId,
@Context HttpServletRequest request) {
EntityManager manager = null;
try {
manager = HibernateUtils.createManager();
User user = AuthenticationUtils.authenticateUser(request, manager);
if (user == null) {
return Response.status(Status.FORBIDDEN).build();
}
manager.getTransaction().begin();
Validation validation = manager.find(Validation.class, validationId);
manager.getTransaction().commit();
if (validation == null) {
return Response.status(Status.BAD_REQUEST).build();
}
if (user.getId() != validation.getModel().getOwner().getId()) {
return Response.status(Status.FORBIDDEN).build();
}
ValidationReference validRef = new ValidationReference(validation.getId(), validation.getName(),
validation.getStatus());
return Response.ok(validRef).build();
} catch (AuthenticationException e) {
logger.trace(AuthenticationUtils.AUTHENTICATION_DENIED, request.getRemoteAddr(), e);
return Response.status(Status.FORBIDDEN).build();
} finally {
if (manager != null) {
manager.close();
}
}
}
@Path("validations/{validationId}/xml")
@GET
@Produces(MediaType.APPLICATION_XML)
public Response getXmlReport(@Context HttpServletRequest request, @PathParam("validationId") int validationId) {
EntityManager manager = null;
try {
manager = HibernateUtils.createManager();
User user = AuthenticationUtils.authenticateUser(request, manager);
if (user == null) {
return Response.status(Status.FORBIDDEN).build();
}
Validation valid = ValidationQueries.getValidation(validationId, manager);
WebCityDoctorModel model = valid.getModel();
if (model.getOwner().getId() != user.getId()) {
return Response.status(Status.FORBIDDEN).build();
}
if (valid.getStatus() != ValidationStatus.OK) {
Response.status(Status.BAD_REQUEST).build();
}
StreamingOutput out = new StreamingOutput() {
@Override
public void write(OutputStream output) throws IOException {
output.write(valid.getXmlReport());
}
};
int lastIndexOf = model.getFileName().lastIndexOf('.');
String fileName = model.getFileName();
if (lastIndexOf > 0) {
fileName = model.getFileName().substring(0, lastIndexOf);
}
fileName = "report_" + fileName + ".xml";
return Response.ok(out).header("Content-Disposition", "attachment; filename=" + fileName).build();
} catch (AuthenticationException e) {
logger.trace(AuthenticationUtils.AUTHENTICATION_DENIED, request.getRemoteAddr(), e);
return Response.status(Status.FORBIDDEN).build();
} finally {
if (manager != null) {
manager.close();
}
}
}
@Path("validations/{validationId}/pdf")
@GET
@Produces("application/pdf")
public Response getPdfReport(@Context HttpServletRequest request, @PathParam("validationId") int validationId) {
EntityManager manager = null;
try {
manager = HibernateUtils.createManager();
User user = AuthenticationUtils.authenticateUser(request, manager);
if (user == null) {
return Response.status(Status.FORBIDDEN).build();
}
Validation valid = ValidationQueries.getValidation(validationId, manager);
WebCityDoctorModel model = valid.getModel();
if (model.getOwner().getId() != user.getId()) {
return Response.status(Status.FORBIDDEN).build();
}
if (valid.getStatus() != ValidationStatus.OK) {
Response.status(Status.BAD_REQUEST).build();
}
StreamingOutput out = new StreamingOutput() {
@Override
public void write(OutputStream output) throws IOException {
output.write(valid.getPdfReport());
}
};
int lastIndexOf = model.getFileName().lastIndexOf('.');
String fileName = model.getFileName();
if (lastIndexOf > 0) {
fileName = model.getFileName().substring(0, lastIndexOf);
}
fileName = "report_" + fileName + ".pdf";
return Response.ok(out).header("Content-Disposition", "attachment; filename=" + fileName).build();
} catch (AuthenticationException e) {
logger.trace(AuthenticationUtils.AUTHENTICATION_DENIED, request.getRemoteAddr(), e);
return Response.status(Status.FORBIDDEN).build();
} catch (Exception e) {
logger.fatal("Error while fetching pdf report for validation id " + validationId, e);
return Response.serverError().build();
} finally {
if (manager != null) {
manager.close();
}
}
}
@Path("validations/{validationId}")
@DELETE
public Response deleteValidation(@Context HttpServletRequest request, @PathParam("validationId") int validationId) {
EntityManager manager = null;
try {
manager = HibernateUtils.createManager();
User user = AuthenticationUtils.authenticateUser(request, manager);
if (user == null) {
return Response.status(Status.FORBIDDEN).build();
}
Validation valid = ValidationQueries.getValidation(validationId, manager);
WebCityDoctorModel model = valid.getModel();
if (model.getOwner().getId() != user.getId()) {
return Response.status(Status.FORBIDDEN).build();
}
manager.getTransaction().begin();
manager.remove(valid);
manager.getTransaction().commit();
return Response.ok().build();
} catch (AuthenticationException e) {
logger.trace(AuthenticationUtils.AUTHENTICATION_DENIED, request.getRemoteAddr(), e);
return Response.status(Status.FORBIDDEN).build();
} catch (Exception e) {
logger.fatal("Error while deleting validation id " + validationId, e);
return Response.serverError().build();
} finally {
if (manager != null) {
manager.close();
}
}
}
private void startValidationProcess(ServletContext context, WebCityDoctorModel oldModel,
ValidationConfiguration config, Validation oldValidation) {
Thread t = new Thread(() -> {
final File tempDir = (File) context.getAttribute("javax.servlet.context.tempdir");
String pdfFileName = FILE_COUNTER.getAndIncrement() + ".pdf";
String tempPdfPath = tempDir.getAbsolutePath() + File.separator + pdfFileName;
String xmlFileName = FILE_COUNTER.getAndIncrement() + ".xml";
String tempXmlPath = tempDir.getAbsolutePath() + File.separator + xmlFileName;
EntityManager manager = HibernateUtils.createManager();
WebCityDoctorModel model = manager.merge(oldModel);
Validation validation = manager.merge(oldValidation);
File gmlFile = null;
try {
String gmlFileName = FILE_COUNTER.getAndIncrement() + ".gml";
String gmlFileString = tempDir.getAbsolutePath() + File.separator + gmlFileName;
gmlFile = new File(gmlFileString);
unpackGmlFile(model, gmlFile);
FeatureCheckedListener l = co -> {
Set<CheckError> errors = new HashSet<>();
List<CheckError> errorList = new ArrayList<>();
co.collectContainedErrors(errorList);
errors.addAll(errorList);
WebBuilding building = BuildingQueries.getBuildingForGmlId(co.getGmlId().getGmlString(),
model.getId(), manager);
FeatureValidationStatus status = new FeatureValidationStatus();
status.setWasValidated(co.hasCheckResults());
status.setHasError(!errors.isEmpty());
ValidationQueries.addFeatureValidationStatus(building, validation, status, manager);
if (!errors.isEmpty()) {
for (CheckError err : errors) {
WebError webError = new WebError();
webError.setBuilding(building);
webError.setName(err.getErrorId().toString());
webError.setValidation(validation);
ErrorQueries.addErrorToBuilding(building, validation, webError, manager);
}
}
};
Checker.streamCheck(gmlFile, tempXmlPath, tempPdfPath, config, l, null);
ValidationQueries.updateValidationWithReports(validation, readToByteArray(tempPdfPath),
readToByteArray(tempXmlPath), manager);
ValidationQueries.updateStatus(validation, ValidationStatus.OK, manager);
} catch (IOException | CityGmlParseException e1) {
logger.fatal("Error while validating {}", model.getFileName());
logger.catching(e1);
ValidationQueries.updateStatus(validation, ValidationStatus.ERROR, manager);
} finally {
manager.close();
try {
if (gmlFile != null && gmlFile.exists()) {
Files.delete(gmlFile.toPath());
}
File pdfFile = new File(tempPdfPath);
if (pdfFile.exists()) {
Files.delete(pdfFile.toPath());
}
File xmlFile = new File(tempXmlPath);
if (xmlFile.exists()) {
Files.delete(xmlFile.toPath());
}
} catch (IOException e1) {
logger.catching(e1);
}
}
});
t.setUncaughtExceptionHandler((thread, e) -> {
logger.catching(e);
setValidationStatusToError(oldValidation);
});
t.start();
}
private byte[] readToByteArray(String tempPdfPath) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
File pdfFile = new File(tempPdfPath);
Files.copy(pdfFile.toPath(), baos);
return baos.toByteArray();
}
private void setValidationStatusToError(Validation validation) {
EntityManager manager = HibernateUtils.createManager();
Validation valid = manager.merge(validation);
ValidationQueries.updateStatus(valid, ValidationStatus.ERROR, manager);
manager.close();
}
private void unpackGmlFile(WebCityDoctorModel model, File gmlFile) throws IOException {
File zipFile = new File(model.getZipFile().getFilePath());
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) {
zis.getNextEntry();
Files.copy(zis, gmlFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
}
}
package de.hft.stuttgart.citydoctor2.webservice.model;
import java.util.List;
public class AvailableChecksReturnType {
private List<CheckReturnType> geometricChecks;
private List<CheckReturnType> semanticChecks;
public List<CheckReturnType> getGeometricChecks() {
return geometricChecks;
}
public void setGeometricChecks(List<CheckReturnType> geometricChecks) {
this.geometricChecks = geometricChecks;
}
public List<CheckReturnType> getSemanticChecks() {
return semanticChecks;
}
public void setSemanticChecks(List<CheckReturnType> semanticChecks) {
this.semanticChecks = semanticChecks;
}
}
package de.hft.stuttgart.citydoctor2.webservice.model;
import java.util.ArrayList;
import java.util.List;
import de.hft.stuttgart.citydoctor2.webservice.model.entities.WebBuilding;
public class BuildingReference {
private int id;
private String gmlId;
private double width;
private List<ErrorReference> errors = new ArrayList<>();
public static BuildingReference of(WebBuilding ref) {
return new BuildingReference(ref.getId(), ref.getGmlId(), ref.getModelWidth());
}
public BuildingReference(int id, String gmlId, double width) {
super();
this.id = id;
this.gmlId = gmlId;
this.width = width;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getGmlId() {
return gmlId;
}
public void setGmlId(String gmlId) {
this.gmlId = gmlId;
}
public List<ErrorReference> getErrors() {
return errors;
}
public void setErrors(List<ErrorReference> errors) {
this.errors = errors;
}
}
package de.hft.stuttgart.citydoctor2.webservice.model;
public class BuildingReferenceWithErrorIndicator extends BuildingReference {
private boolean hasErrors;
public BuildingReferenceWithErrorIndicator(int id, String gmlId, double width, boolean hasErrors) {
super(id, gmlId, width);
this.hasErrors = hasErrors;
}
public boolean isHasErrors() {
return hasErrors;
}
public void setHasErrors(boolean hasErrors) {
this.hasErrors = hasErrors;
}
}
package de.hft.stuttgart.citydoctor2.webservice.model;
import java.util.ArrayList;
import java.util.List;
public class BuildingsReturnType {
private long from;
private long to;
private List<BuildingReference> buildings = new ArrayList<>();
public long getFrom() {
return from;
}
public void setFrom(long from) {
this.from = from;
}
public long getTo() {
return to;
}
public void setTo(long to) {
this.to = to;
}
public List<BuildingReference> getBuildings() {
return buildings;
}
public void setBuildings(List<BuildingReference> buildings) {
this.buildings = buildings;
}
}
package de.hft.stuttgart.citydoctor2.webservice.model;
import java.util.ArrayList;
import java.util.List;
import de.hft.stuttgart.citydoctor2.check.DefaultParameter;
public class CheckReturnType {
private String name;
private List<DefaultParameter> parameters = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<DefaultParameter> getParameters() {
return parameters;
}
public void setParameters(List<DefaultParameter> parameters) {
this.parameters = parameters;
}
}
package de.hft.stuttgart.citydoctor2.webservice.model;
import de.hft.stuttgart.citydoctor2.webservice.model.entities.WebError;
public class ErrorReference {
private int id;
private String name;
public static ErrorReference of(WebError err) {
return new ErrorReference(err.getId(), err.getName());
}
private ErrorReference(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package de.hft.stuttgart.citydoctor2.webservice.model;
public class FeatureValidationStatusReturnValue {
private int featureId;
private boolean hasError;
public FeatureValidationStatusReturnValue() {
}
public FeatureValidationStatusReturnValue(int featureId, boolean hasError) {
super();
this.featureId = featureId;
this.hasError = hasError;
}
public int getFeatureId() {
return featureId;
}
public void setFeatureId(int featureId) {
this.featureId = featureId;
}
public boolean isHasError() {
return hasError;
}
public void setHasError(boolean hasError) {
this.hasError = hasError;
}
}
package de.hft.stuttgart.citydoctor2.webservice.model;
import java.time.LocalDateTime;
public class LoginSuccessfulReturnType {
private String token;
private LocalDateTime expires;
private int userId;
public LoginSuccessfulReturnType(String token, LocalDateTime expires, int userId) {
this.token = token;
this.expires = expires;
this.userId = userId;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public LocalDateTime getExpires() {
return expires;
}
public void setExpires(LocalDateTime expires) {
this.expires = expires;
}
}
package de.hft.stuttgart.citydoctor2.webservice.model;
import java.util.ArrayList;
import java.util.List;
public class ModelReference {
private int id;
private String name;
private ParseStatus status;
private List<ValidationReference> validations = new ArrayList<>();
public ModelReference(int id, String name, ParseStatus status) {
super();
this.id = id;
this.name = name;
this.status = status;
}
public List<ValidationReference> getValidations() {
return validations;
}
public void setValidations(List<ValidationReference> validations) {
this.validations = validations;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ParseStatus getStatus() {
return status;
}
public void setStatus(ParseStatus status) {
this.status = status;
}
}
package de.hft.stuttgart.citydoctor2.webservice.model;
public enum ParseStatus {
PARSING, ERROR, OK
}
package de.hft.stuttgart.citydoctor2.webservice.model;
import de.hft.stuttgart.citydoctor2.webservice.model.entities.Validation;
public class ValidationReference {
private int id;
private String name;
private ValidationStatus status;
public static ValidationReference of(Validation valid) {
return new ValidationReference(valid.getId(), valid.getName(), valid.getStatus());
}
public ValidationReference(int id, String name, ValidationStatus status) {
super();
this.id = id;
this.name = name;
this.status = status;
}
public ValidationStatus getStatus() {
return status;
}
public void setStatus(ValidationStatus status) {
this.status = status;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package de.hft.stuttgart.citydoctor2.webservice.model;
public enum ValidationStatus {
PARSING, VALIDATING, OK, ERROR
}
package de.hft.stuttgart.citydoctor2.webservice.model.entities;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
@Entity
@Table(name = "feature_validation_status")
public class FeatureValidationStatus {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Access(AccessType.PROPERTY)
private int id;
@JoinColumn(name = "feature_id")
@NotNull
@ManyToOne
private WebBuilding feature;
@JoinColumn(name = "validation_id")
@NotNull
@ManyToOne
private Validation validation;
@Column(name = "has_error")
private boolean hasError;
@Column(name = "was_validated")
private boolean wasValidated;
public WebBuilding getFeature() {
return feature;
}
public void setFeature(WebBuilding feature) {
this.feature = feature;
}
public Validation getValidation() {
return validation;
}
public void setValidation(Validation validation) {
this.validation = validation;
}
public boolean isHasError() {
return hasError;
}
public void setHasError(boolean hasError) {
this.hasError = hasError;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public boolean isWasValidated() {
return wasValidated;
}
public void setWasValidated(boolean wasValidated) {
this.wasValidated = wasValidated;
}
}
package de.hft.stuttgart.citydoctor2.webservice.model.entities;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "gml_files")
public class GmlFile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Access(AccessType.PROPERTY)
private int id;
@Column(name = "file_path", length = 1024)
private String filePath;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
}
package de.hft.stuttgart.citydoctor2.webservice.model.entities;
import java.time.LocalDateTime;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
@Entity
@Table(name = "token")
public class Token {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Access(AccessType.PROPERTY)
private int id;
@ManyToOne
@JoinColumn(name = "user_id")
@NotNull
private User user;
@NotNull
private String address;
@NotNull
@Column(name = "token")
private String tokenString;
@NotNull
private LocalDateTime expires;
@Override
public String toString() {
return "Token [id=" + id + ", user=" + user + ", address=" + address + ", token=" + tokenString + ", expires="
+ expires + "]";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getTokenString() {
return tokenString;
}
public void setTokenString(String tokenString) {
this.tokenString = tokenString;
}
public LocalDateTime getExpires() {
return expires;
}
public void setExpires(LocalDateTime expires) {
this.expires = expires;
}
}
package de.hft.stuttgart.citydoctor2.webservice.model.entities;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Access(AccessType.PROPERTY)
private int id;
@Column(unique = true, length = 200)
@NotNull
private String mail;
@Column(name = "pw_hash")
@NotNull
private String passwordHash;
@NotNull
@Column(length = 16)
private String salt;
@OneToMany(mappedBy = "owner")
private List<WebCityDoctorModel> ownedModels = new ArrayList<>();
public List<WebCityDoctorModel> getOwnedModels() {
return ownedModels;
}
public void setOwnedModels(List<WebCityDoctorModel> ownedModels) {
this.ownedModels = ownedModels;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public String getPasswordHash() {
return passwordHash;
}
public void setPasswordHash(String passwordHash) {
this.passwordHash = passwordHash;
}
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
@Override
public String toString() {
return "User [id=" + id + ", mail=" + mail + ", passwordHash=" + passwordHash + ", salt=" + salt + "]";
}
}
package de.hft.stuttgart.citydoctor2.webservice.model.entities;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import de.hft.stuttgart.citydoctor2.webservice.model.ValidationStatus;
@Entity
@Table(name = "validations")
public class Validation {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Access(AccessType.PROPERTY)
private int id;
@ManyToOne
@NotNull
private WebCityDoctorModel model;
@NotNull
private ValidationStatus status;
@NotNull
private String name;
@OneToMany(mappedBy = "validation", orphanRemoval = true)
private List<WebError> errors = new ArrayList<>();
@OneToMany(mappedBy = "validation", orphanRemoval = true)
private List<FeatureValidationStatus> errorStatus = new ArrayList<>();
@Column(name = "pdf_report")
private byte[] pdfReport;
@Column(name = "xml_report")
private byte[] xmlReport;
public Validation() {
}
public Validation(@NotNull WebCityDoctorModel model, @NotNull ValidationStatus status, @NotNull String name) {
super();
this.model = model;
this.status = status;
this.name = name;
}
public List<FeatureValidationStatus> getErrorStatus() {
return errorStatus;
}
public void setErrorStatus(List<FeatureValidationStatus> errorStatus) {
this.errorStatus = errorStatus;
}
public List<WebError> getErrors() {
return errors;
}
public void setErrors(List<WebError> errors) {
this.errors = errors;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public WebCityDoctorModel getModel() {
return model;
}
public void setModel(WebCityDoctorModel model) {
this.model = model;
}
public ValidationStatus getStatus() {
return status;
}
public void setStatus(ValidationStatus status) {
this.status = status;
}
public byte[] getPdfReport() {
return pdfReport;
}
public void setPdfReport(byte[] pdfReport) {
this.pdfReport = pdfReport;
}
public byte[] getXmlReport() {
return xmlReport;
}
public void setXmlReport(byte[] xmlReport) {
this.xmlReport = xmlReport;
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment