IDEMPIERE-5542 [DisplayType] - Cache issue (#1687)

This commit is contained in:
hengsin 2023-03-07 01:33:57 +08:00 committed by GitHub
parent de3ffd3c30
commit 6a5d45cba7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 128 additions and 36 deletions

View File

@ -231,21 +231,28 @@ public final class DisplayType
|| displayType == Image || displayType == Chart || displayType == RecordID)
return true;
//not custom type, don't have to check factory
if (displayType < 1000000)
return false;
IServiceReferenceHolder<IDisplayTypeFactory> cache = s_displayTypeFactoryCache.get(displayType);
if (cache != null) {
IDisplayTypeFactory service = cache.getService();
if (service != null)
return service.isID(displayType);
else
s_displayTypeFactoryCache.remove(displayType);
}
if (! s_displayTypeFactoryCache.containsKey(displayType)) {
String customTypeKey = displayType+"|isID";
if (! s_customDisplayTypeNegativeCache.containsKey(customTypeKey)) {
Optional<IServiceReferenceHolder<IDisplayTypeFactory>> found = getDisplayTypeFactories().stream()
.filter(e -> e.getService() != null && e.getService().isID(displayType))
.findFirst();
if (found.isPresent()) {
s_displayTypeFactoryCache.put(displayType, found.get());
return found.get().getService().isID(displayType);
return true;
}
s_displayTypeFactoryCache.put(displayType, null);
s_customDisplayTypeNegativeCache.put(customTypeKey, Boolean.TRUE);
}
return false;
@ -263,21 +270,28 @@ public final class DisplayType
|| displayType == Integer || displayType == Quantity)
return true;
//not custom type, don't have to check factory
if (displayType < 1000000)
return false;
IServiceReferenceHolder<IDisplayTypeFactory> cache = s_displayTypeFactoryCache.get(displayType);
if (cache != null) {
IDisplayTypeFactory service = cache.getService();
if (service != null)
return service.isNumeric(displayType);
else
s_displayTypeFactoryCache.remove(displayType);
}
if (! s_displayTypeFactoryCache.containsKey(displayType)) {
String customTypeKey = displayType + "|isNumeric";
if (! s_customDisplayTypeNegativeCache.containsKey(customTypeKey)) {
Optional<IServiceReferenceHolder<IDisplayTypeFactory>> found = getDisplayTypeFactories().stream()
.filter(e -> e.getService() != null && e.getService().isNumeric(displayType))
.findFirst();
if (found.isPresent()) {
s_displayTypeFactoryCache.put(displayType, found.get());
return found.get().getService().isNumeric(displayType);
return true;
}
s_displayTypeFactoryCache.put(displayType, null);
s_customDisplayTypeNegativeCache.put(customTypeKey, Boolean.TRUE);
}
return false;
@ -299,15 +313,23 @@ public final class DisplayType
|| displayType == Quantity)
return 4;
//not custom type, don't have to check factory
if (displayType < 1000000)
return 0;
IServiceReferenceHolder<IDisplayTypeFactory> cache = s_displayTypeFactoryCache.get(displayType);
if (cache != null) {
IDisplayTypeFactory service = cache.getService();
if (service != null) {
Integer v = service.getDefaultPrecision(displayType);
return v != null ? v.intValue() : 0;
} else {
s_displayTypeFactoryCache.remove(displayType);
}
}
if (! s_displayTypeFactoryCache.containsKey(displayType)) {
String customTypeKey = displayType + "|getDefaultPrecision";
if (! s_customDisplayTypeNegativeCache.containsKey(customTypeKey)) {
Optional<IServiceReferenceHolder<IDisplayTypeFactory>> found = getDisplayTypeFactories().stream()
.filter(e -> e.getService() != null && e.getService().getDefaultPrecision(displayType) != null)
.findFirst();
@ -316,7 +338,7 @@ public final class DisplayType
Integer v = found.get().getService().getDefaultPrecision(displayType);
return v != null ? v.intValue() : 0;
}
s_displayTypeFactoryCache.put(displayType, null);
s_customDisplayTypeNegativeCache.put(customTypeKey, Boolean.TRUE);
}
return 0;
} // getDefaultPrecision
@ -342,21 +364,29 @@ public final class DisplayType
|| displayType == TimeZoneId)
return true;
//not custom type, don't have to check factory
if (displayType < 1000000)
return false;
IServiceReferenceHolder<IDisplayTypeFactory> cache = s_displayTypeFactoryCache.get(displayType);
if (cache != null) {
IDisplayTypeFactory service = cache.getService();
if (service != null)
return service.isText(displayType);
else
s_displayTypeFactoryCache.remove(displayType);
}
if (! s_displayTypeFactoryCache.containsKey(displayType)) {
String customTypeKey = displayType + "|isText";
if (! s_customDisplayTypeNegativeCache.containsKey(customTypeKey)) {
Optional<IServiceReferenceHolder<IDisplayTypeFactory>> found = getDisplayTypeFactories().stream()
.filter(e -> e.getService() != null && e.getService().isText(displayType))
.findFirst();
if (found.isPresent()) {
s_displayTypeFactoryCache.put(displayType, found.get());
return found.get().getService().isText(displayType);
return true;
}
s_displayTypeFactoryCache.put(displayType, null);
s_customDisplayTypeNegativeCache.put(customTypeKey, Boolean.TRUE);
}
return false;
} // isText
@ -375,21 +405,29 @@ public final class DisplayType
if (isTimestampWithTimeZone(displayType))
return true;
//not custom type, don't have to check factory
if (displayType < 1000000)
return false;
IServiceReferenceHolder<IDisplayTypeFactory> cache = s_displayTypeFactoryCache.get(displayType);
if (cache != null) {
IDisplayTypeFactory service = cache.getService();
if (service != null)
return service.isDate(displayType);
else
s_displayTypeFactoryCache.remove(displayType);
}
if (! s_displayTypeFactoryCache.containsKey(displayType)) {
String customTypeKey = displayType + "|isDate";
if (! s_customDisplayTypeNegativeCache.containsKey(customTypeKey)) {
Optional<IServiceReferenceHolder<IDisplayTypeFactory>> found = getDisplayTypeFactories().stream()
.filter(e -> e.getService() != null && e.getService().isDate(displayType))
.findFirst();
if (found.isPresent()) {
s_displayTypeFactoryCache.put(displayType, found.get());
return found.get().getService().isDate(displayType);
return true;
}
s_displayTypeFactoryCache.put(displayType, null);
s_customDisplayTypeNegativeCache.put(customTypeKey, Boolean.TRUE);
}
return false;
@ -408,21 +446,29 @@ public final class DisplayType
|| DisplayType.Payment == displayType)
return true;
//not custom type, don't have to check factory
if (displayType < 1000000)
return false;
IServiceReferenceHolder<IDisplayTypeFactory> cache = s_displayTypeFactoryCache.get(displayType);
if (cache != null) {
IDisplayTypeFactory service = cache.getService();
if (service != null)
return service.isList(displayType);
else
s_displayTypeFactoryCache.remove(displayType);
}
if (! s_displayTypeFactoryCache.containsKey(displayType)) {
String customTypeKey = displayType + "|isList";
if (! s_customDisplayTypeNegativeCache.containsKey(customTypeKey)) {
Optional<IServiceReferenceHolder<IDisplayTypeFactory>> found = getDisplayTypeFactories().stream()
.filter(e -> e.getService() != null && e.getService().isList(displayType))
.findFirst();
if (found.isPresent()) {
s_displayTypeFactoryCache.put(displayType, found.get());
return found.get().getService().isList(displayType);
return true;
}
s_displayTypeFactoryCache.put(displayType, null);
s_customDisplayTypeNegativeCache.put(customTypeKey, Boolean.TRUE);
}
return false;
@ -444,21 +490,29 @@ public final class DisplayType
|| displayType == ChosenMultipleSelectionList)
return true;
//not custom type, don't have to check factory
if (displayType < 1000000)
return false;
IServiceReferenceHolder<IDisplayTypeFactory> cache = s_displayTypeFactoryCache.get(displayType);
if (cache != null) {
IDisplayTypeFactory service = cache.getService();
if (service != null)
return service.isLookup(displayType);
else
s_displayTypeFactoryCache.remove(displayType);
}
if (! s_displayTypeFactoryCache.containsKey(displayType)) {
String customTypeKey = displayType + "|isLookup";
if (! s_customDisplayTypeNegativeCache.containsKey(customTypeKey)) {
Optional<IServiceReferenceHolder<IDisplayTypeFactory>> found = getDisplayTypeFactories().stream()
.filter(e -> e.getService() != null && e.getService().isLookup(displayType))
.findFirst();
if (found.isPresent()) {
s_displayTypeFactoryCache.put(displayType, found.get());
return found.get().getService().isLookup(displayType);
return true;
}
s_displayTypeFactoryCache.put(displayType, null);
s_customDisplayTypeNegativeCache.put(customTypeKey, Boolean.TRUE);
}
return false;
@ -475,21 +529,29 @@ public final class DisplayType
|| displayType == TextLong)
return true;
//not custom type, don't have to check factory
if (displayType < 1000000)
return false;
IServiceReferenceHolder<IDisplayTypeFactory> cache = s_displayTypeFactoryCache.get(displayType);
if (cache != null) {
IDisplayTypeFactory service = cache.getService();
if (service != null)
return service.isLOB(displayType);
else
s_displayTypeFactoryCache.remove(displayType);
}
if (! s_displayTypeFactoryCache.containsKey(displayType)) {
String customTypeKey = displayType + "|isLOB";
if (! s_customDisplayTypeNegativeCache.containsKey(customTypeKey)) {
Optional<IServiceReferenceHolder<IDisplayTypeFactory>> found = getDisplayTypeFactories().stream()
.filter(e -> e.getService() != null && e.getService().isLOB(displayType))
.findFirst();
if (found.isPresent()) {
s_displayTypeFactoryCache.put(displayType, found.get());
return found.get().getService().isLOB(displayType);
return true;
}
s_displayTypeFactoryCache.put(displayType, null);
s_customDisplayTypeNegativeCache.put(customTypeKey, Boolean.TRUE);
}
return false;
@ -576,6 +638,10 @@ public final class DisplayType
}
else
{
//not custom type, don't have to check factory
if (displayType < 1000000)
return format;
IServiceReferenceHolder<IDisplayTypeFactory> cache = s_displayTypeFactoryCache.get(displayType);
if (cache != null) {
IDisplayTypeFactory service = cache.getService();
@ -583,9 +649,13 @@ public final class DisplayType
DecimalFormat f = service.getNumberFormat(displayType, language, pattern);
if (f != null)
return f;
} else {
s_displayTypeFactoryCache.remove(displayType);
}
}
if (! s_displayTypeFactoryCache.containsKey(displayType)) {
String customTypeKey = displayType + "|getNumberFormat";
if (! s_customDisplayTypeNegativeCache.containsKey(customTypeKey)) {
Optional<IServiceReferenceHolder<IDisplayTypeFactory>> found = getDisplayTypeFactories().stream()
.filter(e -> e.getService() != null && e.getService().getNumberFormat(displayType, language, pattern) != null)
.findFirst();
@ -593,7 +663,7 @@ public final class DisplayType
s_displayTypeFactoryCache.put(displayType, found.get());
return found.get().getService().getNumberFormat(displayType, language, pattern);
}
s_displayTypeFactoryCache.put(displayType, null);
s_customDisplayTypeNegativeCache.put(customTypeKey, Boolean.TRUE);
}
format.setMaximumIntegerDigits(MAX_DIGITS);
@ -709,7 +779,7 @@ public final class DisplayType
format = myLanguage.getDateTimeFormat();
return setTimeZone(format);
}
else {
else if (displayType >= 1000000) { //custom display type
IServiceReferenceHolder<IDisplayTypeFactory> cache = s_displayTypeFactoryCache.get(displayType);
if (cache != null) {
IDisplayTypeFactory service = cache.getService();
@ -717,9 +787,13 @@ public final class DisplayType
SimpleDateFormat v = service.getDateFormat(displayType, language, pattern);
if (v != null)
return v;
} else {
s_displayTypeFactoryCache.remove(displayType);
}
}
if (! s_displayTypeFactoryCache.containsKey(displayType)) {
String customTypeKey = displayType + "|getDateFormat";
if (! s_customDisplayTypeNegativeCache.containsKey(customTypeKey)) {
Optional<IServiceReferenceHolder<IDisplayTypeFactory>> found = getDisplayTypeFactories().stream()
.filter(e -> e.getService() != null && e.getService().getDateFormat(displayType, language, pattern) != null)
.findFirst();
@ -727,7 +801,7 @@ public final class DisplayType
s_displayTypeFactoryCache.put(displayType, found.get());
return found.get().getService().getDateFormat(displayType, language, pattern);
}
s_displayTypeFactoryCache.put(displayType, null);
s_customDisplayTypeNegativeCache.put(customTypeKey, Boolean.TRUE);
}
}
@ -798,7 +872,7 @@ public final class DisplayType
return String.class;
else if (isLOB(displayType)) // CLOB is String
return byte[].class;
else
else if (displayType >= 1000000) // custom display type
{
IServiceReferenceHolder<IDisplayTypeFactory> cache = s_displayTypeFactoryCache.get(displayType);
if (cache != null) {
@ -807,9 +881,13 @@ public final class DisplayType
Class<?> v = service.getClass(displayType, yesNoAsBoolean);
if (v != null)
return v;
} else {
s_displayTypeFactoryCache.remove(displayType);
}
}
if (! s_displayTypeFactoryCache.containsKey(displayType)) {
String customTypeKey = displayType + "|getClass";
if (! s_customDisplayTypeNegativeCache.containsKey(customTypeKey)) {
Optional<IServiceReferenceHolder<IDisplayTypeFactory>> found = getDisplayTypeFactories().stream()
.filter(e -> e.getService() != null && e.getService().getClass(displayType, yesNoAsBoolean) != null)
.findFirst();
@ -817,7 +895,7 @@ public final class DisplayType
s_displayTypeFactoryCache.put(displayType, found.get());
return found.get().getService().getClass(displayType, yesNoAsBoolean);
}
s_displayTypeFactoryCache.put(displayType, null);
s_customDisplayTypeNegativeCache.put(customTypeKey, Boolean.TRUE);
}
}
//
@ -901,9 +979,13 @@ public final class DisplayType
String v = service.getSQLDataType(displayType, columnName, fieldLength);
if (v != null)
return v;
} else {
s_displayTypeFactoryCache.remove(displayType);
}
}
if (! s_displayTypeFactoryCache.containsKey(displayType)) {
String customTypeKey = displayType + "|getSQLDataType";
if (! s_customDisplayTypeNegativeCache.containsKey(customTypeKey)) {
Optional<IServiceReferenceHolder<IDisplayTypeFactory>> found = getDisplayTypeFactories().stream()
.filter(e -> e.getService() != null && e.getService().getSQLDataType(displayType, columnName, fieldLength) != null)
.findFirst();
@ -911,7 +993,7 @@ public final class DisplayType
s_displayTypeFactoryCache.put(displayType, found.get());
return found.get().getService().getSQLDataType(displayType, columnName, fieldLength);
}
s_displayTypeFactoryCache.put(displayType, null);
s_customDisplayTypeNegativeCache.put(customTypeKey, Boolean.TRUE);
}
if (!DisplayType.isText(displayType))
@ -1008,9 +1090,13 @@ public final class DisplayType
String v = service.getDescription(displayType);
if (v != null)
return v;
} else {
s_displayTypeFactoryCache.remove(displayType);
}
}
if (! s_displayTypeFactoryCache.containsKey(displayType)) {
String customTypeKey = displayType + "|getDescription";
if (! s_customDisplayTypeNegativeCache.containsKey(customTypeKey)) {
Optional<IServiceReferenceHolder<IDisplayTypeFactory>> found = getDisplayTypeFactories().stream()
.filter(e -> e.getService() != null && e.getService().getDescription(displayType) != null)
.findFirst();
@ -1018,7 +1104,7 @@ public final class DisplayType
s_displayTypeFactoryCache.put(displayType, found.get());
return found.get().getService().getDescription(displayType);
}
s_displayTypeFactoryCache.put(displayType, null);
s_customDisplayTypeNegativeCache.put(customTypeKey, Boolean.TRUE);
}
//
@ -1040,7 +1126,11 @@ public final class DisplayType
return currencyFormatter;
} // getCurrencyFormat
/**
* Custom DisplayType|Method:Boolean.TRUE (for e.g 1000000|isID:Boolean.TRUE). <br/>
* Map to cache that a custom display type does not have display type factory register for a Method (isID, isNumeric, getDateFormat, etc).
*/
private final static CCache<String, Boolean> s_customDisplayTypeNegativeCache = new CCache<>(null, "CustomDisplayTypeNegativeCache", 100, false);
private final static CCache<Integer, IServiceReferenceHolder<IDisplayTypeFactory>> s_displayTypeFactoryCache = new CCache<>(null, "IDisplayTypeFactory", 100, false);
private static List<IServiceReferenceHolder<IDisplayTypeFactory>> getDisplayTypeFactories() {

View File

@ -663,6 +663,8 @@ public class CacheTest extends AbstractTestCase {
//IDisplayTypeFactory
TestActivator.context.registerService(IDisplayTypeFactory.class, new FakeDisplayTypeFactory(), null);
cacheName = "IDisplayTypeFactory";
boolean isLOB = DisplayType.isLOB(FakeDisplayTypeFactory.DISPLAY_TYPE);
assertFalse(isLOB);
boolean isText = DisplayType.isText(FakeDisplayTypeFactory.DISPLAY_TYPE);
assertTrue(isText);
cache = findByNameAndKey(cacheName, FakeDisplayTypeFactory.DISPLAY_TYPE);