All checks were successful
Publish FaceAI Container / publish (push) Successful in 9m53s
314 lines
No EOL
10 KiB
Text
314 lines
No EOL
10 KiB
Text
<%@ page contentType="application/json; charset=UTF-8" %>
|
|
<%@ page language="java" import="java.lang.reflect.Constructor" %>
|
|
<%@ page language="java" import="java.lang.reflect.Method" %>
|
|
<%!
|
|
private String faceAiLookupTrim(String value) {
|
|
return value == null ? "" : value.trim();
|
|
}
|
|
|
|
private String faceAiLookupEscapeJson(String value) {
|
|
if (value == null) {
|
|
return "";
|
|
}
|
|
|
|
StringBuilder builder = new StringBuilder(value.length() + 16);
|
|
for (int index = 0; index < value.length(); index++) {
|
|
char current = value.charAt(index);
|
|
switch (current) {
|
|
case '\\':
|
|
builder.append("\\\\");
|
|
break;
|
|
case '"':
|
|
builder.append("\\\"");
|
|
break;
|
|
case '\b':
|
|
builder.append("\\b");
|
|
break;
|
|
case '\f':
|
|
builder.append("\\f");
|
|
break;
|
|
case '\n':
|
|
builder.append("\\n");
|
|
break;
|
|
case '\r':
|
|
builder.append("\\r");
|
|
break;
|
|
case '\t':
|
|
builder.append("\\t");
|
|
break;
|
|
default:
|
|
if (current < 0x20) {
|
|
String hex = Integer.toHexString(current);
|
|
builder.append("\\u");
|
|
for (int padding = hex.length(); padding < 4; padding++) {
|
|
builder.append('0');
|
|
}
|
|
builder.append(hex);
|
|
} else {
|
|
builder.append(current);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return builder.toString();
|
|
}
|
|
|
|
private Object faceAiLookupInvoke(Object target, String methodName, Class[] paramTypes, Object[] args) {
|
|
if (target == null || methodName == null || methodName.length() == 0) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
Method method = target.getClass().getMethod(methodName, paramTypes == null ? new Class[0] : paramTypes);
|
|
return method.invoke(target, args == null ? new Object[0] : args);
|
|
} catch (Exception ignored) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private long faceAiLookupLong(Object value) {
|
|
if (value instanceof Number) {
|
|
return ((Number) value).longValue();
|
|
}
|
|
if (value != null) {
|
|
try {
|
|
return Long.parseLong(String.valueOf(value));
|
|
} catch (NumberFormatException ignored) {
|
|
return 0L;
|
|
}
|
|
}
|
|
return 0L;
|
|
}
|
|
|
|
private String faceAiLookupString(Object value) {
|
|
return value == null ? "" : String.valueOf(value);
|
|
}
|
|
|
|
private boolean faceAiLookupIsSafeValue(String value) {
|
|
return value == null || value.indexOf('\'') == -1;
|
|
}
|
|
|
|
private String faceAiLookupNormalizePhotoId(String value) {
|
|
return faceAiLookupTrim(value).replace('\\', '/');
|
|
}
|
|
|
|
private String faceAiLookupNormalizeFileName(String value) {
|
|
String normalized = faceAiLookupNormalizePhotoId(value);
|
|
int lastSlash = normalized.lastIndexOf('/');
|
|
if (lastSlash >= 0 && lastSlash < normalized.length() - 1) {
|
|
normalized = normalized.substring(lastSlash + 1);
|
|
}
|
|
return faceAiLookupTrim(normalized);
|
|
}
|
|
|
|
private String faceAiLookupCompositeFileName(String photoId) {
|
|
String normalized = faceAiLookupNormalizePhotoId(photoId);
|
|
if (normalized.length() == 0) {
|
|
return "";
|
|
}
|
|
return normalized.replace('/', '_').replace(':', '_');
|
|
}
|
|
|
|
private long[] faceAiLookupParseLongList(String value) {
|
|
if (value == null || value.trim().length() == 0) {
|
|
return new long[0];
|
|
}
|
|
|
|
String[] parts = value.split(",");
|
|
long[] parsed = new long[parts.length];
|
|
int count = 0;
|
|
for (int index = 0; index < parts.length; index++) {
|
|
String part = parts[index] == null ? "" : parts[index].trim();
|
|
if (!part.matches("^\\d+$")) {
|
|
continue;
|
|
}
|
|
|
|
parsed[count] = Long.parseLong(part);
|
|
count++;
|
|
}
|
|
|
|
if (count == parsed.length) {
|
|
return parsed;
|
|
}
|
|
|
|
long[] compact = new long[count];
|
|
for (int index = 0; index < count; index++) {
|
|
compact[index] = parsed[index];
|
|
}
|
|
return compact;
|
|
}
|
|
|
|
private Object faceAiLookupInstantiateFoto(Class fotoClass, Constructor constructor, Object apFull) throws Exception {
|
|
return constructor.newInstance(new Object[] { apFull });
|
|
}
|
|
|
|
private boolean faceAiLookupHasResolvedPhoto(Object foto) {
|
|
return faceAiLookupLong(faceAiLookupInvoke(foto, "getDBState", null, null)) == 1L
|
|
&& faceAiLookupLong(faceAiLookupInvoke(foto, "getId_foto", null, null)) > 0L;
|
|
}
|
|
|
|
private boolean faceAiLookupMatchesRace(Object foto, long raceId) {
|
|
if (raceId <= 0L) {
|
|
return true;
|
|
}
|
|
|
|
return faceAiLookupLong(faceAiLookupInvoke(foto, "getId_gara", null, null)) == raceId;
|
|
}
|
|
|
|
private Object faceAiLookupResolvePhoto(Class fotoClass, Constructor constructor, Object apFull, String photoId, String normalizedPhotoId, String fileName, long raceId, long[] puntoFotoIds) throws Exception {
|
|
Method findByPrimaryKey = fotoClass.getMethod("findByPrimaryKey", new Class[] { long.class });
|
|
Method findByFoto = fotoClass.getMethod("findByFoto", new Class[] { String.class });
|
|
Method findByFilenamePuntoFoto = fotoClass.getMethod("findByFilenamePuntoFoto", new Class[] { String.class, long.class });
|
|
Method findByFilenameGara = fotoClass.getMethod("findByFilenameGara", new Class[] { String.class, long.class });
|
|
String compositeFileName = faceAiLookupCompositeFileName(photoId);
|
|
|
|
if (photoId.matches("^\\d+$")) {
|
|
Object foto = faceAiLookupInstantiateFoto(fotoClass, constructor, apFull);
|
|
findByPrimaryKey.invoke(foto, new Object[] { Long.valueOf(Long.parseLong(photoId)) });
|
|
if (faceAiLookupHasResolvedPhoto(foto) && faceAiLookupMatchesRace(foto, raceId)) {
|
|
return foto;
|
|
}
|
|
}
|
|
|
|
String[] fotoCandidates = new String[] {
|
|
photoId,
|
|
normalizedPhotoId,
|
|
compositeFileName
|
|
};
|
|
for (int index = 0; index < fotoCandidates.length; index++) {
|
|
String candidate = faceAiLookupTrim(fotoCandidates[index]);
|
|
if (candidate.length() == 0 || !faceAiLookupIsSafeValue(candidate)) {
|
|
continue;
|
|
}
|
|
|
|
Object foto = faceAiLookupInstantiateFoto(fotoClass, constructor, apFull);
|
|
findByFoto.invoke(foto, new Object[] { candidate });
|
|
if (faceAiLookupHasResolvedPhoto(foto) && faceAiLookupMatchesRace(foto, raceId)) {
|
|
return foto;
|
|
}
|
|
}
|
|
|
|
if (fileName.length() > 0 && faceAiLookupIsSafeValue(fileName)) {
|
|
for (int index = 0; index < puntoFotoIds.length; index++) {
|
|
if (puntoFotoIds[index] <= 0L) {
|
|
continue;
|
|
}
|
|
|
|
Object foto = faceAiLookupInstantiateFoto(fotoClass, constructor, apFull);
|
|
findByFilenamePuntoFoto.invoke(foto, new Object[] { fileName, Long.valueOf(puntoFotoIds[index]) });
|
|
if (faceAiLookupHasResolvedPhoto(foto)) {
|
|
return foto;
|
|
}
|
|
}
|
|
|
|
if (raceId > 0L) {
|
|
Object foto = faceAiLookupInstantiateFoto(fotoClass, constructor, apFull);
|
|
findByFilenameGara.invoke(foto, new Object[] { fileName, Long.valueOf(raceId) });
|
|
if (faceAiLookupHasResolvedPhoto(foto)) {
|
|
return foto;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (compositeFileName.length() > 0 && raceId > 0L && faceAiLookupIsSafeValue(compositeFileName)) {
|
|
Object foto = faceAiLookupInstantiateFoto(fotoClass, constructor, apFull);
|
|
findByFilenameGara.invoke(foto, new Object[] { compositeFileName, Long.valueOf(raceId) });
|
|
if (faceAiLookupHasResolvedPhoto(foto)) {
|
|
return foto;
|
|
}
|
|
}
|
|
|
|
if (fileName.length() > 0 && raceId <= 0L && faceAiLookupIsSafeValue(fileName)) {
|
|
Object foto = faceAiLookupInstantiateFoto(fotoClass, constructor, apFull);
|
|
findByFoto.invoke(foto, new Object[] { fileName });
|
|
if (faceAiLookupHasResolvedPhoto(foto)) {
|
|
return foto;
|
|
}
|
|
}
|
|
|
|
return faceAiLookupInstantiateFoto(fotoClass, constructor, apFull);
|
|
}
|
|
|
|
private Object faceAiLookupResolveApFull(javax.servlet.jsp.PageContext pageContext) {
|
|
if (pageContext == null) {
|
|
return null;
|
|
}
|
|
|
|
Object[] candidates = new Object[] {
|
|
pageContext.findAttribute("user"),
|
|
pageContext.findAttribute("utenteLogon")
|
|
};
|
|
|
|
for (int index = 0; index < candidates.length; index++) {
|
|
Object candidate = candidates[index];
|
|
Object apFull = faceAiLookupInvoke(candidate, "getApFull", null, null);
|
|
if (apFull != null) {
|
|
return apFull;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
%>
|
|
<%
|
|
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
|
|
response.setHeader("Pragma", "no-cache");
|
|
|
|
String rawPhotoId = request.getParameter("photoId");
|
|
String photoId = faceAiLookupTrim(rawPhotoId);
|
|
String normalizedPhotoId = faceAiLookupNormalizePhotoId(request.getParameter("normalizedPhotoId"));
|
|
String fileName = faceAiLookupNormalizeFileName(request.getParameter("fileName"));
|
|
long raceId = faceAiLookupLong(request.getParameter("raceId"));
|
|
long[] puntoFotoIds = faceAiLookupParseLongList(request.getParameter("puntoFotoIds"));
|
|
|
|
if (photoId.length() == 0) {
|
|
response.setStatus(400);
|
|
out.print("{\"found\":false,\"error\":\"missing-photo-id\"}");
|
|
return;
|
|
}
|
|
|
|
if (!faceAiLookupIsSafeValue(photoId) || !faceAiLookupIsSafeValue(normalizedPhotoId) || !faceAiLookupIsSafeValue(fileName)) {
|
|
response.setStatus(400);
|
|
out.print("{\"found\":false,\"photoId\":\"" + faceAiLookupEscapeJson(photoId) + "\",\"error\":\"invalid-photo-id\"}");
|
|
return;
|
|
}
|
|
|
|
Object apFull = faceAiLookupResolveApFull(pageContext);
|
|
if (apFull == null) {
|
|
response.setStatus(503);
|
|
out.print("{\"found\":false,\"photoId\":\"" + faceAiLookupEscapeJson(photoId) + "\",\"error\":\"missing-apfull\"}");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
Class fotoClass = Class.forName("it.acxent.pg.Foto");
|
|
Constructor constructor = fotoClass.getConstructor(new Class[] { apFull.getClass() });
|
|
Object foto = faceAiLookupResolvePhoto(fotoClass, constructor, apFull, photoId, normalizedPhotoId, fileName, raceId, puntoFotoIds);
|
|
|
|
long dbState = faceAiLookupLong(faceAiLookupInvoke(foto, "getDBState", null, null));
|
|
long legacyId = faceAiLookupLong(faceAiLookupInvoke(foto, "getId_foto", null, null));
|
|
|
|
if (dbState != 1L || legacyId <= 0L) {
|
|
response.setStatus(404);
|
|
out.print("{\"found\":false,\"photoId\":\"" + faceAiLookupEscapeJson(photoId) + "\"}");
|
|
return;
|
|
}
|
|
|
|
Method getFileName = fotoClass.getMethod("getFileName", new Class[] { String.class });
|
|
String thumbnailBase = faceAiLookupString(getFileName.invoke(foto, new Object[] { ".jpg" }));
|
|
String thumbSrc = "foto/" + thumbnailBase + "+tn-" + legacyId + ".jpg";
|
|
|
|
out.print("{"
|
|
+ "\"found\":true,"
|
|
+ "\"photoId\":\"" + faceAiLookupEscapeJson(photoId) + "\","
|
|
+ "\"resolvedFile\":\"" + faceAiLookupEscapeJson(faceAiLookupString(faceAiLookupInvoke(foto, "getFile", null, null))) + "\","
|
|
+ "\"legacyId\":" + legacyId + ","
|
|
+ "\"thumbSrc\":\"" + faceAiLookupEscapeJson(thumbSrc) + "\""
|
|
+ "}");
|
|
} catch (Exception error) {
|
|
log("FaceAI photo lookup failed for " + photoId, error);
|
|
response.setStatus(500);
|
|
out.print("{\"found\":false,\"photoId\":\"" + faceAiLookupEscapeJson(photoId) + "\",\"error\":\"lookup-failed\"}");
|
|
}
|
|
%> |