001// --------------------------------------------------------------------------------
002// Copyright 2002-2024 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.control;
018
019import com.echothree.model.control.core.server.control.CoreControl;
020import com.echothree.model.data.core.server.entity.EntityInstance;
021import com.echothree.util.common.exception.BaseException;
022import com.echothree.util.common.message.Message;
023import com.echothree.util.common.persistence.BasePK;
024import com.echothree.util.server.message.ExecutionErrorAccumulator;
025import com.echothree.util.server.message.SecurityMessageAccumulator;
026import com.echothree.util.server.persistence.BaseEntity;
027import com.echothree.util.server.persistence.Session;
028import com.echothree.util.server.persistence.ThreadSession;
029import java.lang.reflect.InvocationTargetException;
030
031public abstract class BaseLogic {
032    
033    public Session getSession() {
034        return ThreadSession.currentSession();
035    }
036    
037    public void addExecutionError(final ExecutionErrorAccumulator eea, final String key, final Object... values) {
038        if(eea != null) {
039            eea.addExecutionError(key, values);
040        }
041    }
042
043    public void addSecurityMessage(final SecurityMessageAccumulator sma, final String key, final Object... values) {
044        if(sma != null) {
045            sma.addSecurityMessage(key, values);
046        }
047    }
048
049    public EntityInstance getEntityInstanceByBasePK(final BasePK pk) {
050        var coreControl = Session.getModelController(CoreControl.class);
051
052        return coreControl.getEntityInstanceByBasePK(pk);
053    }
054
055    public EntityInstance getEntityInstanceByBaseEntity(final BaseEntity baseEntity) {
056        var coreControl = Session.getModelController(CoreControl.class);
057
058        return coreControl.getEntityInstanceByBaseEntity(baseEntity);
059    }
060
061    // If eea is specified, we'll consider this to be a non-fatal error, and add this error to it. Otherwise, if a BaseException class
062    // is specified, we'll instantiate it and throw it. If neither was specified, the error cannot be handled - abort.
063    public void handleExecutionError(final Class<? extends BaseException> exceptionClass, final ExecutionErrorAccumulator eea, final String key, final Object... values) {
064        Message message = new Message(key, values);
065
066        if(eea == null) {
067            if(exceptionClass != null) {
068                try {
069                    throw exceptionClass.getConstructor(Message.class).newInstance(message);
070                } catch (NoSuchMethodException nsme) {
071                    throw new RuntimeException(nsme);
072                } catch (InstantiationException ie) {
073                    throw new RuntimeException(ie);
074                } catch (IllegalAccessException iae) {
075                    throw new RuntimeException(iae);
076                } catch (InvocationTargetException ite) {
077                    throw new RuntimeException(ite);
078                }
079            } else {
080                throw new RuntimeException("BaseException or ExecutionErrorAccumulator must be specified");
081            }
082        } else {
083            eea.addExecutionError(message);
084        }
085    }
086    
087    // If sma is specified, we'll consider this to be a non-fatal error, and add this error to it. Otherwise, if a BaseException class
088    // is specified, we'll instantiate it and throw it. If neither was specified, the error cannot be handled - abort.
089    public void handleSecurityMessage(final Class<? extends BaseException> exceptionClass, final SecurityMessageAccumulator sma, final String key, final Object... values) {
090        Message message = new Message(key, values);
091
092        if(sma == null) {
093            if(exceptionClass != null) {
094                try {
095                    throw exceptionClass.getConstructor(Message.class).newInstance(message);
096                } catch (NoSuchMethodException nsme) {
097                    throw new RuntimeException(nsme);
098                } catch (InstantiationException ie) {
099                    throw new RuntimeException(ie);
100                } catch (IllegalAccessException iae) {
101                    throw new RuntimeException(iae);
102                } catch (InvocationTargetException ite) {
103                    throw new RuntimeException(ite);
104                }
105            } else {
106                throw new RuntimeException("BaseException or SecurityMessageAccumulator must be specified");
107            }
108        } else {
109            sma.addSecurityMessage(message);
110        }
111    }
112    
113    // This is only safe to use if all function are using handleError. If eea is null in that case, an Exception will be throw, and this
114    // code will never be needed. Otherwise, eea will be checked and the value of hasExecutionErrors() returned.
115    public boolean hasExecutionErrors(final ExecutionErrorAccumulator eea) {
116        boolean hasExecutionErrors = false;
117        
118        if(eea != null) {
119            hasExecutionErrors = eea.hasExecutionErrors();
120        }
121        
122        return hasExecutionErrors;
123    }
124
125}