001// --------------------------------------------------------------------------------
002// Copyright 2002-2025 Echo Three, LLC
003// Copyright 1999-2005 The Apache Software Foundation.
004//
005// Licensed under the Apache License, Version 2.0 (the "License");
006// you may not use this file except in compliance with the License.
007// You may obtain a copy of the License at
008//
009//     http://www.apache.org/licenses/LICENSE-2.0
010//
011// Unless required by applicable law or agreed to in writing, software
012// distributed under the License is distributed on an "AS IS" BASIS,
013// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014// See the License for the specific language governing permissions and
015// limitations under the License.
016// --------------------------------------------------------------------------------
017
018package com.echothree.util.server.message;
019
020import com.echothree.model.control.core.common.exception.UnknownCommandMessageTypeNameException;
021import com.echothree.model.control.core.server.control.CommandControl;
022import com.echothree.model.control.party.server.control.PartyControl;
023import com.echothree.model.data.core.server.entity.CommandMessageType;
024import com.echothree.model.data.party.server.entity.Language;
025import com.echothree.util.common.message.ExecutionErrors;
026import com.echothree.util.common.message.Message;
027import com.echothree.util.common.message.Messages;
028import com.echothree.util.server.persistence.Session;
029import java.text.MessageFormat;
030
031public class MessageUtils {
032    
033    private static final MessageUtils instance = new MessageUtils();
034    
035    protected MessageUtils() {
036        super();
037    }
038    
039    public static MessageUtils getInstance() {
040        return instance;
041    }
042    
043    /**
044     * Escape any single quote characters that are included in the specified
045     * message string.
046     *
047     * @param string The string to be escaped
048     */
049    protected String escape(String string) {
050        if((string == null) || (string.indexOf('\'') < 0)) {
051            return string;
052        }
053
054        var n = string.length();
055        var sb = new StringBuilder(n);
056        
057        for (var i = 0; i < n; i++) {
058            var ch = string.charAt(i);
059            
060            if (ch == '\'') {
061                sb.append('\'');
062            }
063            
064            sb.append(ch);
065        }
066        
067        return sb.toString();
068    }
069    
070    /**
071     * Returns a text message after parametric replacement of the specified
072     * parameter placeholders.  A null string result will be returned by this
073     * method if no resource bundle has been configured.
074     */
075    protected void fillInMessage(CommandControl commandControl, Language language, CommandMessageType commandMessageType, Message message) {
076        var key = message.getKey();
077        var commandMessage = commandControl.getCommandMessageByKey(commandMessageType, key);
078        String translation = null;
079        
080        if(commandMessage != null) {
081            var commandMessageTranslation = commandControl.getBestCommandMessageTranslation(commandMessage, language);
082
083            if(commandMessageTranslation != null) {
084                translation = commandMessageTranslation.getTranslation();
085
086                if(translation != null) {
087                    translation = new MessageFormat(escape(translation)).format(message.getValues());
088                }
089            }
090        }
091        
092        message.setMessage(translation == null ? "??" + key + "??" : translation);
093    }
094    
095    public void fillInMessages(Language language, String commandMessageTypeName, Messages messages) {
096        if(messages != null) {
097            var commandControl = Session.getModelController(CommandControl.class);
098            var commandMessageType = commandControl.getCommandMessageTypeByName(commandMessageTypeName);
099            
100            if(commandMessageType != null) {
101                var iter = messages.get();
102                
103                while(iter.hasNext()) {
104                    fillInMessage(commandControl, language, commandMessageType, iter.next());
105                }
106            }
107        }
108    }
109
110    // The language used in the Exceptions will always be the default Language (typically English).
111    public String getExceptionMessage(String commandMessageTypeName, Message message) {
112        var commandControl = Session.getModelController(CommandControl.class);
113        var commandMessageType = commandControl.getCommandMessageTypeByName(commandMessageTypeName);
114        
115        if(commandMessageType == null) {
116            throw new UnknownCommandMessageTypeNameException(new Message(ExecutionErrors.UnknownCommandMessageTypeName.name(), commandMessageTypeName));
117        } else {
118            var partyControl = Session.getModelController(PartyControl.class);
119            var language = partyControl.getDefaultLanguage();
120            
121            fillInMessage(commandControl, language, commandMessageType, message);
122        }
123
124        return message.getMessage();
125    }
126    
127}