org.milyn.persistence.EntityLocator Maven / Gradle / Ivy
The newest version!
/*
Milyn - Copyright (C) 2006 - 2010
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License (version 2.1) as published by the Free Software
Foundation.
This library 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:
http://www.gnu.org/licenses/lgpl.txt
*/
package org.milyn.persistence;
import java.io.IOException;
import java.util.Collection;
import java.util.Set;
import javax.persistence.NonUniqueResultException;
import javax.xml.namespace.QName;
import org.apache.commons.lang.StringUtils;
import org.milyn.SmooksException;
import org.milyn.cdr.SmooksConfigurationException;
import org.milyn.cdr.annotation.AppContext;
import org.milyn.cdr.annotation.ConfigParam;
import org.milyn.cdr.annotation.ConfigParam.Use;
import org.milyn.container.ApplicationContext;
import org.milyn.container.ExecutionContext;
import org.milyn.delivery.Fragment;
import org.milyn.delivery.annotation.Initialize;
import org.milyn.delivery.dom.DOMElementVisitor;
import org.milyn.delivery.ordering.Consumer;
import org.milyn.delivery.ordering.Producer;
import org.milyn.delivery.sax.SAXElement;
import org.milyn.delivery.sax.SAXUtil;
import org.milyn.delivery.sax.SAXVisitAfter;
import org.milyn.delivery.sax.SAXVisitBefore;
import org.milyn.event.report.annotation.VisitAfterReport;
import org.milyn.event.report.annotation.VisitBeforeReport;
import org.milyn.javabean.context.BeanContext;
import org.milyn.javabean.repository.BeanId;
import org.milyn.persistence.parameter.NamedParameterContainer;
import org.milyn.persistence.parameter.ParameterContainer;
import org.milyn.persistence.parameter.ParameterIndex;
import org.milyn.persistence.parameter.ParameterManager;
import org.milyn.persistence.parameter.PositionalParameterContainer;
import org.milyn.persistence.util.PersistenceUtil;
import org.milyn.scribe.invoker.DaoInvoker;
import org.milyn.scribe.invoker.DaoInvokerFactory;
import org.milyn.scribe.register.DaoRegister;
import org.milyn.util.CollectionsUtil;
import org.w3c.dom.Element;
/**
* DAO Locator
*
* This DAO locator uses lookup methods or methods that accept a query to
* lookup entities from a data source. In case of a query it depends on the DAO
* or the Scribe adapter what the query language is.
*
* Configuration
* Namespace: http://www.milyn.org/xsd/smooks/persistence-1.2.xsd
* Element: locator
* Attributes:
*
* Take a look at the schema for all the information on the configurations parameters.
*
* Configuration Example
*
* <?xml version="1.0"?>
* <smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd"
* xmlns:dao="http://www.milyn.org/xsd/smooks/persistence-1.2.xsd">
* <dao:locator beanId="entity" lookup="something" lookupOnElement="b">
* <dao:params>
* <dao:value name="arg1" decoder="Integer" data="c" />
* <dao:expression name="arg2">dAnde.d + dAnde.e</dao:expression>
* <dao:wiring name="arg3" beanIdRef="dAnde" wireOnElement="e" />
* <dao:value name="arg4" data="f/@name" />
* <dao:value name="arg5" decoder="Date" data="g" >
* <dao:decodeParam name="format">yyyy-MM-dd HH:mm:ss</dao:decodeParam>
* </dao:value>
* </dao:params>
* </dao:locator>
*
* <dao:locator beanId="customer" lookupOnElement="b">
* <dao:query>from Customer c where c.id = :arg1</dao:query>
* <dao:params>
* <dao:value name="arg1" decoder="Integer" data="c" />
* </dao:params>
* </dao:locator>
* </smooks-resource-list>
*
*
* @author [email protected]
*/
@VisitBeforeReport(summary = "Initializing parameter container to hold the parameters needed for the lookup.", detailTemplate="reporting/EntityLocator_before.html")
@VisitAfterReport(summary = "Looking up entity to put under beanId '${resource.parameters.beanId}'.", detailTemplate="reporting/EntityLocator_after.html")
public class EntityLocator implements DOMElementVisitor, SAXVisitBefore, SAXVisitAfter, Producer, Consumer {
@ConfigParam()
private int id;
@ConfigParam(name="beanId")
private String beanIdName;
@ConfigParam(name = "dao", use = Use.OPTIONAL)
private String daoName;
@ConfigParam(name="lookup", use = Use.OPTIONAL)
private String lookupName;
@ConfigParam(use = Use.OPTIONAL)
private String query;
@ConfigParam(defaultVal = OnNoResult.NULLIFY_STR, decoder = OnNoResult.DataDecoder.class)
private OnNoResult onNoResult;
@ConfigParam(defaultVal = "false")
private boolean uniqueResult;
@ConfigParam(defaultVal = ParameterListType.NAMED_STR, decoder = ParameterListType.DataDecoder.class)
private ParameterListType parameterListType;
@AppContext
private ApplicationContext appContext;
private ApplicationContextObjectStore objectStore;
private ParameterIndex, ?> parameterIndex;
private BeanId beanId;
@Initialize
public void initialize() throws SmooksConfigurationException {
if(StringUtils.isEmpty(lookupName) && StringUtils.isEmpty(query)) {
throw new SmooksConfigurationException("A lookup name or a query needs to be set to be able to lookup anything");
}
if(StringUtils.isNotEmpty(lookupName) && StringUtils.isNotEmpty(query)) {
throw new SmooksConfigurationException("Both the lookup name and the query can't be set at the same time");
}
beanId = appContext.getBeanIdStore().register(beanIdName);
parameterIndex = ParameterManager.initializeParameterIndex(id, parameterListType, appContext);
objectStore = new ApplicationContextObjectStore(appContext);
}
/* (non-Javadoc)
* @see org.milyn.delivery.ordering.Producer#getProducts()
*/
public Set extends Object> getProducts() {
return CollectionsUtil.toSet(beanIdName);
}
/* (non-Javadoc)
* @see org.milyn.delivery.ordering.Consumer#consumes(java.lang.String)
*/
public boolean consumes(Object object) {
return parameterIndex.containsParameter(object);
}
/* (non-Javadoc)
* @see org.milyn.delivery.dom.DOMVisitBefore#visitBefore(org.w3c.dom.Element, org.milyn.container.ExecutionContext)
*/
public void visitBefore(Element element, ExecutionContext executionContext) throws SmooksException {
initParameterContainer(executionContext);
}
/* (non-Javadoc)
* @see org.milyn.delivery.sax.SAXVisitBefore#visitBefore(org.milyn.delivery.sax.SAXElement, org.milyn.container.ExecutionContext)
*/
public void visitBefore(SAXElement element, ExecutionContext executionContext) throws SmooksException, IOException {
initParameterContainer(executionContext);
}
/* (non-Javadoc)
* @see org.milyn.delivery.dom.DOMVisitAfter#visitAfter(org.w3c.dom.Element, org.milyn.container.ExecutionContext)
*/
public void visitAfter(Element element, ExecutionContext executionContext) throws SmooksException {
lookup(executionContext, new Fragment(element));
}
/* (non-Javadoc)
* @see org.milyn.delivery.sax.SAXVisitAfter#visitAfter(org.milyn.delivery.sax.SAXElement, org.milyn.container.ExecutionContext)
*/
public void visitAfter(SAXElement element, ExecutionContext executionContext) throws SmooksException, IOException {
lookup(executionContext, new Fragment(element));
}
public void initParameterContainer(ExecutionContext executionContext) {
ParameterManager.initializeParameterContainer(id, parameterListType, executionContext);
}
@SuppressWarnings("unchecked")
public void lookup(ExecutionContext executionContext, Fragment source) {
final DaoRegister emr = PersistenceUtil.getDAORegister(executionContext);
Object dao = null;
try {
if(daoName == null) {
dao = emr.getDefaultDao();
} else {
dao = emr.getDao(daoName);
}
if(dao == null) {
throw new IllegalStateException("The DAO register returned null while getting the DAO '" + daoName + "'");
}
Object result = lookup(dao, executionContext);
if(result != null && uniqueResult == true) {
if(result instanceof Collection){
Collection