diff --git a/src/main/java/ch/autumo/beetroot/BeetRootWebServer.java b/src/main/java/ch/autumo/beetroot/BeetRootWebServer.java index 747dd3f1..2169d7fc 100644 --- a/src/main/java/ch/autumo/beetroot/BeetRootWebServer.java +++ b/src/main/java/ch/autumo/beetroot/BeetRootWebServer.java @@ -491,8 +491,8 @@ public Response serve(BeetRootHTTPSession session, HttpServletRequest request) { } catch (FileNotFoundException e) { final String err = "Couldn't serve temporary file '" + fullTmpPath + "'!"; LOG.error(err, e); - final String t = LanguageManager.getInstance().translate("base.err.resource.title", userSession); - final String m = LanguageManager.getInstance().translate("base.err.resource.msg", userSession, uriWithoutServlet); + final String t = LanguageManager.getInstance().translate("base.err.resource.title", userLang); + final String m = LanguageManager.getInstance().translate("base.err.resource.msg", userLang, uriWithoutServlet); return serverResponse(session, ErrorHandler.class, Status.NOT_FOUND, t, m); } } @@ -527,8 +527,8 @@ public Response serve(BeetRootHTTPSession session, HttpServletRequest request) { } catch (IOException e1) { final String err = "Resource not found on server looking up with resource path '" + filePath + "'!"; LOG.error(err, e); - final String t = LanguageManager.getInstance().translate("base.err.resource.title", userSession); - final String m = LanguageManager.getInstance().translate("base.err.resource.msg", userSession, uriWithoutServlet); + final String t = LanguageManager.getInstance().translate("base.err.resource.title", userLang); + final String m = LanguageManager.getInstance().translate("base.err.resource.msg", userLang, uriWithoutServlet); return serverResponse(session, ErrorHandler.class, Status.NOT_FOUND, t, m); } } @@ -545,8 +545,8 @@ public Response serve(BeetRootHTTPSession session, HttpServletRequest request) { } catch (IOException e1) { final String err = "Resource not found on server looking up with file path '" + filePath + "'!"; LOG.error(err, e); - final String t = LanguageManager.getInstance().translate("base.err.resource.title", userSession); - final String m = LanguageManager.getInstance().translate("base.err.resource.msg", userSession, uriWithoutServlet); + final String t = LanguageManager.getInstance().translate("base.err.resource.title", userLang); + final String m = LanguageManager.getInstance().translate("base.err.resource.msg", userLang, uriWithoutServlet); return serverResponse(session, ErrorHandler.class, Status.NOT_FOUND, t, m); } } @@ -602,15 +602,15 @@ public Response serve(BeetRootHTTPSession session, HttpServletRequest request) { // If we come here, a mime type has been requested that is not yet implemented final String err = "Mime type for web resource '" + filePath + "' not implemented yet!"; LOG.warn(err); - final String t = LanguageManager.getInstance().translate("base.err.resource.mime.title", userSession); - final String m = LanguageManager.getInstance().translate("base.err.resource.mime.msg", userSession, filePath); + final String t = LanguageManager.getInstance().translate("base.err.resource.mime.title", userLang); + final String m = LanguageManager.getInstance().translate("base.err.resource.mime.msg", userLang, filePath); return serverResponse(session, ErrorHandler.class, Status.NOT_FOUND, t, m); } } catch (IOException e) { final String err = "Couldn't parse css for pre-url replacements Resource Not found! - Web resource '" + filePath + "'."; LOG.error(err, e); - final String t = LanguageManager.getInstance().translate("base.err.resource.title", userSession); - final String m = LanguageManager.getInstance().translate("base.err.resource.msg", userSession, filePath); + final String t = LanguageManager.getInstance().translate("base.err.resource.title", userLang); + final String m = LanguageManager.getInstance().translate("base.err.resource.msg", userLang, filePath); return serverResponse(session, ErrorHandler.class, Status.NOT_FOUND, t, m); } } @@ -632,15 +632,15 @@ public Response serve(BeetRootHTTPSession session, HttpServletRequest request) { } catch (IOException ioe) { final String err = "Server Internal Error - I/O Exception: " + ioe.getMessage(); LOG.error(err, ioe); - final String t = LanguageManager.getInstance().translate("base.err.srv.io.title", userSession); - final String m = LanguageManager.getInstance().translate("base.err.srv.io.msg", userSession, ioe.getMessage()); + final String t = LanguageManager.getInstance().translate("base.err.srv.io.title", userLang); + final String m = LanguageManager.getInstance().translate("base.err.srv.io.msg", userLang, ioe.getMessage()); return serverResponse(session, ErrorHandler.class, Status.INTERNAL_ERROR, t, m); } catch (ResponseException re) { final String err = "Server Internal Error - Response Exception (Status: "+re.getStatus().getDescription()+"): " + re.getMessage(); LOG.error(err, re); - final String t = LanguageManager.getInstance().translate("base.err.srv.re.title", userSession); - final String m = LanguageManager.getInstance().translate("base.err.srv.re.msg", userSession, re.getStatus().getRequestStatus(), re.getMessage()); + final String t = LanguageManager.getInstance().translate("base.err.srv.re.title", userLang); + final String m = LanguageManager.getInstance().translate("base.err.srv.re.msg", userLang, re.getStatus().getRequestStatus(), re.getMessage()); return serverResponse(session, ErrorHandler.class, Status.INTERNAL_ERROR, t, m); } } @@ -655,7 +655,7 @@ public Response serve(BeetRootHTTPSession session, HttpServletRequest request) { loggedIn = false; session.getParameters().clear(); session.getHeaders().put("Connection", "close"); - final Response end = serverResponse(session, this.getHandlerClass("LogoutHandler"), "logout", LanguageManager.getInstance().translate("base.info.session.timeout", userSession)); + final Response end = serverResponse(session, this.getHandlerClass("LogoutHandler"), "logout", LanguageManager.getInstance().translate("base.info.session.timeout", userLang)); userSession.deleteAllParameters(); userSession.destroy(session.getCookies()); return end; @@ -670,7 +670,7 @@ public Response serve(BeetRootHTTPSession session, HttpServletRequest request) { loggedIn = false; session.getParameters().clear(); session.getHeaders().put("Connection", "close"); - final Response end = serverResponse(session, this.getHandlerClass("LogoutHandler"), "logout", LanguageManager.getInstance().translate("base.info.logout.msg", userSession)); + final Response end = serverResponse(session, this.getHandlerClass("LogoutHandler"), "logout", LanguageManager.getInstance().translate("base.info.logout.msg", userLang)); userSession.deleteAllParameters(); userSession.destroyDelete(session.getCookies()); return end; @@ -704,7 +704,7 @@ public Response serve(BeetRootHTTPSession session, HttpServletRequest request) { return postLogin(session, userSession, userSession.getUserId().intValue(), userSession.getUserName()); } else { userSession.clearUserData(); - String m = LanguageManager.getInstance().translate("base.err.login.msg", userSession, postParamUsername); + String m = LanguageManager.getInstance().translate("base.err.login.msg", userLang, postParamUsername); return serverResponse(session, this.getHandlerClass("LoginHandler"), "Login", m); } } @@ -729,31 +729,32 @@ else if (postParamUsername != null && postParamUsername.length() != 0) { user.setLang(userLang); } dbTwoFa = user.getTwoFa(); - } - // Roles - final List usersRoles = UserRole.where(UserRole.class, "user_id = ?", Integer.valueOf(user.getId())); - if (usersRoles == null) - throw new SQLException("no roles data!"); - for (Iterator iterator = usersRoles.iterator(); iterator.hasNext();) { - final UserRole userRole = (UserRole) iterator.next(); - final Role role = (Role) userRole.getAssociatedReference(Role.class); - dbRoles += role.getName() + ","; - dbPermissions += role.getPermissions()+","; - } - if (usersRoles.size() > 0) { - dbRoles = dbRoles.substring(0, dbRoles.length() - 1); - if (dbPermissions.endsWith(",")) - dbPermissions = dbPermissions.substring(0, dbPermissions.length() - 1); - } - dbRoles = dbRoles.toLowerCase(); - dbPermissions = dbPermissions.toLowerCase(); + // Roles + final List usersRoles = UserRole.where(UserRole.class, "user_id = ?", Integer.valueOf(user.getId())); + if (usersRoles == null) + throw new SQLException("no roles data!"); + for (Iterator iterator = usersRoles.iterator(); iterator.hasNext();) { + final UserRole userRole = (UserRole) iterator.next(); + final Role role = (Role) userRole.getAssociatedReference(Role.class); + dbRoles += role.getName() + ","; + dbPermissions += role.getPermissions()+","; + } + if (usersRoles.size() > 0) { + dbRoles = dbRoles.substring(0, dbRoles.length() - 1); + if (dbPermissions.endsWith(",")) + dbPermissions = dbPermissions.substring(0, dbPermissions.length() - 1); + } + dbRoles = dbRoles.toLowerCase(); + dbPermissions = dbPermissions.toLowerCase(); + } + } catch (SQLException e) { final String err = "Server Internal Error - DB is possibly not reachable, check DB configuration - DB Exception: " + e.getMessage(); LOG.error(err, e); userSession.clearUserData(); - String t = LanguageManager.getInstance().translate("base.err.srv.db.title", userSession); - String m = LanguageManager.getInstance().translate("base.err.srv.db.msg", userSession, e.getMessage()); + String t = LanguageManager.getInstance().translate("base.err.srv.db.title", userLang); + String m = LanguageManager.getInstance().translate("base.err.srv.db.msg", userLang, e.getMessage()); return serverResponse(session, ErrorHandler.class, Status.INTERNAL_ERROR, t, m); } finally { try { @@ -780,8 +781,8 @@ else if (postParamUsername != null && postParamUsername.length() != 0) { final String err = "Server Internal Error - Exception: " + e.getMessage(); LOG.error(err, e); userSession.clearUserData(); - String t = LanguageManager.getInstance().translate("base.err.srv.ex.title", userSession); - String m = LanguageManager.getInstance().translate("base.err.srv.ex.msg", userSession, e.getMessage()); + String t = LanguageManager.getInstance().translate("base.err.srv.ex.title", userLang); + String m = LanguageManager.getInstance().translate("base.err.srv.ex.msg", userLang, e.getMessage()); return serverResponse(session, ErrorHandler.class, Status.INTERNAL_ERROR, t, m); } } else { @@ -872,7 +873,7 @@ else if (postParamUsername != null && postParamUsername.length() != 0) { } else { userSession.clearUserData(); // serve login page! - String m = LanguageManager.getInstance().translate("base.err.login.msg", userSession, postParamUsername); + String m = LanguageManager.getInstance().translate("base.err.login.msg", userLang, postParamUsername); return serverResponse(session, this.getHandlerClass("LoginHandler"), "Login", m); } } @@ -1011,6 +1012,7 @@ public static Response serverResponse( return Response.newFixedLengthResponse(Status.NOT_IMPLEMENTED, "text/html", t+m); } BaseHandler handler = null; + try { handler = (BaseHandler) constructor.newInstance(initParameter); } catch (Exception e) { diff --git a/src/main/java/ch/autumo/beetroot/plant/Fertilizer.java b/src/main/java/ch/autumo/beetroot/plant/Fertilizer.java index 71a42475..12fd8e2a 100644 --- a/src/main/java/ch/autumo/beetroot/plant/Fertilizer.java +++ b/src/main/java/ch/autumo/beetroot/plant/Fertilizer.java @@ -119,7 +119,8 @@ public Fertilizer(String dbEntity, String resource, String outputBaseDir, String } catch (SQLException e) { } } - fieldNames = databaseFields.keySet(); + + fieldNames = new FieldSet(databaseFields.keySet()); amountOfFields = fieldNames.size(); } diff --git a/src/main/java/ch/autumo/beetroot/plant/FieldSet.java b/src/main/java/ch/autumo/beetroot/plant/FieldSet.java new file mode 100644 index 00000000..0e954b8f --- /dev/null +++ b/src/main/java/ch/autumo/beetroot/plant/FieldSet.java @@ -0,0 +1,104 @@ +/** + * + * Copyright (c) 2024 autumo Ltd. Switzerland, Michael Gasche + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package ch.autumo.beetroot.plant; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + + +/** + * Field-set does some typical ordering for fields shown in an UI. + */ +public class FieldSet implements Set { + + // Define the priority list with the desired order + final List priorityList = Arrays.asList("id", "name", "description", "type", "category", "created", "modified"); + + private final Set keySet; + + public FieldSet(Set keySet) { + this.keySet = keySet; + } + + @Override + public Iterator iterator() { + // Create a list of keys to be sorted + List sortedKeys = new ArrayList<>(keySet); + + // Sort using a custom comparator with a generic priority list and placeholder for other fields + Collections.sort(sortedKeys, new Comparator() { + @Override + public int compare(K o1, K o2) { + String s1 = o1.toString(); + String s2 = o2.toString(); + + // Check the index of both keys in the priority list + int index1 = priorityList.indexOf(s1); + int index2 = priorityList.indexOf(s2); + + // If both are in the priority list, compare by their order in the list + if (index1 != -1 && index2 != -1) { + return Integer.compare(index1, index2); + } + + // If only one is in the priority list, determine its position + if (index1 != -1) { + // If s1 is "created" or "modified", any non-predefined field should come before them + if (index1 >= priorityList.indexOf("created")) { + return 1; // s1 should come after any non-predefined field + } + return -1; // s1 should come before s2 + } + if (index2 != -1) { + // If s2 is "created" or "modified", any non-predefined field should come before them + if (index2 >= priorityList.indexOf("created")) { + return -1; // s2 should come after any non-predefined field + } + return 1; // s2 should come before s1 + } + + // If both are non-predefined fields, sort them alphanumerically + return s1.compareTo(s2); + } + }); + + // Return an iterator over the sorted keys + return sortedKeys.iterator(); + } + + // Delegate all other Set methods to the underlying keySet + @Override public int size() { return keySet.size(); } + @Override public boolean isEmpty() { return keySet.isEmpty(); } + @Override public boolean contains(Object o) { return keySet.contains(o); } + @Override public Object[] toArray() { return keySet.toArray(); } + @Override public T[] toArray(T[] a) { return keySet.toArray(a); } + @Override public boolean add(K k) { throw new UnsupportedOperationException(); } // keySet is read-only + @Override public boolean remove(Object o) { return keySet.remove(o); } + @Override public boolean containsAll(Collection c) { return keySet.containsAll(c); } + @Override public boolean addAll(Collection c) { throw new UnsupportedOperationException(); } // read-only + @Override public boolean retainAll(Collection c) { return keySet.retainAll(c); } + @Override public boolean removeAll(Collection c) { return keySet.removeAll(c); } + @Override public void clear() { keySet.clear(); } + +}