![JAR search and dependency download from the Maven repository](/logo.png)
org.apache.cayenne.gen.ImportUtils Maven / Gradle / Ivy
/*****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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
*
* https://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 org.apache.cayenne.gen;
import org.apache.cayenne.dba.TypesMapping;
import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.EmbeddableAttribute;
import org.apache.cayenne.map.ObjAttribute;
import org.apache.cayenne.util.Util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Methods for mangling strings.
*
*/
public class ImportUtils {
public static final String[] importOrdering = { "java.", "javax.", "org.", "com." };
static final String[] primitives = { "long", "double", "byte", "boolean", "float", "short", "int", "char" };
static final String[] primitiveClasses = new String[] { Long.class.getName(), Double.class.getName(),
Byte.class.getName(), Boolean.class.getName(), Float.class.getName(), Short.class.getName(),
Integer.class.getName(), Character.class.getName() };
static Map classesForPrimitives = Util.toMap(primitives, primitiveClasses);
static Map primitivesForClasses = Util.toMap(primitiveClasses, primitives);
protected Map importTypesMap = new HashMap<>();
// Types forced to be FQN
protected Map reservedImportTypesMap = new HashMap<>();
protected String packageName;
protected boolean canRegisterType(String typeName) {
// Not sure why this would ever happen, but it did
if (null == typeName) {
return false;
}
StringUtils stringUtils = StringUtils.getInstance();
String typeClassName = stringUtils.stripPackageName(typeName);
String typePackageName = stringUtils.stripClass(typeName);
if (typePackageName.length() == 0) {
return false; // disallow non-packaged types (primitives, probably)
}
if ("java.lang".equals(typePackageName)) {
return false;
}
// Can only have one type -- rest must use fqn
if (reservedImportTypesMap.containsKey(typeClassName)) {
return false;
}
return !importTypesMap.containsKey(typeClassName);
}
/**
* Reserve a fully-qualified data type class name so it cannot be used by
* another class. No import statements will be generated for reserved types.
* Typically, this is the fully-qualified class name of the class being
* generated.
*
* @param typeName
* FQ data type class name.
*/
public void addReservedType(String typeName) {
if (!canRegisterType(typeName)) {
return;
}
StringUtils stringUtils = StringUtils.getInstance();
String typeClassName = stringUtils.stripPackageName(typeName);
reservedImportTypesMap.put(typeClassName, typeName);
}
/**
* Register a fully-qualified data type class name. For example,
* org.apache.cayenne.GenericPersistentObject.
*
* @param typeName
* FQ data type class name.
*/
public void addType(String typeName) {
if (!canRegisterType(typeName)) {
return;
}
StringUtils stringUtils = StringUtils.getInstance();
String typePackageName = stringUtils.stripClass(typeName);
if (typePackageName.equals(packageName)) {
return;
}
importTypesMap.put(stringUtils.stripPackageName(typeName), typeName);
}
/**
* Add the package name to use for this importUtil invocation.
*/
public void setPackage(String packageName) {
this.packageName = packageName;
}
/**
* Performs processing similar to formatJavaType(String)
, with
* special handling of primitive types and their Java class counterparts.
* This method allows users to make a decision whether to use primitives or
* not, regardless of how type is mapped.
*/
public String formatJavaType(String typeName, boolean usePrimitives) {
if (usePrimitives) {
String primitive = primitivesForClasses.get(typeName);
return (primitive != null) ? primitive : formatJavaType(typeName);
} else {
String primitiveClass = classesForPrimitives.get(typeName);
return (primitiveClass != null) ? formatJavaType(primitiveClass) : formatJavaType(typeName);
}
}
/**
* Removes registered package and non-reserved registered type name prefixes
* from java types
*/
public String formatJavaType(String typeName) {
if (typeName != null) {
StringUtils stringUtils = StringUtils.getInstance();
String typeClassName = stringUtils.stripPackageName(typeName);
if (!reservedImportTypesMap.containsKey(typeClassName)
&& importTypesMap.containsKey(typeClassName)
&& typeName.equals(importTypesMap.get(typeClassName))) {
return typeClassName;
}
String typePackageName = stringUtils.stripClass(typeName);
if ("java.lang".equals(typePackageName)) {
return typeClassName;
}
if ((null != packageName) && (packageName.equals(typePackageName))) {
return typeClassName;
}
}
return typeName;
}
/**
* @since 3.0
*/
public String formatJavaTypeAsNonBooleanPrimitive(String type) {
String value = ImportUtils.classesForPrimitives.get(type);
return formatJavaType(value != null ? value : type);
}
/**
* @since 3.0
*/
public boolean isNonBooleanPrimitive(String type) {
return ImportUtils.classesForPrimitives.containsKey(type) && !isBoolean(type);
}
/**
* @since 4.2
*/
public boolean isNumericPrimitive(String type) {
return isNonBooleanPrimitive(type) && !"char".equals(type);
}
/**
* @since 3.0
*/
public boolean isBoolean(String type) {
return "boolean".equals(type);
}
/**
* @since 4.1
* @param type name
* @return is given type primitive
*/
public boolean isPrimitive(String type) {
return classesForPrimitives.containsKey(type);
}
/**
*
* This method decide can primitive type be used for given attribute.
* It can be used in following cases:
* - attribute is PK and primitive
* - attribute not PK and is mandatory
*
* @param attribute to check
* @return can primitive Java type be used
*
* @since 4.1
*/
public boolean canUsePrimitive(ObjAttribute attribute) {
return !attribute.isLazy() && attribute.isMandatory() && isPrimitive(attribute.getType());
}
public boolean canUsePrimitive(EmbeddableAttribute attribute) {
return isPrimitive(attribute.getType());
}
/**
* Generate package and list of import statements based on the registered
* types.
*/
public String generate() {
StringBuilder outputBuffer = new StringBuilder();
if (null != packageName) {
outputBuffer.append("package ");
outputBuffer.append(packageName);
// Using UNIX line endings intentionally - generated Java files should look
// the same regardless of platform to prevent developer teams working on
// multiple OS's to override each other's work
outputBuffer.append(";\n\n");
}
List typesList = new ArrayList<>(importTypesMap.values());
typesList.sort((s1, s2) -> {
for (String ordering : importOrdering) {
if ((s1.startsWith(ordering)) && (!s2.startsWith(ordering))) {
return -1;
}
if ((!s1.startsWith(ordering)) && (s2.startsWith(ordering))) {
return 1;
}
}
return s1.compareTo(s2);
});
String lastStringPrefix = null;
boolean firstIteration = true;
for (String typeName : typesList) {
if (firstIteration) {
firstIteration = false;
} else {
outputBuffer.append('\n');
}
// Output another newline if we're in a different root package.
// Find root package
String thisStringPrefix = typeName;
int dotIndex = typeName.indexOf('.');
if (-1 != dotIndex) {
thisStringPrefix = typeName.substring(0, dotIndex);
}
// if this isn't the first import,
if (null != lastStringPrefix) {
// and it's different from the last import
if (!thisStringPrefix.equals(lastStringPrefix)) {
// output a newline; force UNIX style per comment above
outputBuffer.append("\n");
}
}
lastStringPrefix = thisStringPrefix;
outputBuffer.append("import ");
outputBuffer.append(typeName);
outputBuffer.append(';');
}
return outputBuffer.toString();
}
/**
* @param attribute db attribute
* @return name of the java type
*
* @since 4.1
*/
public String dbAttributeToJavaType(DbAttribute attribute) {
String javaTypeName = TypesMapping.getJavaBySqlType(attribute);
return formatJavaType(javaTypeName);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy