/* * Copyright (c) 2005-2016 Vincent Vandenschrick. All rights reserved. * * This file is part of the Jspresso framework. * * Jspresso is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Jspresso is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Jspresso. If not, see <http://www.gnu.org/licenses/>. */ package org.jspresso.framework.application.backend.entity; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.jspresso.framework.application.backend.BackendControllerHolder; import org.jspresso.framework.application.backend.IBackendController; import org.jspresso.framework.application.backend.component.ControllerAwareComponentInvocationHandler; import org.jspresso.framework.application.backend.session.IApplicationSession; import org.jspresso.framework.model.component.IComponent; import org.jspresso.framework.model.component.IQueryComponent; import org.jspresso.framework.model.descriptor.IComponentDescriptor; import org.jspresso.framework.model.entity.IEntity; import org.jspresso.framework.model.entity.IEntityLifecycleHandler; import org.jspresso.framework.model.entity.basic.BasicProxyEntityFactory; import org.jspresso.framework.security.UserPrincipal; import org.jspresso.framework.util.accessor.IAccessor; import org.jspresso.framework.util.bean.MissingPropertyException; /** * Proxy entity factory aware of a backend controller to deal with uniqueness of * entity instances across the JVM. * * @author Vincent Vandenschrick */ public class ControllerAwareProxyEntityFactory extends BasicProxyEntityFactory { private static final Logger LOG = LoggerFactory.getLogger( ControllerAwareProxyEntityFactory.class); private static final String SESSION_PROPERTY_PREFIX = "session."; /** * If a unit of work is active, it will register the new entity in the UOW * before performing any initialization. * <p> * {@inheritDoc} */ @Override protected void initializeEntity(IEntity entity) { getBackendController().registerEntity(entity); super.initializeEntity(entity); } /** * {@inheritDoc} */ @Override protected InvocationHandler createEntityInvocationHandler(IComponentDescriptor<IEntity> entityDescriptor) { return new ControllerAwareEntityInvocationHandler(entityDescriptor, this, getComponentCollectionFactory(), getAccessorFactory(), getComponentExtensionFactory()); } /** * Gets the backendController. * * @return the backendController. */ protected IBackendController getBackendController() { return BackendControllerHolder.getCurrentBackendController(); } /** * Returns the backend controller. * <p> * {@inheritDoc} */ @Override protected IEntityLifecycleHandler getEntityLifecycleHandler() { return getBackendController(); } /** * {@inheritDoc} */ @Override protected UserPrincipal getPrincipal() { return getBackendController().getApplicationSession().getPrincipal(); } /** * {@inheritDoc} */ @Override protected InvocationHandler createComponentInvocationHandler(IComponentDescriptor<IComponent> componentDescriptor) { return new ControllerAwareComponentInvocationHandler(componentDescriptor, this, getComponentCollectionFactory(), getAccessorFactory(), getComponentExtensionFactory()); } /** * {@inheritDoc} */ @Override public IQueryComponent createQueryComponentInstance(Class<? extends IComponent> componentContract) { IQueryComponent queryComponent = super.createQueryComponentInstance(componentContract); queryComponent.translate(getBackendController(), getBackendController().getLocale()); return queryComponent; } /** * {@inheritDoc} */ @Override protected Object extractInitValue(Object masterComponent, String referencePath, Object initializedAttributeValue) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { Object initValue; if (initializedAttributeValue instanceof String && ((String) initializedAttributeValue) .startsWith(SESSION_PROPERTY_PREFIX)) { String sessionProperty = ((String) initializedAttributeValue) .substring(SESSION_PROPERTY_PREFIX.length()); IApplicationSession applicationSession = getBackendController().getApplicationSession(); if (applicationSession != null) { Class<?> sessionContract = applicationSession.getClass(); try { IAccessor sessionAccessor = getAccessorFactory() .createPropertyAccessor(sessionProperty, sessionContract); initValue = sessionAccessor.getValue(applicationSession); if (LOG.isDebugEnabled()) { LOG.debug("Session contract : " + sessionContract.getName()); LOG.debug("Init value computed from session : " + initValue); } } catch (MissingPropertyException ex) { // the value in the initialization mapping is not a session // value. Handle it as null. initValue = null; if (LOG.isDebugEnabled()) { LOG.debug( "Init value '{}' not found on application session. Assigning null.", sessionProperty); } } } else { initValue = null; if (LOG.isDebugEnabled()) { LOG.debug("Application session is null. Assigning null."); } } } else { initValue = super.extractInitValue(masterComponent, referencePath, initializedAttributeValue); } return initValue; } }