Package framework.beans

Source Code of framework.beans.FacadeBean

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package framework.beans;

import framework.audit.Audit;
import framework.audit.AuditDetails;
import framework.audit.AuditDoc;
import framework.beans.collaborator.CollaboratorAbstract;
import framework.beans.security.BeanRights;
import framework.generic.ClipsServerException;
import framework.generic.EDataIntegrity;
import framework.generic.ESecurity;
import framework.generic.HasEntityInfo;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import framework.security.RightChecker;
import framework.utils.DateTimeUtils;
import java.util.LinkedList;

/**
*
* @param <GEN>
* @author axe
*/
abstract public class FacadeBean<GEN extends GenericEntity> extends SecuredBean
    implements EntityFacade {

    public static int COMMAND_READ = 0;
    public static int COMMAND_CREATE = 1;
    public static int COMMAND_MODIFY = 2;
    public static int COMMAND_REMOVE = 3;

    private boolean justCreated;
    private int entityID;
    private Class<GEN> cls;

    public FacadeBean(Class<GEN> cls) {
        this.cls = cls;
    }
   
    protected int getId() {
        return entityID;
    }

  public Class<GEN> getEntityClass() {
    return cls;
  }

    private GEN getEntity() throws ClipsServerException {
        if(entityID == 0) {
            try {
                return cls.newInstance();
            } catch (Exception ex) {
                throw new ClipsServerException("Неожиданная ошибка при создании новых данных на сервере", ex);
            }
        }
    else {
            //entity = (GEN) findEntity(cls, anId);
            return findEntity(cls, entityID);
        }
    }

    protected GEN getExistentEntity() throws ClipsServerException {
        checkEntityExist();
        return getEntity();
    }

    @Override
    public String getEntityName() {
    return getEntityHumanName(cls);
    }
   
    /**
     * Этот метод следует обязательно вызывать перед работой с бином.
     * @param anId - идентификатор сущности, с которой будет работать бин. 0 - если создаётся новая
     * сущность.
     * @param aSessionId - идентификатор сессии. Без него работу заблокирует система безопасности.
     * @return
     * @throws generic.ClipsServerException
     */
    @Override
    public BeanRights initByID(int anId, int aSessionId)
        throws ClipsServerException {
        entityID = anId;
        if(anId == 0) {
            /*try {
                entity = cls.newInstance();
            } catch (Exception ex) {
                throw new ClipsServerException("Неожиданная ошибка при инициализации сервера", ex);
            }*/
        } else {
            //entity = (GEN) findEntity(cls, anId);
            findEntity(cls, anId);
        }
       
        justCreated = anId == 0;
        setSession(aSessionId);
        return rights;
    }

    public boolean isJustCreated() {
        return justCreated;
    }

    /**
     * В системе безопасности это комманда COMMAND_READ. В этом классе (FacadeBean) этот
     * метод - только начало для метода getDetails всех подклассов. Ни чего не возвращает, а
     * только проверяет наличие прав на эту комманду.
     * @return
     * @throws generic.ClipsServerException
     */
    @Override
    public EntityDetails getDetails() throws ClipsServerException {
        checkEntityExist();
        checkCommandAccessibility(COMMAND_READ);
        return getEntity().getDetails((RightChecker) this);
    }

    /**
     * Этот метод позволяет создавать новую или редактировать уже существующую сущность.
     * В системе безопасности это комманда COMMAND_CREATE или COMMAND_MODIFY.
     * Здесь проверяется наличие прав на комманду, возможность выполнения (проверка целостности и
     * корректности, переопределить в методе checkAccessibilityForUpdate), и вызывается
     * updateUnconditional.
     * @param details
     * @return
     * @throws generic.ClipsServerException
     */
    @Override
    public ModificationInfo update(EntityDetails details) throws ClipsServerException {
        try {
            List<AuditDoc> auditList = new LinkedList<AuditDoc>();

            checkCommandAccessibility(isJustCreated() ? COMMAND_CREATE : COMMAND_MODIFY);
            GEN entity = getEntity();
            AuditDoc<GEN> auditDoc = new AuditDoc<GEN>(entity, getCollaborator());
            onUpdate(entity, details, auditDoc, auditList);
            boolean newEntity = (entityID == 0);
            int id = saveEntity(entity);
            checkAudit(auditList, auditDoc, entity);

            details.setId(entityID);
            afterUpdate(entity, newEntity, details, auditList);
            entityID = id;

            List<AuditDetails> auditInfo = persistAudit(auditList);
            return new ModificationInfo(id, auditInfo);
        } catch (ClipsServerException ex) {
            throw ex;
        } catch (Exception ex) {
            throw new ClipsServerException("Не удалось сохранить: ", ex);
        }
    }

    /**
     * Проверяет возможность удаления сущности.
     * В этот методе не следует добавлять проверку наличия прав, это сделанно за его пределами.
   * @param entity
   * @TODO Сейчас этот метод НЕ абстрактный, чтобы не пришлось исправлять всё сразу.
     * В последствии для поиска случаев, когда этот метод не реализован, можно сделать его абстрактным.
     * @throws ClipsServerException
     */
    protected void onRemove(GEN entity, List<AuditDoc> auditDocList) throws ClipsServerException {
       /* java.lang.reflect.Field fields[] = cls.getDeclaredFields();
        for(int i=0; i<fields.length; i++) {
            Class fc = fields[i].getDeclaringClass();
            if(fc.isInstance(GenericEntity.class)) {
               
            }
        }*/
    }

    /**
     * Проверяет возможность создания или изменения сущности учитывая принятые детали.
     * В этот методе не следует добавлять проверку наличия прав, это сделанно за его пределами.
     * В последствии для поиска случаев, когда этот метод не реализован, можно сделать его абстрактным.
     * Внимание! В auditDocList добавлять ничего не надо, если изменяется только сущность,
     * закрываемая бином. Если же изменяются сопутствующие сущности, то создается документ
     * аудита, затем сопутствующие сущности изменяются, записываются в базу, рефрешаются для
     * получения ID, документу аудита делается check, и добавляем его к auditDocList.
     * @param entity
     * @param details
     * @param auditDoc передается для возможных извращений (к примеру CheckupBean)
     * @param auditDocList передается для заталкивания документов аудита для
     * сопутсвующих измененных сущностей
     * @throws ClipsServerException
     */
    abstract protected void onUpdate(GEN entity, EntityDetails details, AuditDoc auditDoc, List<AuditDoc> auditDocList) throws ClipsServerException;

    /**
     * Выполняет некоторые необходимые действия которые должны быть реализованы после создания
     * или изменения сущности
   * @param entity
   * @param isNewEntity
   * @param details
     * @throws ClipsServerException
     */
    protected void afterUpdate(GEN entity, boolean isNewEntity, EntityDetails details, List<AuditDoc> auditDocList) throws ClipsServerException {
       
    };

    /**
     * Этот метод позволяет удаляет сущность.
     * В системе безопасности это комманда COMMAND_REMOVE.
     * Здесь проверяется наличие прав на комманду, возможность выполнения (проверка целостности и
     * корректности, переопределить в методе checkAccessibilityForRemove), и вызывается
     * removeUnconditional.
     * @throws ClipsServerException
     */
    @Override
    public ModificationInfo remove() throws ClipsServerException {
        try {
            checkCommandAccessibility(COMMAND_REMOVE);
            checkEntityExist();
            GEN entity = getEntity();

            List<AuditDoc> auditDocList = new LinkedList<AuditDoc>();
            AuditDoc<GEN> auditDoc = new AuditDoc<GEN>(entity, getCollaborator());
            auditDocList.add(auditDoc);
            //Нельзя нарушать последовательность вызовов
            onRemove(entity, auditDocList);
            auditDoc.check(null);
            removeEntity(entity);

            List<AuditDetails> auditInfo = persistAudit(auditDocList);
            return new ModificationInfo(entity.getId(), auditInfo);
        } catch (ClipsServerException ex) {
            throw ex;
        } catch (Exception ex) {
            throw new ClipsServerException("Ошибка удаления", ex);
        }
    }
   
    /**
     * Проверка, сохранена ли основная сущность бина
   * @throws EDataIntegrity если не сохранена, выбрасывается исключение
     */
    protected void checkEntityExist() throws EDataIntegrity {
        if(entityID == 0) {
            throw new EDataIntegrity("Сущность должна быть предварительно сохранена");
        }        
    }   
   
    /**
     * Проверка, соответсвтвует ли указанная сущность основной сущности бина
   * @param gent
   * @throws ClipsServerException если не соответствует, выбрасывается исключение
     */
    protected void checkTheSame(GenericEntity gent) throws ClipsServerException {
        if(gent.getId() != getEntity().getId()) {
            throw new EDataIntegrity("Зафиксирована попытка переноса данных");
        }
    }   

    protected void checkDate(Date date) throws ClipsServerException {
        if(!DateTimeUtils.belongsToCurrentDay(date)) {
            throw new ESecurity("Срок редактирования вышел");
        }
    }
   
    /**
   * Ищет и возвращяет детали сущностей ссылающихся на сущьность текущего бина
   * @param <K>
   * @param <T>
   * @param childClass - класс дочерней сущности например Prescription.class
   * @param member - член класса который ссылается на сущность бина
   *        например "serviceRender" для Prescription.class и ServiceRenderBean
   * @return
   * @throws ClipsServerException
   */
    protected <K extends EntityDetails, T extends GenericEntity<K>>
        ArrayList<K> loadChildDetailsList(Class<T> childClass, String member)
        throws ClipsServerException {
        GEN        entity = getExistentEntity();
        return loadChildDetailsList(entity, childClass, member);
    }

  protected <T extends GenericEntity> void checkEntityNotRef(Class<T> clazz, String member) throws EDataIntegrity{
    checkEntityNotRef(clazz, member, null);
  }

  protected void checkEntityNotRef(Class clazz, String member, String message) throws EDataIntegrity{
        GEN  entity = manager.find(cls, entityID);
        checkEntityNotRef(entity, clazz, member, message);
    }

    /**
     * проверка связана ли сущность с другими сущностями
     * @param <T>
     * @param entity
     * @param clazz
     * @param member
     * @param message
     * @throws framework.generic.EDataIntegrity
     */
  protected <T extends GenericEntity> void checkEntityNotRef(GEN entity, Class<T> clazz, String member, String message) throws EDataIntegrity{
        if(entityID == 0) {
      return;
    }
    if (entity == null){
      return;
    }


//        List entityList = findEntityList(clazz, new Field[]{new Field(member, entity)});
        Field[] f = new Field[]{new Field(member, entity)};
    int  count = getEntityCount(clazz, f);// entityList.size();
    if (count > 0){
            List<T> list = findEntityListWithResCount(clazz, f, "", 1);
            if (list.isEmpty()){

            }else{
                Object linked = list.get(0);
                String linkInfo = "";
                if (linked instanceof HasEntityInfo) {
                    linkInfo = "\n[" + ((HasEntityInfo) linked).getInfo() + "]";
                }
                if (message == null){
                    message = "Нельзя удалить объект \"%1$s\" так как на него ссылается \"%2$s\", перед удалением надо удалить или отредактировать \"%2$s\"";
                }
                throw new EDataIntegrity(String.format(message, getEntityHumanName(cls), getEntityHumanName(clazz), count) + linkInfo);
            }
    }
  }

    protected <T extends GenericEntity> void checkAudit(List<AuditDoc> list,
            AuditDoc<T> auditDoc, T entity) throws ClipsServerException {
        if(auditDoc.check(entity)) {
            list.add(auditDoc);
        }
    }


}
TOP

Related Classes of framework.beans.FacadeBean

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.