diff --git a/pom.xml b/pom.xml index dcebe35..ad4231f 100644 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,7 @@ 4.0.0 fish.payara.starter payara-starter-parent - 1.0-beta11 + 1.0-beta12 pom Payara Starter Parent Payara Starter Parent diff --git a/starter-archetype/pom.xml b/starter-archetype/pom.xml index 4473601..8637b9c 100644 --- a/starter-archetype/pom.xml +++ b/starter-archetype/pom.xml @@ -41,14 +41,14 @@ 4.0.0 payara-starter-archetype - 1.0-beta11 + 1.0-beta12 maven-archetype Payara Starter Archetype Archetype for Payara Platform application. fish.payara.starter payara-starter-parent - 1.0-beta11 + 1.0-beta12 ../pom.xml diff --git a/starter-generator/pom.xml b/starter-generator/pom.xml index 5b6cbc6..8785227 100644 --- a/starter-generator/pom.xml +++ b/starter-generator/pom.xml @@ -4,7 +4,7 @@ fish.payara.starter payara-starter-parent - 1.0-beta11 + 1.0-beta12 payara-starter-generator Payara Starter Generator diff --git a/starter-generator/src/main/java/fish/payara/starter/application/domain/Attribute.java b/starter-generator/src/main/java/fish/payara/starter/application/domain/Attribute.java index 6893652..815579b 100644 --- a/starter-generator/src/main/java/fish/payara/starter/application/domain/Attribute.java +++ b/starter-generator/src/main/java/fish/payara/starter/application/domain/Attribute.java @@ -56,9 +56,12 @@ import fish.payara.starter.application.util.AttributeType; import static fish.payara.starter.application.util.AttributeType.LOCAL_DATE; import static fish.payara.starter.application.util.AttributeType.LOCAL_DATE_TIME; -import static fish.payara.starter.application.util.StringHelper.pluralize; -import static fish.payara.starter.application.util.StringHelper.startCase; -import static fish.payara.starter.application.util.StringHelper.titleCase; +import static fish.payara.starter.application.util.StringUtils.firstLower; +import static fish.payara.starter.application.util.StringUtils.firstUpper; +import static fish.payara.starter.application.util.StringUtils.kebabCase; +import static fish.payara.starter.application.util.StringUtils.pluralize; +import static fish.payara.starter.application.util.StringUtils.startCase; +import static fish.payara.starter.application.util.StringUtils.titleCase; import jakarta.json.bind.annotation.JsonbTransient; import jakarta.json.bind.annotation.JsonbTypeSerializer; import java.util.ArrayList; @@ -109,7 +112,7 @@ public Attribute(String name, boolean multi, String relation) { this.type = relation; this.multi = multi; } - + /** * Returns the name of the attribute. * @@ -129,16 +132,6 @@ public String getStartCaseName() { return startCase(name); } - /** - * Returns the name of the attribute in lower case format. - * - * @return the lower case name - */ - @JsonbTransient - public String getLowerCaseName() { - return name.toLowerCase(); - } - /** * Returns the name of the attribute in title case format. * @@ -146,27 +139,7 @@ public String getLowerCaseName() { */ @JsonbTransient public String getTitleCaseName() { - return titleCase(name); - } - - /** - * Returns the pluralized lower case name of the attribute. - * - * @return the pluralized lower case name - */ - @JsonbTransient - public String getLowerCasePluralizeName() { - return pluralize(name.toLowerCase()); - } - - /** - * Returns the pluralized title case name of the attribute. - * - * @return the pluralized title case name - */ - @JsonbTransient - public String getTitleCasePluralizeName() { - return pluralize(titleCase(name)); + return firstUpper(name); } /** @@ -344,6 +317,10 @@ public void setMulti(boolean multi) { this.multi = multi; } + public String getApiUrl() { + return kebabCase(firstLower(type)); + } + @Override public String toString() { return "\n\t\tAttribute{name=" + name + ", type=" + type + ", isPrimaryKey=" + primaryKey + '}'; diff --git a/starter-generator/src/main/java/fish/payara/starter/application/domain/ERModel.java b/starter-generator/src/main/java/fish/payara/starter/application/domain/ERModel.java index f1cd35f..76b8d4b 100644 --- a/starter-generator/src/main/java/fish/payara/starter/application/domain/ERModel.java +++ b/starter-generator/src/main/java/fish/payara/starter/application/domain/ERModel.java @@ -97,7 +97,8 @@ public void addEntity(Entity entity) { public Entity getEntity(String entityName) { for (Entity entity : entities) { - if (entity.getName().equals(entityName)) { + if (entity.getName().equals(entityName) + || entity.getClassName().equals(entityName)) { return entity; } } diff --git a/starter-generator/src/main/java/fish/payara/starter/application/domain/Entity.java b/starter-generator/src/main/java/fish/payara/starter/application/domain/Entity.java index 331285b..bc5e812 100644 --- a/starter-generator/src/main/java/fish/payara/starter/application/domain/Entity.java +++ b/starter-generator/src/main/java/fish/payara/starter/application/domain/Entity.java @@ -53,10 +53,9 @@ */ package fish.payara.starter.application.domain; -import static fish.payara.starter.application.util.StringHelper.firstUpper; -import static fish.payara.starter.application.util.StringHelper.pluralize; -import static fish.payara.starter.application.util.StringHelper.startCase; -import static fish.payara.starter.application.util.StringHelper.titleCase; +import static fish.payara.starter.application.util.StringUtils.firstUpper; +import static fish.payara.starter.application.util.StringUtils.startCase; +import static fish.payara.starter.application.util.StringUtils.titleCase; import jakarta.json.bind.annotation.JsonbTransient; import java.util.ArrayList; import java.util.List; @@ -111,16 +110,6 @@ public String getTitleCaseName() { return titleCase(getClassName()); } - @JsonbTransient - public String getLowerCasePluralizeName() { - return pluralize(getLowerCaseName()); - } - - @JsonbTransient - public String getTitleCasePluralizeName() { - return pluralize(getTitle()); - } - public List getAttributes() { return attributes; } diff --git a/starter-generator/src/main/java/fish/payara/starter/application/generator/CRUDAppGenerator.java b/starter-generator/src/main/java/fish/payara/starter/application/generator/CRUDAppGenerator.java index 59b30b0..9ff7acf 100644 --- a/starter-generator/src/main/java/fish/payara/starter/application/generator/CRUDAppGenerator.java +++ b/starter-generator/src/main/java/fish/payara/starter/application/generator/CRUDAppGenerator.java @@ -62,12 +62,13 @@ import static fish.payara.starter.application.util.JPAUtil.ALL_RESERVED_KEYWORDS; import static fish.payara.starter.application.util.JavaUtil.getIntrospectionPrefix; import static fish.payara.starter.application.util.JavaUtil.getMethodName; -import static fish.payara.starter.application.util.StringHelper.firstLower; -import static fish.payara.starter.application.util.StringHelper.firstUpper; -import static fish.payara.starter.application.util.StringHelper.kebabCase; -import static fish.payara.starter.application.util.StringHelper.pluralize; -import static fish.payara.starter.application.util.StringHelper.startCase; -import static fish.payara.starter.application.util.StringHelper.titleCase; +import static fish.payara.starter.application.util.StringUtils.firstLower; +import static fish.payara.starter.application.util.StringUtils.firstUpper; +import static fish.payara.starter.application.util.StringUtils.kebabCase; +import static fish.payara.starter.application.util.StringUtils.pluralize; +import static fish.payara.starter.application.util.StringUtils.singularize; +import static fish.payara.starter.application.util.StringUtils.startCase; +import static fish.payara.starter.application.util.StringUtils.titleCase; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; @@ -107,8 +108,8 @@ public CRUDAppGenerator(ERModel model, String _package, String domainLayer, Stri } public static void main(String[] args) { - String mermaidCode = """ -erDiagram + String mermaidCode = """ + erDiagram DEPARTMENT ||--o{ IT_EMPLOYEE : belongs_to IT_EMPLOYEE { int employeeID PK @@ -267,9 +268,6 @@ private void generateEntityController(String _package, Entity entity, File outpu String pkName = entity.getPrimaryKeyName(); String pkType = entity.getPrimaryKeyType(); dataModel.put("pkName", firstLower(pkName)); -// System.out.println("getIntrospectionPrefix " + getIntrospectionPrefix(isBoolean(pkType))); -// System.out.println("pkType " + pkType); -// System.out.println("pkName " + pkName); dataModel.put("pkGetter", getMethodName(getIntrospectionPrefix(isBoolean(pkType)), pkName)); dataModel.put("pkSetter", getMethodName("set", pkName)); dataModel.put("pkType", pkType); @@ -504,65 +502,76 @@ private void appendRelationship(StringBuilder sb, StringBuilder sbfunc, Set get").append(pluralize(secondEntity)).append("() {\n"); - sbfunc.append(" return ").append(pluralize(secondEntity.toLowerCase())).append(";\n"); + attribute = new Attribute(firstEntityVars, true, secondEntity); + entity.getAttributes().add(attribute); + sbfunc.append(" public List<").append(attribute.getType()).append("> get").append(attribute.getTitleCaseName()).append("() {\n"); + sbfunc.append(" return ").append(attribute.getName()).append(";\n"); sbfunc.append(" }\n\n"); - sbfunc.append(" public void set").append(pluralize(secondEntity)).append("(List<").append(secondEntity).append("> ").append(pluralize(secondEntity.toLowerCase())).append(") {\n"); - sbfunc.append(" this.").append(pluralize(secondEntity.toLowerCase())).append(" = ").append(pluralize(secondEntity.toLowerCase())).append(";\n"); + sbfunc.append(" public void set").append(attribute.getTitleCaseName()).append("(List<").append(attribute.getType()).append("> ").append(attribute.getName()).append(") {\n"); + sbfunc.append(" this.").append(attribute.getName()).append(" = ").append(attribute.getName()).append(";\n"); sbfunc.append(" }\n\n"); _imports.add(model.getImportPrefix() + ".json.bind.annotation.JsonbTransient"); _imports.add("java.util.List"); sb.append(" @JsonbTransient\n"); - sb.append(" @OneToMany(mappedBy = \"").append(firstEntity.toLowerCase()).append("\")\n"); - sb.append(" private List<").append(secondEntity).append("> ").append(pluralize(secondEntity.toLowerCase())).append(";\n"); + sb.append(" @OneToMany(mappedBy = \"").append(secondEntityVar).append("\")\n"); + sb.append(" private List<").append(attribute.getType()).append("> ").append(attribute.getName()).append(";\n"); break; case "}|--||": // One or more to exactly one case "}o--||": // Zero or more to exactly one - entity.getAttributes().add(new Attribute(secondEntity.toLowerCase(), false, secondEntity)); - sbfunc.append(" public ").append(secondEntity).append(" get").append(secondEntity).append("() {\n"); - sbfunc.append(" return ").append(secondEntity.toLowerCase()).append(";\n"); + attribute = new Attribute(firstEntityVar, false, secondEntity); + entity.getAttributes().add(attribute); + sbfunc.append(" public ").append(attribute.getType()).append(" get").append(attribute.getTitleCaseName()).append("() {\n"); + sbfunc.append(" return ").append(attribute.getName()).append(";\n"); sbfunc.append(" }\n\n"); - sbfunc.append(" public void set").append(secondEntity).append("(").append(secondEntity).append(" ").append(secondEntity.toLowerCase()).append(") {\n"); - sbfunc.append(" this.").append(secondEntity.toLowerCase()).append(" = ").append(secondEntity.toLowerCase()).append(";\n"); + sbfunc.append(" public void set").append(attribute.getTitleCaseName()).append("(").append(attribute.getType()).append(" ").append(attribute.getName()).append(") {\n"); + sbfunc.append(" this.").append(attribute.getName()).append(" = ").append(attribute.getName()).append(";\n"); sbfunc.append(" }\n\n"); - sb.append(" @ManyToOne(mappedBy = \"").append(firstEntity.toLowerCase()).append("\")\n"); - sb.append(" private ").append(secondEntity).append(" ").append(secondEntity.toLowerCase()).append(";\n"); + sb.append(" @ManyToOne\n"); + sb.append(" private ").append(attribute.getType()).append(" ").append(attribute.getName()).append(";\n"); break; case "}o--o{": // Zero or more to zero or more case "}|--o{": // One or more to zero or more case "}o--|{": // Zero or more to one or more case "}|--|{": // One or more to one or more -// entity.getAttributes().add(new Attribute(secondEntity.toLowerCase(), secondEntityObj, true, relationship.getProperty())); - sbfunc.append(" public List<").append(secondEntity).append("> get").append(pluralize(secondEntity)).append("() {\n"); - sbfunc.append(" return ").append(pluralize(secondEntity.toLowerCase())).append(";\n"); + attribute = new Attribute(firstEntityVars, true, secondEntity); + entity.getAttributes().add(attribute); + sbfunc.append(" public List<").append(attribute.getType()).append("> get").append(attribute.getTitleCaseName()).append("() {\n"); + sbfunc.append(" return ").append(attribute.getName()).append(";\n"); sbfunc.append(" }\n\n"); - sbfunc.append(" public void set").append(pluralize(secondEntity)).append("(List<").append(secondEntity).append("> ").append(pluralize(secondEntity.toLowerCase())).append(") {\n"); - sbfunc.append(" this.").append(pluralize(secondEntity.toLowerCase())).append(" = ").append(pluralize(secondEntity.toLowerCase())).append(";\n"); + sbfunc.append(" public void set").append(attribute.getTitleCaseName()).append("(List<").append(attribute.getType()).append("> ").append(attribute.getName()).append(") {\n"); + sbfunc.append(" this.").append(attribute.getName()).append(" = ").append(attribute.getName()).append(";\n"); sbfunc.append(" }\n\n"); _imports.add(model.getImportPrefix() + ".json.bind.annotation.JsonbTransient"); _imports.add("java.util.List"); sb.append(" @JsonbTransient\n"); - sb.append(" @ManyToMany(mappedBy = \"").append(firstEntity.toLowerCase()).append("\")\n"); - sb.append(" private List<").append(secondEntity).append("> ").append(pluralize(secondEntity.toLowerCase())).append(";\n"); + sb.append(" @ManyToMany(mappedBy = \"").append(secondEntityVars).append("\")\n"); + sb.append(" private List<").append(attribute.getType()).append("> ").append(attribute.getName()).append(";\n"); break; } } else { @@ -570,55 +579,58 @@ private void appendRelationship(StringBuilder sb, StringBuilder sbfunc, Set get").append(pluralize(firstEntity)).append("() {\n"); - sbfunc.append(" return ").append(pluralize(firstEntity.toLowerCase())).append(";\n"); + attribute = new Attribute(secondEntityVars, true, firstEntity); + entity.getAttributes().add(attribute); + sbfunc.append(" public List<").append(attribute.getType()).append("> get").append(attribute.getTitleCaseName()).append("() {\n"); + sbfunc.append(" return ").append(attribute.getName()).append(";\n"); sbfunc.append(" }\n\n"); - sbfunc.append(" public void set").append(pluralize(firstEntity)).append("(List<").append(firstEntity).append("> ").append(pluralize(firstEntity.toLowerCase())).append(") {\n"); - sbfunc.append(" this.").append(pluralize(firstEntity.toLowerCase())).append(" = ").append(pluralize(firstEntity.toLowerCase())).append(";\n"); + sbfunc.append(" public void set").append(attribute.getTitleCaseName()).append("(List<").append(attribute.getType()).append("> ").append(attribute.getName()).append(") {\n"); + sbfunc.append(" this.").append(attribute.getName()).append(" = ").append(attribute.getName()).append(";\n"); sbfunc.append(" }\n\n"); _imports.add(model.getImportPrefix() + ".json.bind.annotation.JsonbTransient"); _imports.add("java.util.List"); sb.append(" @JsonbTransient\n"); sb.append(" @ManyToMany\n"); - sb.append(" @JoinColumn(name = \"").append(firstEntity.toLowerCase()).append("_id\")\n"); - sb.append(" private List<").append(firstEntity).append("> ").append(pluralize(firstEntity.toLowerCase())).append(";\n"); + sb.append(" @JoinColumn(name = \"").append(secondEntityVar).append("_id\")\n"); + sb.append(" private List<").append(attribute.getType()).append("> ").append(attribute.getName()).append(";\n"); break; } } diff --git a/starter-generator/src/main/java/fish/payara/starter/application/generator/ERDiagramParser.java b/starter-generator/src/main/java/fish/payara/starter/application/generator/ERDiagramParser.java index 9064b09..eb152f6 100644 --- a/starter-generator/src/main/java/fish/payara/starter/application/generator/ERDiagramParser.java +++ b/starter-generator/src/main/java/fish/payara/starter/application/generator/ERDiagramParser.java @@ -59,7 +59,7 @@ import fish.payara.starter.application.domain.Attribute; import static fish.payara.starter.application.util.AttributeType.getWrapperType; import fish.payara.starter.application.util.MermaidUtil; -import static fish.payara.starter.application.util.StringHelper.titleCase; +import static fish.payara.starter.application.util.StringUtils.titleCase; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -106,6 +106,9 @@ public ERModel parse(String mermaidCode) { if (attrMatcher.find()) { String type = attrMatcher.group(1); String name = attrMatcher.group(2); + if(name.equals(name.toUpperCase())) { + name = name.toLowerCase(); + } String keyType = attrMatcher.group(3); boolean isPrimaryKey = "PK".equals(keyType); boolean isForeignKey = "FK".equals(keyType); diff --git a/starter-generator/src/main/java/fish/payara/starter/application/util/AttributeType.java b/starter-generator/src/main/java/fish/payara/starter/application/util/AttributeType.java index 014a767..80145a3 100644 --- a/starter-generator/src/main/java/fish/payara/starter/application/util/AttributeType.java +++ b/starter-generator/src/main/java/fish/payara/starter/application/util/AttributeType.java @@ -305,7 +305,7 @@ public static String getArrayType(String type) { } public static boolean isArray(String type) { - if (StringHelper.isEmpty(type) || type.length() < 3) { + if (StringUtils.isEmpty(type) || type.length() < 3) { return false; } return type.charAt(type.length() - 2) == '[' && type.charAt(type.length() - 1) == ']'; diff --git a/starter-generator/src/main/java/fish/payara/starter/application/util/JavaUtil.java b/starter-generator/src/main/java/fish/payara/starter/application/util/JavaUtil.java index f384e3f..fdba2bb 100644 --- a/starter-generator/src/main/java/fish/payara/starter/application/util/JavaUtil.java +++ b/starter-generator/src/main/java/fish/payara/starter/application/util/JavaUtil.java @@ -53,8 +53,8 @@ */ package fish.payara.starter.application.util; -import static fish.payara.starter.application.util.StringHelper.EMPTY; -import static fish.payara.starter.application.util.StringHelper.isNotBlank; +import static fish.payara.starter.application.util.StringUtils.EMPTY; +import static fish.payara.starter.application.util.StringUtils.isNotBlank; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; @@ -198,7 +198,7 @@ public static String getFieldName(String methodName) { } else { return null; } - fieldName = StringHelper.firstLower(fieldName); + fieldName = StringUtils.firstLower(fieldName); return fieldName; } @@ -211,7 +211,7 @@ public static String getFieldNameFromDelegatorMethod(String methodName) { } else { return null; } - fieldName = StringHelper.firstLower(fieldName); + fieldName = StringUtils.firstLower(fieldName); return fieldName; } diff --git a/starter-generator/src/main/java/fish/payara/starter/application/util/StringHelper.java b/starter-generator/src/main/java/fish/payara/starter/application/util/StringHelper.java deleted file mode 100644 index 9f98d3e..0000000 --- a/starter-generator/src/main/java/fish/payara/starter/application/util/StringHelper.java +++ /dev/null @@ -1,522 +0,0 @@ -/** - * Copyright 2013-2022 the original author or authors from the Jeddict project (https://jeddict.github.io/). - * - * 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. - */ -/* - * - * Copyright (c) 2024 Payara Foundation and/or its affiliates. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common Development - * and Distribution License("CDDL") (collectively, the "License"). You - * may not use this file except in compliance with the License. You can - * obtain a copy of the License at - * https://github.com/payara/Payara/blob/master/LICENSE.txt - * See the License for the specific - * language governing permissions and limitations under the License. - * - * When distributing the software, include this License Header Notice in each - * file and include the License file at glassfish/legal/LICENSE.txt. - * - * GPL Classpath Exception: - * The Payara Foundation designates this particular file as subject to the "Classpath" - * exception as provided by the Payara Foundation in the GPL Version 2 section of the License - * file that accompanied this code. - * - * Modifications: - * If applicable, add the following below the License Header, with the fields - * enclosed by brackets [] replaced by your own identifying information: - * "Portions Copyright [year] [name of copyright owner]" - * - * Contributor(s): - * If you wish your version of this file to be governed by only the CDDL or - * only the GPL Version 2, indicate your decision by adding "[Contributor] - * elects to include this software in this distribution under the [CDDL or GPL - * Version 2] license." If you don't indicate a single choice of license, a - * recipient has the option to distribute your version of this file under - * either the CDDL, the GPL Version 2 or to extend the choice of license to - * its licensees as provided above. However, if you add GPL Version 2 code - * and therefore, elected the GPL Version 2 license, then the option applies - * only if the new code is made subject to such option by the copyright - * holder. - */ -package fish.payara.starter.application.util; - -import java.util.function.Predicate; - -public final class StringHelper { - - //(\\s+) space - //(?<=[a-z])(?=[A-Z]) => eclipseRCPExt -> eclipse / RCPExt - //(?<=[A-Z])(?=[A-Z][a-z]) => eclipseRCPExt -> eclipse / RCP / Ext - public final static String NATURAL_TEXT_SPLITTER = "(\\s+)|(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])"; - - public static String firstLower(String string) { - if (isBlank(string)) { - return EMPTY; - } - boolean makeFirstLower = string.length() < 2 || (!Character.isUpperCase(string.charAt(1))); - return makeFirstLower ? string.substring(0, 1).toLowerCase() + string.substring(1) : string; - } - - public static String firstUpper(String string) { - if (isBlank(string)) { - return EMPTY; - } - return string.length() > 1 ? string.substring(0, 1).toUpperCase() + string.substring(1) : string.toUpperCase(); - } - - public static String titleCase(String string) { - if (isBlank(string)) { - return EMPTY; - } - return string.length() > 1 ? string.substring(0, 1).toUpperCase() + string.substring(1).toLowerCase() : string.toUpperCase(); - } - - /** - * Converts `string` to [start case] - * - * startCase('--foo-bar--') => 'Foo Bar' startCase('fooBar') => 'Foo Bar' - * startCase('__FOO_BAR__') => 'FOO BAR' - * - * @param content - * @return - * - */ - public static String startCase(String content) { - StringBuilder result = new StringBuilder(); - content = content.replaceFirst("[^a-zA-Z0-9]+", EMPTY); - for (String word : content.replaceAll("[^a-zA-Z0-9]", " ").split(NATURAL_TEXT_SPLITTER)) { - result.append(firstUpper(word)).append(" "); - } - result.setLength(result.length() - 1); - return result.toString(); - } - - /** - * Converts `string` to [snake case] - * Foo Bar > 'foo_bar', fooBar > 'foo_bar', --FOO-BAR-- > 'foo_bar' - * - * @param content - * @return - */ - public static String snakeCase(String content) { - StringBuilder result = new StringBuilder(); - content = content.replaceFirst("[^a-zA-Z0-9]+", EMPTY); - for (String word : content.replaceAll("[^a-zA-Z0-9]", " ").split(NATURAL_TEXT_SPLITTER)) { - result.append(word.toLowerCase()).append("_"); - } - result.setLength(result.length() - 1); - return result.toString(); - } - - /** - * Converts `string` to [kebab case] - * 'Foo Bar > 'foo-bar', 'fooBar' > 'foo-bar', '__FOO_BAR__' > 'foo-bar' - * - * @param content - * @return - * - */ - public static String kebabCase(String content) { - StringBuilder result = new StringBuilder(); - content = content.replaceFirst("[^a-zA-Z0-9]+", EMPTY); - for (String word : content.replaceAll("[^a-zA-Z0-9]", " ").split(NATURAL_TEXT_SPLITTER)) { - result.append(word.toLowerCase()).append("-"); - } - result.setLength(result.length() - 1); - return result.toString(); - } - - /** - * Removes leading and trailing whitespace or specified characters from - * `string`. - * - * _.trim(' abc ', ' '); // => 'abc' - * - * _.trim('_abc_', '_'); // => 'abc' - * - * @param content - * @param trimmer - * @return - * - */ - public static String trim(String content, char trimmer) { - char value[] = content.toCharArray(); - int len = value.length; - int st = 0; - char[] val = value; - /* avoid getfield opcode */ - - while ((st < len) && (val[st] == trimmer)) { - st++; - } - while ((st < len) && (val[len - 1] == trimmer)) { - len--; - } - return ((st > 0) || (len < value.length)) ? content.substring(st, len) : content; - } - - /** - * Converts `string` to [camel case] - * - * 'Foo Bar > 'fooBar', '--foo-bar--' > 'fooBar', '__FOO_BAR__ > 'fooBar' - * - * @param content - * @return - */ - public static String camelCase(String content) { - StringBuilder result = new StringBuilder(); -// content = content.replaceFirst("[^a-zA-Z0-9]+", EMPTY);//issue job-history => jobhistory - int i = 0; - for (String word : content.replaceAll("[^a-zA-Z0-9]", " ").split(NATURAL_TEXT_SPLITTER)) { - word = word.toLowerCase(); - if (i == 0) { - result.append(word); - } else { - result.append(firstUpper(word)); - } - i++; - } - return result.toString(); - } - - /** - * Convert to natural language - * BankAccount => Bank Account Bank_Account => Bank_Account - * - * @param input - * @return - * - */ - public static String toNatural(String input) { - String natural = EMPTY; - Character lastChar = null; - for (Character curChar : input.toCharArray()) { - if (lastChar == null) { - // First character - lastChar = Character.toUpperCase(curChar); - natural = natural + lastChar; - - } else { - if (Character.isLowerCase(lastChar) - && (Character.isUpperCase(curChar)) || Character.isDigit(curChar)) { - natural = natural + " " + curChar; - } else { - natural = natural + curChar; - } - lastChar = curChar; - } - - } - return natural; - } - - /** - * Convert to constant - * BankAccount => BANK_ACCOUNT Bank_Account => BANK_ACCOUNT - * @param input - * @return - * - */ - public static String toConstant(String input) { - String constant = EMPTY; - Character lastChar = null; - for (Character curChar : input.toCharArray()) { - if (lastChar == null) { - // First character - lastChar = Character.toUpperCase(curChar); - constant = constant + lastChar; - - } else { - if (Character.isLowerCase(lastChar) - && (Character.isUpperCase(curChar) || Character.isDigit(curChar))) { - constant = constant + '_' + curChar; - } else { - constant = constant + Character.toUpperCase(curChar); - } - lastChar = curChar; - } - - } - return constant; - } - - public static String getNext(String name, Predicate checkExist) { - return getNext(name, checkExist, false); - } - - public static String getNext(String name, Predicate checkExist, boolean increment) { - int index = 0; - String nextName; - if (increment) { - nextName = name + ++index; - } else { - nextName = name; - } - boolean isExist = true; - while (isExist) { - if (checkExist.test(nextName)) { - isExist = true; - nextName = name + ++index; - } else { - return nextName; - } - } - return nextName; - } - - public static String singularize(String name) { - return Inflector.getInstance().singularize(name); - } - - public static final String COLLECTION = "Collection"; - - public static String pluralize(String name) { - String pluralName = Inflector.getInstance().pluralize(name); - - if (name.equals(pluralName)) { - return name + COLLECTION; - } else { - return pluralName; - } - } - - public static String padRight(String s, int n) { - return String.format("%1$-" + n + "s", s); - } - - public static String padLeft(String s, int n) { - return String.format("%1$" + n + "s", s); - } - - public static boolean compareNonWhitespaces(String v1, String v2) { - return v1 != null && v2 != null - && v1.replaceAll("\\s+", "") - .equals(v2.replaceAll("\\s+", "")); - } - - public static final String SPACE = " "; - - public static final String EMPTY = ""; - - public static final String LF = "\n"; - - public static final String CR = "\r"; - - private static final int PAD_LIMIT = 8192; - - public static boolean isBlank(final CharSequence cs) { - int strLen; - if (cs == null || (strLen = cs.length()) == 0) { - return true; - } - for (int i = 0; i < strLen; i++) { - if (!Character.isWhitespace(cs.charAt(i))) { - return false; - } - } - return true; - } - - public static boolean isNotBlank(final CharSequence cs) { - return !isBlank(cs); - } - - public static boolean isEmpty(Object str) { - return (str == null || "".equals(str)); - } - - public static boolean isNotEmpty(final CharSequence cs) { - return !isEmpty(cs); - } - - public static boolean equals(final CharSequence cs1, final CharSequence cs2) { - if (cs1 == cs2) { - return true; - } - if (cs1 == null || cs2 == null) { - return false; - } - if (cs1.length() != cs2.length()) { - return false; - } - if (cs1 instanceof String && cs2 instanceof String) { - return cs1.equals(cs2); - } - // Step-wise comparison - final int length = cs1.length(); - for (int i = 0; i < length; i++) { - if (cs1.charAt(i) != cs2.charAt(i)) { - return false; - } - } - return true; - } - - public static boolean equalsIgnoreCase(final CharSequence cs1, final CharSequence cs2) { - if (cs1 == cs2) { - return true; - } - if (cs1 == null || cs2 == null) { - return false; - } - if (cs1.length() != cs2.length()) { - return false; - } - return regionMatches(cs1, true, 0, cs2, 0, cs1.length()); - } - - public static boolean containsIgnoreCase(final CharSequence str, final CharSequence searchStr) { - if (str == null || searchStr == null) { - return false; - } - final int len = searchStr.length(); - final int max = str.length() - len; - for (int i = 0; i <= max; i++) { - if (regionMatches(str, true, i, searchStr, 0, len)) { - return true; - } - } - return false; - } - - public static String deleteWhitespace(final String str) { - if (isEmpty(str)) { - return str; - } - final int sz = str.length(); - final char[] chs = new char[sz]; - int count = 0; - for (int i = 0; i < sz; i++) { - if (!Character.isWhitespace(str.charAt(i))) { - chs[count++] = str.charAt(i); - } - } - if (count == sz) { - return str; - } - return new String(chs, 0, count); - } - - public static String trim(final String str) { - return str == null ? null : str.trim(); - } - - public static String leftPad(final String str, final int size) { - return leftPad(str, size, ' '); - } - - public static String leftPad(final String str, final int size, final char padChar) { - if (str == null) { - return null; - } - final int pads = size - str.length(); - if (pads <= 0) { - return str; // returns original String when possible - } - if (pads > PAD_LIMIT) { - return leftPad(str, size, String.valueOf(padChar)); - } - return repeat(padChar, pads).concat(str); - } - - public static String leftPad(final String str, final int size, String padStr) { - if (str == null) { - return null; - } - if (isEmpty(padStr)) { - padStr = SPACE; - } - final int padLen = padStr.length(); - final int strLen = str.length(); - final int pads = size - strLen; - if (pads <= 0) { - return str; // returns original String when possible - } - if (padLen == 1 && pads <= PAD_LIMIT) { - return leftPad(str, size, padStr.charAt(0)); - } - - if (pads == padLen) { - return padStr.concat(str); - } else if (pads < padLen) { - return padStr.substring(0, pads).concat(str); - } else { - final char[] padding = new char[pads]; - final char[] padChars = padStr.toCharArray(); - for (int i = 0; i < pads; i++) { - padding[i] = padChars[i % padLen]; - } - return new String(padding).concat(str); - } - } - - public static String repeat(final char ch, final int repeat) { - if (repeat <= 0) { - return EMPTY; - } - final char[] buf = new char[repeat]; - for (int i = repeat - 1; i >= 0; i--) { - buf[i] = ch; - } - return new String(buf); - } - - static boolean regionMatches(final CharSequence cs, final boolean ignoreCase, final int thisStart, - final CharSequence substring, final int start, final int length) { - if (cs instanceof String && substring instanceof String) { - return ((String) cs).regionMatches(ignoreCase, thisStart, (String) substring, start, length); - } - int index1 = thisStart; - int index2 = start; - int tmpLen = length; - - // Extract these first so we detect NPEs the same as the java.lang.String version - final int srcLen = cs.length() - thisStart; - final int otherLen = substring.length() - start; - - // Check for invalid parameters - if (thisStart < 0 || start < 0 || length < 0) { - return false; - } - - // Check that the regions are long enough - if (srcLen < length || otherLen < length) { - return false; - } - - while (tmpLen-- > 0) { - final char c1 = cs.charAt(index1++); - final char c2 = substring.charAt(index2++); - - if (c1 == c2) { - continue; - } - - if (!ignoreCase) { - return false; - } - - // The same check as in String.regionMatches(): - if (Character.toUpperCase(c1) != Character.toUpperCase(c2) - && Character.toLowerCase(c1) != Character.toLowerCase(c2)) { - return false; - } - } - - return true; - } - -} diff --git a/starter-generator/src/main/java/fish/payara/starter/application/util/StringUtils.java b/starter-generator/src/main/java/fish/payara/starter/application/util/StringUtils.java index efc56a2..e3cc3eb 100644 --- a/starter-generator/src/main/java/fish/payara/starter/application/util/StringUtils.java +++ b/starter-generator/src/main/java/fish/payara/starter/application/util/StringUtils.java @@ -1,3 +1,18 @@ +/** + * Copyright 2013-2022 the original author or authors from the Jeddict project (https://jeddict.github.io/). + * + * 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. + */ /* * * Copyright (c) 2024 Payara Foundation and/or its affiliates. All rights reserved. @@ -38,11 +53,475 @@ */ package fish.payara.starter.application.util; -/** - * - * @author Gaurav Gupta - */ -public class StringUtils { +import java.util.function.Predicate; + +public final class StringUtils { + + //(\\s+) space + //(?<=[a-z])(?=[A-Z]) => eclipseRCPExt -> eclipse / RCPExt + //(?<=[A-Z])(?=[A-Z][a-z]) => eclipseRCPExt -> eclipse / RCP / Ext + public final static String NATURAL_TEXT_SPLITTER = "(\\s+)|(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])"; + + public static String firstLower(String string) { + if (isBlank(string)) { + return EMPTY; + } + boolean makeFirstLower = string.length() < 2 || (!Character.isUpperCase(string.charAt(1))); + return makeFirstLower ? string.substring(0, 1).toLowerCase() + string.substring(1) : string; + } + + public static String firstUpper(String string) { + if (isBlank(string)) { + return EMPTY; + } + return string.length() > 1 ? string.substring(0, 1).toUpperCase() + string.substring(1) : string.toUpperCase(); + } + + public static String titleCase(String string) { + if (isBlank(string)) { + return EMPTY; + } + return string.length() > 1 ? string.substring(0, 1).toUpperCase() + string.substring(1).toLowerCase() : string.toUpperCase(); + } + + /** + * Converts `string` to [start case] + * + * startCase('--foo-bar--') => 'Foo Bar' startCase('fooBar') => 'Foo Bar' + * startCase('__FOO_BAR__') => 'FOO BAR' + * + * @param content + * @return + * + */ + public static String startCase(String content) { + StringBuilder result = new StringBuilder(); + content = content.replaceFirst("[^a-zA-Z0-9]+", EMPTY); + for (String word : content.replaceAll("[^a-zA-Z0-9]", " ").split(NATURAL_TEXT_SPLITTER)) { + result.append(firstUpper(word)).append(" "); + } + result.setLength(result.length() - 1); + return result.toString(); + } + + /** + * Converts `string` to [snake case] Foo Bar > 'foo_bar', fooBar > + * 'foo_bar', --FOO-BAR-- > 'foo_bar' + * + * @param content + * @return + */ + public static String snakeCase(String content) { + StringBuilder result = new StringBuilder(); + content = content.replaceFirst("[^a-zA-Z0-9]+", EMPTY); + for (String word : content.replaceAll("[^a-zA-Z0-9]", " ").split(NATURAL_TEXT_SPLITTER)) { + result.append(word.toLowerCase()).append("_"); + } + result.setLength(result.length() - 1); + return result.toString(); + } + + /** + * Converts `string` to [kebab case] 'Foo Bar > 'foo-bar', 'fooBar' > + * 'foo-bar', '__FOO_BAR__' > 'foo-bar' + * + * @param content + * @return + * + */ + public static String kebabCase(String content) { + StringBuilder result = new StringBuilder(); + content = content.replaceFirst("[^a-zA-Z0-9]+", EMPTY); + for (String word : content.replaceAll("[^a-zA-Z0-9]", " ").split(NATURAL_TEXT_SPLITTER)) { + result.append(word.toLowerCase()).append("-"); + } + result.setLength(result.length() - 1); + return result.toString(); + } + + /** + * Removes leading and trailing whitespace or specified characters from + * `string`. + * + * _.trim(' abc ', ' '); // => 'abc' + * + * _.trim('_abc_', '_'); // => 'abc' + * + * @param content + * @param trimmer + * @return + * + */ + public static String trim(String content, char trimmer) { + char value[] = content.toCharArray(); + int len = value.length; + int st = 0; + char[] val = value; + /* avoid getfield opcode */ + + while ((st < len) && (val[st] == trimmer)) { + st++; + } + while ((st < len) && (val[len - 1] == trimmer)) { + len--; + } + return ((st > 0) || (len < value.length)) ? content.substring(st, len) : content; + } + + /** + * Converts `string` to [camel case] + * + * 'Foo Bar > 'fooBar', '--foo-bar--' > 'fooBar', '__FOO_BAR__ > 'fooBar' + * + * @param content + * @return + */ + public static String camelCase(String content) { + StringBuilder result = new StringBuilder(); +// content = content.replaceFirst("[^a-zA-Z0-9]+", EMPTY);//issue job-history => jobhistory + int i = 0; + for (String word : content.replaceAll("[^a-zA-Z0-9]", " ").split(NATURAL_TEXT_SPLITTER)) { + word = word.toLowerCase(); + if (i == 0) { + result.append(word); + } else { + result.append(firstUpper(word)); + } + i++; + } + return result.toString(); + } + + /** + * Convert to natural language BankAccount => Bank Account Bank_Account => + * Bank_Account + * + * @param input + * @return + * + */ + public static String toNatural(String input) { + String natural = EMPTY; + Character lastChar = null; + for (Character curChar : input.toCharArray()) { + if (lastChar == null) { + // First character + lastChar = Character.toUpperCase(curChar); + natural = natural + lastChar; + + } else { + if (Character.isLowerCase(lastChar) + && (Character.isUpperCase(curChar)) || Character.isDigit(curChar)) { + natural = natural + " " + curChar; + } else { + natural = natural + curChar; + } + lastChar = curChar; + } + + } + return natural; + } + + /** + * Convert to constant BankAccount => BANK_ACCOUNT Bank_Account => + * BANK_ACCOUNT + * + * @param input + * @return + * + */ + public static String toConstant(String input) { + String constant = EMPTY; + Character lastChar = null; + for (Character curChar : input.toCharArray()) { + if (lastChar == null) { + // First character + lastChar = Character.toUpperCase(curChar); + constant = constant + lastChar; + + } else { + if (Character.isLowerCase(lastChar) + && (Character.isUpperCase(curChar) || Character.isDigit(curChar))) { + constant = constant + '_' + curChar; + } else { + constant = constant + Character.toUpperCase(curChar); + } + lastChar = curChar; + } + + } + return constant; + } + + public static String getNext(String name, Predicate checkExist) { + return getNext(name, checkExist, false); + } + + public static String getNext(String name, Predicate checkExist, boolean increment) { + int index = 0; + String nextName; + if (increment) { + nextName = name + ++index; + } else { + nextName = name; + } + boolean isExist = true; + while (isExist) { + if (checkExist.test(nextName)) { + isExist = true; + nextName = name + ++index; + } else { + return nextName; + } + } + return nextName; + } + + public static String singularize(String name) { + return Inflector.getInstance().singularize(name); + } + + public static final String COLLECTION = "Collection"; + + public static String pluralize(String name) { + if(name.endsWith("s")) { + return name; + } + String pluralName = Inflector.getInstance().pluralize(name); + + if (name.equals(pluralName)) { + return name + COLLECTION; + } else { + return pluralName; + } + } + + public static String padRight(String s, int n) { + return String.format("%1$-" + n + "s", s); + } + + public static String padLeft(String s, int n) { + return String.format("%1$" + n + "s", s); + } + + public static boolean compareNonWhitespaces(String v1, String v2) { + return v1 != null && v2 != null + && v1.replaceAll("\\s+", "") + .equals(v2.replaceAll("\\s+", "")); + } + + public static final String SPACE = " "; + + public static final String EMPTY = ""; + + public static final String LF = "\n"; + + public static final String CR = "\r"; + + private static final int PAD_LIMIT = 8192; + + public static boolean isBlank(final CharSequence cs) { + int strLen; + if (cs == null || (strLen = cs.length()) == 0) { + return true; + } + for (int i = 0; i < strLen; i++) { + if (!Character.isWhitespace(cs.charAt(i))) { + return false; + } + } + return true; + } + + public static boolean isNotBlank(final CharSequence cs) { + return !isBlank(cs); + } + + public static boolean isEmpty(Object str) { + return (str == null || "".equals(str)); + } + + public static boolean isNotEmpty(final CharSequence cs) { + return !isEmpty(cs); + } + + public static boolean equals(final CharSequence cs1, final CharSequence cs2) { + if (cs1 == cs2) { + return true; + } + if (cs1 == null || cs2 == null) { + return false; + } + if (cs1.length() != cs2.length()) { + return false; + } + if (cs1 instanceof String && cs2 instanceof String) { + return cs1.equals(cs2); + } + // Step-wise comparison + final int length = cs1.length(); + for (int i = 0; i < length; i++) { + if (cs1.charAt(i) != cs2.charAt(i)) { + return false; + } + } + return true; + } + + public static boolean equalsIgnoreCase(final CharSequence cs1, final CharSequence cs2) { + if (cs1 == cs2) { + return true; + } + if (cs1 == null || cs2 == null) { + return false; + } + if (cs1.length() != cs2.length()) { + return false; + } + return regionMatches(cs1, true, 0, cs2, 0, cs1.length()); + } + + public static boolean containsIgnoreCase(final CharSequence str, final CharSequence searchStr) { + if (str == null || searchStr == null) { + return false; + } + final int len = searchStr.length(); + final int max = str.length() - len; + for (int i = 0; i <= max; i++) { + if (regionMatches(str, true, i, searchStr, 0, len)) { + return true; + } + } + return false; + } + + public static String deleteWhitespace(final String str) { + if (isEmpty(str)) { + return str; + } + final int sz = str.length(); + final char[] chs = new char[sz]; + int count = 0; + for (int i = 0; i < sz; i++) { + if (!Character.isWhitespace(str.charAt(i))) { + chs[count++] = str.charAt(i); + } + } + if (count == sz) { + return str; + } + return new String(chs, 0, count); + } + + public static String trim(final String str) { + return str == null ? null : str.trim(); + } + + public static String leftPad(final String str, final int size) { + return leftPad(str, size, ' '); + } + + public static String leftPad(final String str, final int size, final char padChar) { + if (str == null) { + return null; + } + final int pads = size - str.length(); + if (pads <= 0) { + return str; // returns original String when possible + } + if (pads > PAD_LIMIT) { + return leftPad(str, size, String.valueOf(padChar)); + } + return repeat(padChar, pads).concat(str); + } + + public static String leftPad(final String str, final int size, String padStr) { + if (str == null) { + return null; + } + if (isEmpty(padStr)) { + padStr = SPACE; + } + final int padLen = padStr.length(); + final int strLen = str.length(); + final int pads = size - strLen; + if (pads <= 0) { + return str; // returns original String when possible + } + if (padLen == 1 && pads <= PAD_LIMIT) { + return leftPad(str, size, padStr.charAt(0)); + } + + if (pads == padLen) { + return padStr.concat(str); + } else if (pads < padLen) { + return padStr.substring(0, pads).concat(str); + } else { + final char[] padding = new char[pads]; + final char[] padChars = padStr.toCharArray(); + for (int i = 0; i < pads; i++) { + padding[i] = padChars[i % padLen]; + } + return new String(padding).concat(str); + } + } + + public static String repeat(final char ch, final int repeat) { + if (repeat <= 0) { + return EMPTY; + } + final char[] buf = new char[repeat]; + for (int i = repeat - 1; i >= 0; i--) { + buf[i] = ch; + } + return new String(buf); + } + + static boolean regionMatches(final CharSequence cs, final boolean ignoreCase, final int thisStart, + final CharSequence substring, final int start, final int length) { + if (cs instanceof String && substring instanceof String) { + return ((String) cs).regionMatches(ignoreCase, thisStart, (String) substring, start, length); + } + int index1 = thisStart; + int index2 = start; + int tmpLen = length; + + // Extract these first so we detect NPEs the same as the java.lang.String version + final int srcLen = cs.length() - thisStart; + final int otherLen = substring.length() - start; + + // Check for invalid parameters + if (thisStart < 0 || start < 0 || length < 0) { + return false; + } + + // Check that the regions are long enough + if (srcLen < length || otherLen < length) { + return false; + } + + while (tmpLen-- > 0) { + final char c1 = cs.charAt(index1++); + final char c2 = substring.charAt(index2++); + + if (c1 == c2) { + continue; + } + + if (!ignoreCase) { + return false; + } + + // The same check as in String.regionMatches(): + if (Character.toUpperCase(c1) != Character.toUpperCase(c2) + && Character.toLowerCase(c1) != Character.toLowerCase(c2)) { + return false; + } + } + + return true; + } public static String toCamelCase(String input) { StringBuilder result = new StringBuilder(); @@ -60,4 +539,5 @@ public static String toCamelCase(String input) { } return result.toString(); } + } diff --git a/starter-generator/src/main/resources/template/html/entity.html.ftl b/starter-generator/src/main/resources/template/html/entity.html.ftl index fcea41f..0abec85 100644 --- a/starter-generator/src/main/resources/template/html/entity.html.ftl +++ b/starter-generator/src/main/resources/template/html/entity.html.ftl @@ -23,7 +23,9 @@ <#list entity.attributes as attribute> + <#if !attribute.multi> ${attribute.getStartCaseName()} + Actions @@ -46,31 +48,39 @@