org.smooks.cartridges.persistence.EntityUpdater Maven / Gradle / Ivy
/*-
* ========================LICENSE_START=================================
* smooks-persistence-cartridge
* %%
* Copyright (C) 2020 Smooks
* %%
* Licensed under the terms of the Apache License Version 2.0, or
* the GNU Lesser General Public License version 3.0 or later.
*
* SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-or-later
*
* ======================================================================
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ======================================================================
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* =========================LICENSE_END==================================
*/
package org.smooks.cartridges.persistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.smooks.api.ApplicationContext;
import org.smooks.api.ExecutionContext;
import org.smooks.api.SmooksConfigException;
import org.smooks.api.SmooksException;
import org.smooks.api.bean.context.BeanContext;
import org.smooks.api.bean.context.BeanIdStore;
import org.smooks.api.bean.repository.BeanId;
import org.smooks.api.delivery.ordering.Consumer;
import org.smooks.api.delivery.ordering.Producer;
import org.smooks.api.resource.visitor.VisitAfterIf;
import org.smooks.api.resource.visitor.VisitAfterReport;
import org.smooks.api.resource.visitor.VisitBeforeIf;
import org.smooks.api.resource.visitor.VisitBeforeReport;
import org.smooks.api.resource.visitor.sax.ng.AfterVisitor;
import org.smooks.api.resource.visitor.sax.ng.BeforeVisitor;
import org.smooks.cartridges.persistence.util.PersistenceUtil;
import org.smooks.engine.delivery.fragment.NodeFragment;
import org.smooks.scribe.ObjectStore;
import org.smooks.scribe.invoker.DaoInvoker;
import org.smooks.scribe.invoker.DaoInvokerFactory;
import org.smooks.scribe.register.DaoRegister;
import org.w3c.dom.Element;
import jakarta.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* DAO Updater
*
* This DAO updater calls the update method of a DAO, using a entity bean from
* the bean context as parameter.
*
* Configuration
* Namespace: https://www.smooks.org/xsd/smooks/persistence-2.0.xsd
* Element: updater
* Attributes:
*
* - beanId : The id under which the entity bean is bound in the bean context. (required)
*
- updateOnElement : The element selector to select the element when the inserter should execute. (required)
*
- dao : The name of the DAO that will be used. If it is not set then the default DAO is used. (optional)
*
- name* : The name of the update method. Depending of the adapter this can mean different things.
* For instance when using annotated DAO's you can name the methods and target them with this property, but
* when using the MyBatis adapter you set the id of the Ibatis statement in this attribute. (optional)
*
- updatedBeanId : The bean id under which the updated bean will be stored. If not set then the object returned
* by the update method will not be stored in bean context. (optional)
*
- updateBefore : If the updater should execute on the 'before' event. (default: false)
*
*
* * This attribute is not supported by all scribe adapters.
*
* Configuration Example
*
* <?xml version="1.0"?>
* <smooks-resource-list xmlns="https://www.smooks.org/xsd/smooks-2.0.xsd"
* xmlns:dao="https://www.smooks.org/xsd/smooks/persistence-2.0.xsd">
*
* <dao:updater dao="dao" name="updateIt" beanId="toUpdate" updateOnElement="root" updateBeanId="updated" updateBefore="false" />
*
* </smooks-resource-list>
*
*
* @author [email protected]
*/
@VisitBeforeIf(condition = "updateBefore")
@VisitAfterIf(condition = "!updateBefore")
@VisitBeforeReport(summary = "Updating bean under beanId '${resource.parameters.beanId}'.", detailTemplate = "reporting/EntityUpdater.html")
@VisitAfterReport(summary = "Updating bean under beanId '${resource.parameters.beanId}'.", detailTemplate = "reporting/EntityUpdater.html")
public class EntityUpdater implements AfterVisitor, BeforeVisitor, Producer, Consumer {
private static final Logger LOGGER = LoggerFactory.getLogger(EntityUpdater.class);
@Inject
@Named("beanId")
private String beanIdName;
@Inject
@Named("updatedBeanId")
private Optional updatedBeanIdName;
@Inject
@Named("dao")
private Optional daoName;
@Inject
private Optional name;
@Inject
private ApplicationContext appContext;
@Inject
private Boolean updateBefore = false;
private ObjectStore objectStore;
private BeanId beanId;
private BeanId updatedBeanId;
@PostConstruct
public void initialize() throws SmooksConfigException {
BeanIdStore beanIdStore = appContext.getBeanIdStore();
beanId = beanIdStore.register(beanIdName);
updatedBeanIdName.ifPresent(s -> updatedBeanId = beanIdStore.register(s));
objectStore = new ApplicationContextObjectStore(appContext);
}
public Boolean getUpdateBefore() {
return updateBefore;
}
/* (non-Javadoc)
* @see org.smooks.api.delivery.ordering.Producer#getProducts()
*/
public Set extends Object> getProducts() {
if (!updatedBeanIdName.isPresent()) {
return Collections.emptySet();
} else {
return Stream.of(updatedBeanIdName.get()).collect(Collectors.toSet());
}
}
/* (non-Javadoc)
* @see org.smooks.api.delivery.ordering.Consumer#consumes(java.lang.String)
*/
public boolean consumes(Object object) {
return object.equals(beanIdName);
}
@Override
public void visitBefore(final Element element, final ExecutionContext executionContext) throws SmooksException {
update(executionContext, new NodeFragment(element));
}
@Override
public void visitAfter(final Element element, final ExecutionContext executionContext) throws SmooksException {
update(executionContext, new NodeFragment(element));
}
/**
* @param executionContext
* @param source
* @return
*/
@SuppressWarnings("unchecked")
private void update(final ExecutionContext executionContext, NodeFragment source) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Updating bean under BeanId '" + beanIdName + "' with DAO '" + daoName + "'.");
}
BeanContext beanContext = executionContext.getBeanContext();
Object bean = beanContext.getBean(beanId);
final DaoRegister emr = PersistenceUtil.getDAORegister(executionContext);
Object dao = null;
try {
if (!daoName.isPresent()) {
dao = emr.getDefaultDao();
} else {
dao = emr.getDao(daoName.get());
}
if (dao == null) {
throw new IllegalStateException("The DAO register returned null while getting the DAO '" + daoName + "'");
}
final DaoInvoker daoInvoker = DaoInvokerFactory.getInstance().create(dao, objectStore);
Object result = !name.isPresent() ? daoInvoker.update(bean) : daoInvoker.update(name.get(), bean);
if (updatedBeanId != null) {
if (result == null) {
result = bean;
}
beanContext.addBean(updatedBeanId, result, source);
} else if (result != null && bean != result) {
beanContext.changeBean(beanId, bean, source);
}
} finally {
if (dao != null) {
emr.returnDao(dao);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy