001// -------------------------------------------------------------------------------- 002// Copyright 2002-2025 Echo Three, LLC 003// 004// Licensed under the Apache License, Version 2.0 (the "License"); 005// you may not use this file except in compliance with the License. 006// You may obtain a copy of the License at 007// 008// http://www.apache.org/licenses/LICENSE-2.0 009// 010// Unless required by applicable law or agreed to in writing, software 011// distributed under the License is distributed on an "AS IS" BASIS, 012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013// See the License for the specific language governing permissions and 014// limitations under the License. 015// -------------------------------------------------------------------------------- 016 017package com.echothree.util.server.string; 018 019import com.echothree.model.control.uom.server.control.UomControl; 020import com.echothree.model.control.user.server.control.UserControl; 021import com.echothree.model.data.party.server.entity.Language; 022import com.echothree.model.data.uom.server.entity.UnitOfMeasureKind; 023import com.echothree.model.data.uom.server.entity.UnitOfMeasureType; 024import com.echothree.model.data.user.server.entity.UserVisit; 025import com.echothree.util.server.persistence.Session; 026 027public class UnitOfMeasureUtils { 028 029 private UnitOfMeasureUtils() { 030 super(); 031 } 032 033 private static class UnitOfMeasureUtilsHolder { 034 static UnitOfMeasureUtils instance = new UnitOfMeasureUtils(); 035 } 036 037 public static UnitOfMeasureUtils getInstance() { 038 return UnitOfMeasureUtilsHolder.instance; 039 } 040 041 private void appendMeasure(UomControl uomControl, Language language, final StringBuilder builder, final UnitOfMeasureType unitOfMeasureType, final long measure) { 042 if(builder.length() > 0) 043 builder.append(", "); 044 045 builder.append(measure).append(' '); 046 if(measure == 1) { 047 builder.append(uomControl.getBestSingularUnitOfMeasureTypeDescription(unitOfMeasureType, language)); 048 } else { 049 builder.append(uomControl.getBestPluralUnitOfMeasureTypeDescription(unitOfMeasureType, language)); 050 } 051 } 052 053 private StringBuilder formatUnitOfMeasure(UomControl uomControl, Language language, StringBuilder builder, UnitOfMeasureType unitOfMeasureType, long measure) { 054 var unitOfMeasureEquivalents = uomControl.getUnitOfMeasureEquivalentsByToUnitOfMeasureType(unitOfMeasureType); 055 var appended = false; 056 057 for(var unitOfMeasureEquivalent : unitOfMeasureEquivalents) { 058 long toQuantity = unitOfMeasureEquivalent.getToQuantity(); 059 060 if(measure > toQuantity) { 061 var equivMeasure = measure / toQuantity; 062 var remainMeasure = measure % toQuantity; 063 064 formatUnitOfMeasure(uomControl, language, builder, unitOfMeasureEquivalent.getFromUnitOfMeasureType(), equivMeasure); 065 066 if(remainMeasure != 0) { 067 appendMeasure(uomControl, language, builder, unitOfMeasureType, remainMeasure); 068 } 069 070 appended = true; 071 break; 072 } 073 } 074 075 if(!appended && measure != 0) { 076 appendMeasure(uomControl, language, builder, unitOfMeasureType, measure); 077 } 078 079 return builder; 080 } 081 082 private UnitOfMeasureType getLowestUnitOfMeasureType(UomControl uomControl, UnitOfMeasureType unitOfMeasureType) { 083 var unitOfMeasureEquivalents = uomControl.getUnitOfMeasureEquivalentsByFromUnitOfMeasureType(unitOfMeasureType); 084 var iter = unitOfMeasureEquivalents.iterator(); 085 086 if(iter.hasNext()) { 087 var unitOfMeasureEquivalent = iter.next(); 088 089 unitOfMeasureType = unitOfMeasureEquivalent.getToUnitOfMeasureType(); 090 } 091 092 return unitOfMeasureType; 093 } 094 095 // TODO: This should have a cache 096 public UnitOfMeasureType getLowestUnitOfMeasureType(UomControl uomControl, UnitOfMeasureKind unitOfMeasureKind) { 097 var unitOfMeasureTypes = uomControl.getUnitOfMeasureTypesByUnitOfMeasureKind(unitOfMeasureKind); 098 var iter = unitOfMeasureTypes.iterator(); 099 UnitOfMeasureType unitOfMeasureType = null; 100 101 if(iter.hasNext()) { 102 unitOfMeasureType = getLowestUnitOfMeasureType(uomControl, iter.next()); 103 } 104 105 return unitOfMeasureType; 106 } 107 108 public String formatUnitOfMeasure(UserVisit userVisit, UnitOfMeasureKind unitOfMeasureKind, Long measure) { 109 String result = null; 110 111 if(measure != null) { 112 var uomControl = Session.getModelController(UomControl.class); 113 var userControl = Session.getModelController(UserControl.class); 114 var language = userControl.getPreferredLanguageFromUserVisit(userVisit); 115 var unitOfMeasureType = getLowestUnitOfMeasureType(uomControl, unitOfMeasureKind); 116 117 result = formatUnitOfMeasure(uomControl, language, new StringBuilder(), unitOfMeasureType, measure).toString(); 118 } 119 120 return result; 121 } 122 123}